2 This file contains wireless extension handlers.
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
8 Parts of this driver are based on the GPL part
9 of the official realtek driver.
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon.
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16 We want to tanks the Authors of those projects and the Ndiswrapper
24 #include "ieee80211/dot11d.h"
26 //#define RATE_COUNT 4
27 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
28 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
30 #define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
32 static CHANNEL_LIST DefaultChannelPlan[] = {
33 // {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //Default channel plan
34 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
35 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
36 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
37 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
38 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
39 {{14,36,40,44,48,52,56,60,64},9}, //MKK
40 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
41 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
42 {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
43 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
45 static int r8180_wx_get_freq(struct net_device *dev,
46 struct iw_request_info *a,
47 union iwreq_data *wrqu, char *b)
49 struct r8180_priv *priv = ieee80211_priv(dev);
51 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
55 int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
56 union iwreq_data *wrqu, char *key)
58 struct r8180_priv *priv = ieee80211_priv(dev);
59 struct iw_point *erq = &(wrqu->encoding);
61 if(priv->ieee80211->bHwRadioOff)
64 if (erq->flags & IW_ENCODE_DISABLED) {
68 /* i = erq->flags & IW_ENCODE_INDEX;
72 if (erq->length > 0) {
74 //int len = erq->length <= 5 ? 5 : 13;
76 u32* tkey= (u32*) key;
77 priv->key0[0] = tkey[0];
78 priv->key0[1] = tkey[1];
79 priv->key0[2] = tkey[2];
80 priv->key0[3] = tkey[3] &0xff;
81 DMESG("Setting wep key to %x %x %x %x",
82 tkey[0],tkey[1],tkey[2],tkey[3]);
83 rtl8180_set_hw_wep(dev);
89 static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
90 union iwreq_data *wrqu, char *b)
92 int *parms = (int *)b;
95 struct r8180_priv *priv = ieee80211_priv(dev);
97 if(priv->ieee80211->bHwRadioOff)
101 DMESG("setting beacon interval to %x",bi);
103 priv->ieee80211->current_network.beacon_interval=bi;
112 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
113 union iwreq_data *wrqu, char *b)
115 struct r8180_priv *priv = ieee80211_priv(dev);
116 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
121 static int r8180_wx_get_rate(struct net_device *dev,
122 struct iw_request_info *info,
123 union iwreq_data *wrqu, char *extra)
125 struct r8180_priv *priv = ieee80211_priv(dev);
126 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
131 static int r8180_wx_set_rate(struct net_device *dev,
132 struct iw_request_info *info,
133 union iwreq_data *wrqu, char *extra)
136 struct r8180_priv *priv = ieee80211_priv(dev);
139 if(priv->ieee80211->bHwRadioOff)
144 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
152 static int r8180_wx_set_crcmon(struct net_device *dev,
153 struct iw_request_info *info,
154 union iwreq_data *wrqu, char *extra)
156 struct r8180_priv *priv = ieee80211_priv(dev);
157 int *parms = (int *)extra;
158 int enable = (parms[0] > 0);
159 short prev = priv->crcmon;
162 if(priv->ieee80211->bHwRadioOff)
172 DMESG("bad CRC in monitor mode are %s",
173 priv->crcmon ? "accepted" : "rejected");
175 if(prev != priv->crcmon && priv->up){
186 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
187 union iwreq_data *wrqu, char *b)
189 struct r8180_priv *priv = ieee80211_priv(dev);
193 if(priv->ieee80211->bHwRadioOff)
198 // printk("set mode ENABLE_IPS\n");
199 if(priv->bInactivePs){
200 if(wrqu->mode == IW_MODE_ADHOC)
204 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
206 //rtl8180_commit(dev);
212 //YJ,add,080819,for hidden ap
213 struct iw_range_with_scan_capa
215 /* Informative stuff (to choose between different interface) */
216 __u32 throughput; /* To give an idea... */
217 /* In theory this value should be the maximum benchmarked
218 * TCP/IP throughput, because with most of these devices the
219 * bit rate is meaningless (overhead an co) to estimate how
220 * fast the connection will go and pick the fastest one.
221 * I suggest people to play with Netperf or any benchmark...
224 /* NWID (or domain id) */
225 __u32 min_nwid; /* Minimal NWID we are able to set */
226 __u32 max_nwid; /* Maximal NWID we are able to set */
228 /* Old Frequency (backward compat - moved lower ) */
229 __u16 old_num_channels;
230 __u8 old_num_frequency;
232 /* Scan capabilities */
235 //YJ,add,080819,for hidden ap
238 static int rtl8180_wx_get_range(struct net_device *dev,
239 struct iw_request_info *info,
240 union iwreq_data *wrqu, char *extra)
242 struct iw_range *range = (struct iw_range *)extra;
243 struct r8180_priv *priv = ieee80211_priv(dev);
246 //struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
248 wrqu->data.length = sizeof(*range);
249 memset(range, 0, sizeof(*range));
251 /* Let's try to keep this struct in the same order as in
252 * linux/include/wireless.h
255 /* TODO: See what values we can set, and remove the ones we can't
256 * set, or fill them with some default data.
259 /* ~5 Mb/s real (802.11b) */
260 range->throughput = 5 * 1000 * 1000;
262 // TODO: Not used in 802.11b?
263 // range->min_nwid; /* Minimal NWID we are able to set */
264 // TODO: Not used in 802.11b?
265 // range->max_nwid; /* Maximal NWID we are able to set */
267 /* Old Frequency (backward compat - moved lower ) */
268 // range->old_num_channels;
269 // range->old_num_frequency;
270 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
271 if(priv->rf_set_sens != NULL)
272 range->sensitivity = priv->max_sens; /* signal level threshold range */
274 range->max_qual.qual = 100;
275 /* TODO: Find real max RSSI and stick here */
276 range->max_qual.level = 0;
277 range->max_qual.noise = -98;
278 range->max_qual.updated = 7; /* Updated all three */
280 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
281 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
282 range->avg_qual.level = 20 + -98;
283 range->avg_qual.noise = 0;
284 range->avg_qual.updated = 7; /* Updated all three */
286 range->num_bitrates = RATE_COUNT;
288 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
289 range->bitrate[i] = rtl8180_rates[i];
292 range->min_frag = MIN_FRAG_THRESHOLD;
293 range->max_frag = MAX_FRAG_THRESHOLD;
297 range->we_version_compiled = WIRELESS_EXT;
298 range->we_version_source = 16;
300 // range->retry_capa; /* What retry options are supported */
301 // range->retry_flags; /* How to decode max/min retry limit */
302 // range->r_time_flags; /* How to decode max/min retry life */
303 // range->min_retry; /* Minimal number of retries */
304 // range->max_retry; /* Maximal number of retries */
305 // range->min_r_time; /* Minimal retry lifetime */
306 // range->max_r_time; /* Maximal retry lifetime */
308 range->num_channels = 14;
310 for (i = 0, val = 0; i < 14; i++) {
312 // Include only legal frequencies for some countries
313 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
314 range->freq[val].i = i + 1;
315 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
316 range->freq[val].e = 1;
319 // FIXME: do we need to set anything for channels
323 if (val == IW_MAX_FREQUENCIES)
327 range->num_frequency = val;
328 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
329 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
331 //tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
337 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
338 union iwreq_data *wrqu, char *b)
340 struct r8180_priv *priv = ieee80211_priv(dev);
342 struct ieee80211_device* ieee = priv->ieee80211;
345 if(priv->ieee80211->bHwRadioOff)
348 //YJ,add,080819, for hidden ap
349 //printk("==*&*&*&==>%s in\n", __func__);
350 //printk("=*&*&*&*===>flag:%x, %x\n", wrqu->data.flags, IW_SCAN_THIS_ESSID);
351 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
353 struct iw_scan_req* req = (struct iw_scan_req*)b;
356 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
357 ieee->current_network.ssid_len = req->essid_len;
358 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
359 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
362 //YJ,add,080819, for hidden ap, end
367 // printk("set scan ENABLE_IPS\n");
368 priv->ieee80211->actscanning = true;
369 if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
371 // down(&priv->ieee80211->wx_sem);
373 // if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || !(priv->ieee80211->proto_started)){
375 // up(&priv->ieee80211->wx_sem);
376 // up(&priv->wx_sem);
380 // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
381 //printk("start scan============================>\n");
382 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
383 //ieee80211_start_scan(priv->ieee80211);
384 /* intentionally forget to up sem */
385 // up(&priv->ieee80211->wx_sem);
391 //YJ,add,080828, prevent scan in BusyTraffic
392 //FIXME: Need to consider last scan time
393 if ((priv->link_detect.bBusyTraffic) && (true))
396 printk("Now traffic is busy, please try later!\n");
399 //YJ,add,080828, prevent scan in BusyTraffic,end
400 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
412 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
413 union iwreq_data *wrqu, char *b)
417 struct r8180_priv *priv = ieee80211_priv(dev);
421 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
430 static int r8180_wx_set_essid(struct net_device *dev,
431 struct iw_request_info *a,
432 union iwreq_data *wrqu, char *b)
434 struct r8180_priv *priv = ieee80211_priv(dev);
438 if(priv->ieee80211->bHwRadioOff)
443 //printk("set essid ENABLE_IPS\n");
444 if(priv->bInactivePs)
447 // printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b, wrqu->essid.length, wrqu->essid.flags);
449 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
456 static int r8180_wx_get_essid(struct net_device *dev,
457 struct iw_request_info *a,
458 union iwreq_data *wrqu, char *b)
461 struct r8180_priv *priv = ieee80211_priv(dev);
465 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
473 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
474 union iwreq_data *wrqu, char *b)
477 struct r8180_priv *priv = ieee80211_priv(dev);
480 if(priv->ieee80211->bHwRadioOff)
485 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
492 static int r8180_wx_get_name(struct net_device *dev,
493 struct iw_request_info *info,
494 union iwreq_data *wrqu, char *extra)
496 struct r8180_priv *priv = ieee80211_priv(dev);
497 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
500 static int r8180_wx_set_frag(struct net_device *dev,
501 struct iw_request_info *info,
502 union iwreq_data *wrqu, char *extra)
504 struct r8180_priv *priv = ieee80211_priv(dev);
506 if(priv->ieee80211->bHwRadioOff)
509 if (wrqu->frag.disabled)
510 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
512 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
513 wrqu->frag.value > MAX_FRAG_THRESHOLD)
516 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
523 static int r8180_wx_get_frag(struct net_device *dev,
524 struct iw_request_info *info,
525 union iwreq_data *wrqu, char *extra)
527 struct r8180_priv *priv = ieee80211_priv(dev);
529 wrqu->frag.value = priv->ieee80211->fts;
530 wrqu->frag.fixed = 0; /* no auto select */
531 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
537 static int r8180_wx_set_wap(struct net_device *dev,
538 struct iw_request_info *info,
539 union iwreq_data *awrq,
543 struct r8180_priv *priv = ieee80211_priv(dev);
545 if(priv->ieee80211->bHwRadioOff)
550 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
558 static int r8180_wx_get_wap(struct net_device *dev,
559 struct iw_request_info *info,
560 union iwreq_data *wrqu, char *extra)
562 struct r8180_priv *priv = ieee80211_priv(dev);
564 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
568 static int r8180_wx_set_enc(struct net_device *dev,
569 struct iw_request_info *info,
570 union iwreq_data *wrqu, char *key)
572 struct r8180_priv *priv = ieee80211_priv(dev);
575 if(priv->ieee80211->bHwRadioOff)
581 if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
583 DMESG("Setting SW wep key");
584 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
592 static int r8180_wx_get_enc(struct net_device *dev,
593 struct iw_request_info *info,
594 union iwreq_data *wrqu, char *key)
596 struct r8180_priv *priv = ieee80211_priv(dev);
598 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
602 static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
603 iwreq_data *wrqu, char *p){
605 struct r8180_priv *priv = ieee80211_priv(dev);
609 if(priv->ieee80211->bHwRadioOff)
612 priv->ieee80211->active_scan = mode;
618 /* added by christian */
620 static int r8180_wx_set_monitor_type(struct net_device *dev, struct iw_request_info *aa, union
621 iwreq_data *wrqu, char *p){
623 struct r8180_priv *priv = ieee80211_priv(dev);
627 if(priv->ieee80211->iw_mode != IW_MODE_MONITOR) return -1;
628 priv->prism_hdr = mode;
629 if(!mode)dev->type=ARPHRD_IEEE80211;
630 else dev->type=ARPHRD_IEEE80211_PRISM;
631 DMESG("using %s RX encap", mode ? "AVS":"80211");
636 //of r8180_wx_set_monitor_type
637 /* end added christian */
639 static int r8180_wx_set_retry(struct net_device *dev,
640 struct iw_request_info *info,
641 union iwreq_data *wrqu, char *extra)
643 struct r8180_priv *priv = ieee80211_priv(dev);
646 if(priv->ieee80211->bHwRadioOff)
651 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
652 wrqu->retry.disabled){
656 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
661 if(wrqu->retry.value > R8180_MAX_RETRY){
665 if (wrqu->retry.flags & IW_RETRY_MAX) {
666 priv->retry_rts = wrqu->retry.value;
667 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
670 priv->retry_data = wrqu->retry.value;
671 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
675 * We might try to write directly the TX config register
676 * or to restart just the (R)TX process.
677 * I'm unsure if whole reset is really needed
683 rtl8180_rtx_disable(dev);
684 rtl8180_rx_enable(dev);
685 rtl8180_tx_enable(dev);
695 static int r8180_wx_get_retry(struct net_device *dev,
696 struct iw_request_info *info,
697 union iwreq_data *wrqu, char *extra)
699 struct r8180_priv *priv = ieee80211_priv(dev);
702 wrqu->retry.disabled = 0; /* can't be disabled */
704 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
708 if (wrqu->retry.flags & IW_RETRY_MAX) {
709 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
710 wrqu->retry.value = priv->retry_rts;
712 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
713 wrqu->retry.value = priv->retry_data;
715 //DMESG("returning %d",wrqu->retry.value);
721 static int r8180_wx_get_sens(struct net_device *dev,
722 struct iw_request_info *info,
723 union iwreq_data *wrqu, char *extra)
725 struct r8180_priv *priv = ieee80211_priv(dev);
726 if(priv->rf_set_sens == NULL)
727 return -1; /* we have not this support for this radio */
728 wrqu->sens.value = priv->sens;
733 static int r8180_wx_set_sens(struct net_device *dev,
734 struct iw_request_info *info,
735 union iwreq_data *wrqu, char *extra)
738 struct r8180_priv *priv = ieee80211_priv(dev);
742 if(priv->ieee80211->bHwRadioOff)
746 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
747 if(priv->rf_set_sens == NULL) {
748 err= -1; /* we have not this support for this radio */
751 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
752 priv->sens = wrqu->sens.value;
763 static int r8180_wx_set_rawtx(struct net_device *dev,
764 struct iw_request_info *info,
765 union iwreq_data *wrqu, char *extra)
767 struct r8180_priv *priv = ieee80211_priv(dev);
770 if(priv->ieee80211->bHwRadioOff)
775 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
783 static int r8180_wx_get_power(struct net_device *dev,
784 struct iw_request_info *info,
785 union iwreq_data *wrqu, char *extra)
788 struct r8180_priv *priv = ieee80211_priv(dev);
792 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
799 static int r8180_wx_set_power(struct net_device *dev,
800 struct iw_request_info *info,
801 union iwreq_data *wrqu, char *extra)
804 struct r8180_priv *priv = ieee80211_priv(dev);
807 if(priv->ieee80211->bHwRadioOff)
811 printk("=>>>>>>>>>>=============================>set power:%d,%d!\n",wrqu->power.disabled, wrqu->power.flags);
812 if (wrqu->power.disabled==0) {
813 wrqu->power.flags|=IW_POWER_ALL_R;
814 wrqu->power.flags|=IW_POWER_TIMEOUT;
815 wrqu->power.value =1000;
818 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
825 static int r8180_wx_set_rts(struct net_device *dev,
826 struct iw_request_info *info,
827 union iwreq_data *wrqu, char *extra)
829 struct r8180_priv *priv = ieee80211_priv(dev);
832 if(priv->ieee80211->bHwRadioOff)
835 if (wrqu->rts.disabled)
836 priv->rts = DEFAULT_RTS_THRESHOLD;
838 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
839 wrqu->rts.value > MAX_RTS_THRESHOLD)
842 priv->rts = wrqu->rts.value;
847 static int r8180_wx_get_rts(struct net_device *dev,
848 struct iw_request_info *info,
849 union iwreq_data *wrqu, char *extra)
851 struct r8180_priv *priv = ieee80211_priv(dev);
855 wrqu->rts.value = priv->rts;
856 wrqu->rts.fixed = 0; /* no auto select */
857 wrqu->rts.disabled = (wrqu->rts.value == 0);
861 static int dummy(struct net_device *dev, struct iw_request_info *a,
862 union iwreq_data *wrqu,char *b)
868 static int r8180_wx_get_psmode(struct net_device *dev,
869 struct iw_request_info *info,
870 union iwreq_data *wrqu, char *extra)
872 struct r8180_priv *priv = ieee80211_priv(dev);
873 struct ieee80211_device *ieee;
881 ieee = priv->ieee80211;
882 if(ieee->ps == IEEE80211_PS_DISABLED) {
883 *((unsigned int *)extra) = IEEE80211_PS_DISABLED;
886 *((unsigned int *)extra) = IW_POWER_TIMEOUT;
887 if (ieee->ps & IEEE80211_PS_MBCAST)
888 *((unsigned int *)extra) |= IW_POWER_ALL_R;
890 *((unsigned int *)extra) |= IW_POWER_UNICAST_R;
898 static int r8180_wx_set_psmode(struct net_device *dev,
899 struct iw_request_info *info,
900 union iwreq_data *wrqu, char *extra)
902 struct r8180_priv *priv = ieee80211_priv(dev);
903 //struct ieee80211_device *ieee;
910 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
919 static int r8180_wx_get_iwmode(struct net_device *dev,
920 struct iw_request_info *info,
921 union iwreq_data *wrqu, char *extra)
923 struct r8180_priv *priv = ieee80211_priv(dev);
924 struct ieee80211_device *ieee;
931 ieee = priv->ieee80211;
933 strcpy(extra, "802.11");
934 if(ieee->modulation & IEEE80211_CCK_MODULATION) {
936 if(ieee->modulation & IEEE80211_OFDM_MODULATION)
938 } else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
945 static int r8180_wx_set_iwmode(struct net_device *dev,
946 struct iw_request_info *info,
947 union iwreq_data *wrqu, char *extra)
949 struct r8180_priv *priv = ieee80211_priv(dev);
950 struct ieee80211_device *ieee = priv->ieee80211;
951 int *param = (int *)extra;
953 int modulation = 0, mode = 0;
956 if(priv->ieee80211->bHwRadioOff)
962 modulation |= IEEE80211_CCK_MODULATION;
964 printk(KERN_INFO "B mode!\n");
965 } else if (*param == 2) {
966 modulation |= IEEE80211_OFDM_MODULATION;
968 printk(KERN_INFO "G mode!\n");
969 } else if (*param == 3) {
970 modulation |= IEEE80211_CCK_MODULATION;
971 modulation |= IEEE80211_OFDM_MODULATION;
972 mode = IEEE_B|IEEE_G;
973 printk(KERN_INFO "B/G mode!\n");
976 if(ieee->proto_started) {
977 ieee80211_stop_protocol(ieee);
979 ieee->modulation = modulation;
980 ieee80211_start_protocol(ieee);
983 ieee->modulation = modulation;
984 // ieee80211_start_protocol(ieee);
991 static int r8180_wx_get_preamble(struct net_device *dev,
992 struct iw_request_info *info,
993 union iwreq_data *wrqu, char *extra)
995 struct r8180_priv *priv = ieee80211_priv(dev);
1003 *extra = (char) priv->plcp_preamble_mode; // 0:auto 1:short 2:long
1008 static int r8180_wx_set_preamble(struct net_device *dev,
1009 struct iw_request_info *info,
1010 union iwreq_data *wrqu, char *extra)
1012 struct r8180_priv *priv = ieee80211_priv(dev);
1016 if(priv->ieee80211->bHwRadioOff)
1019 down(&priv->wx_sem);
1020 if (*extra<0||*extra>2)
1023 priv->plcp_preamble_mode = *((short *)extra) ;
1031 static int r8180_wx_get_siglevel(struct net_device *dev,
1032 struct iw_request_info *info,
1033 union iwreq_data *wrqu, char *extra)
1035 struct r8180_priv *priv = ieee80211_priv(dev);
1036 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1041 down(&priv->wx_sem);
1042 // Modify by hikaru 6.5
1043 *((int *)extra) = priv->wstats.qual.level;//for interface test ,it should be the priv->wstats.qual.level;
1051 static int r8180_wx_get_sigqual(struct net_device *dev,
1052 struct iw_request_info *info,
1053 union iwreq_data *wrqu, char *extra)
1055 struct r8180_priv *priv = ieee80211_priv(dev);
1056 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1061 down(&priv->wx_sem);
1062 // Modify by hikaru 6.5
1063 *((int *)extra) = priv->wstats.qual.qual;//for interface test ,it should be the priv->wstats.qual.qual;
1071 static int r8180_wx_reset_stats(struct net_device *dev,
1072 struct iw_request_info *info,
1073 union iwreq_data *wrqu, char *extra)
1075 struct r8180_priv *priv =ieee80211_priv(dev);
1076 down(&priv->wx_sem);
1078 priv->stats.txrdu = 0;
1079 priv->stats.rxrdu = 0;
1080 priv->stats.rxnolast = 0;
1081 priv->stats.rxnodata = 0;
1082 priv->stats.rxnopointer = 0;
1083 priv->stats.txnperr = 0;
1084 priv->stats.txresumed = 0;
1085 priv->stats.rxerr = 0;
1086 priv->stats.rxoverflow = 0;
1087 priv->stats.rxint = 0;
1089 priv->stats.txnpokint = 0;
1090 priv->stats.txhpokint = 0;
1091 priv->stats.txhperr = 0;
1092 priv->stats.ints = 0;
1093 priv->stats.shints = 0;
1094 priv->stats.txoverflow = 0;
1095 priv->stats.rxdmafail = 0;
1096 priv->stats.txbeacon = 0;
1097 priv->stats.txbeaconerr = 0;
1098 priv->stats.txlpokint = 0;
1099 priv->stats.txlperr = 0;
1100 priv->stats.txretry =0;//20060601
1101 priv->stats.rxcrcerrmin=0;
1102 priv->stats.rxcrcerrmid=0;
1103 priv->stats.rxcrcerrmax=0;
1104 priv->stats.rxicverr=0;
1111 static int r8180_wx_radio_on(struct net_device *dev,
1112 struct iw_request_info *info,
1113 union iwreq_data *wrqu, char *extra)
1115 struct r8180_priv *priv =ieee80211_priv(dev);
1117 if(priv->ieee80211->bHwRadioOff)
1121 down(&priv->wx_sem);
1122 priv->rf_wakeup(dev);
1130 static int r8180_wx_radio_off(struct net_device *dev,
1131 struct iw_request_info *info,
1132 union iwreq_data *wrqu, char *extra)
1134 struct r8180_priv *priv =ieee80211_priv(dev);
1136 if(priv->ieee80211->bHwRadioOff)
1140 down(&priv->wx_sem);
1141 priv->rf_sleep(dev);
1148 static int r8180_wx_get_channelplan(struct net_device *dev,
1149 struct iw_request_info *info,
1150 union iwreq_data *wrqu, char *extra)
1152 struct r8180_priv *priv = ieee80211_priv(dev);
1156 down(&priv->wx_sem);
1157 *extra = priv->channel_plan;
1165 static int r8180_wx_set_channelplan(struct net_device *dev,
1166 struct iw_request_info *info,
1167 union iwreq_data *wrqu, char *extra)
1169 struct r8180_priv *priv = ieee80211_priv(dev);
1170 //struct ieee80211_device *ieee = netdev_priv(dev);
1171 int *val = (int *)extra;
1173 printk("-----in fun %s\n", __func__);
1175 if(priv->ieee80211->bHwRadioOff)
1178 //unsigned long flags;
1179 down(&priv->wx_sem);
1180 if (DefaultChannelPlan[*val].Len != 0){
1181 priv ->channel_plan = *val;
1182 // Clear old channel map
1183 for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
1185 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1187 // Set new channel map
1188 for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
1190 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1198 static int r8180_wx_get_version(struct net_device *dev,
1199 struct iw_request_info *info,
1200 union iwreq_data *wrqu, char *extra)
1202 struct r8180_priv *priv = ieee80211_priv(dev);
1203 //struct ieee80211_device *ieee;
1205 down(&priv->wx_sem);
1206 strcpy(extra, "1020.0808");
1212 //added by amy 080818
1213 //receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive.
1214 static int r8180_wx_set_forcerate(struct net_device *dev,
1215 struct iw_request_info *info,
1216 union iwreq_data *wrqu, char *extra)
1218 struct r8180_priv *priv = ieee80211_priv(dev);
1219 u8 forcerate = *extra;
1221 down(&priv->wx_sem);
1223 printk("==============>%s(): forcerate is %d\n",__func__,forcerate);
1224 if((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1225 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1226 (forcerate == 96) || (forcerate == 108))
1228 priv->ForcedDataRate = 1;
1229 priv->ieee80211->rate = forcerate * 5;
1231 else if(forcerate == 0)
1233 priv->ForcedDataRate = 0;
1234 printk("OK! return rate adaptive\n");
1237 printk("ERR: wrong rate\n");
1242 static int r8180_wx_set_enc_ext(struct net_device *dev,
1243 struct iw_request_info *info,
1244 union iwreq_data *wrqu, char *extra)
1247 struct r8180_priv *priv = ieee80211_priv(dev);
1248 //printk("===>%s()\n", __func__);
1252 if(priv->ieee80211->bHwRadioOff)
1255 down(&priv->wx_sem);
1256 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1261 static int r8180_wx_set_auth(struct net_device *dev,
1262 struct iw_request_info *info,
1263 union iwreq_data *wrqu, char *extra)
1265 //printk("====>%s()\n", __func__);
1266 struct r8180_priv *priv = ieee80211_priv(dev);
1269 if(priv->ieee80211->bHwRadioOff)
1272 down(&priv->wx_sem);
1273 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1278 static int r8180_wx_set_mlme(struct net_device *dev,
1279 struct iw_request_info *info,
1280 union iwreq_data *wrqu, char *extra)
1282 //printk("====>%s()\n", __func__);
1285 struct r8180_priv *priv = ieee80211_priv(dev);
1288 if(priv->ieee80211->bHwRadioOff)
1292 down(&priv->wx_sem);
1294 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1299 static int r8180_wx_set_gen_ie(struct net_device *dev,
1300 struct iw_request_info *info,
1301 union iwreq_data *wrqu, char *extra)
1303 // printk("====>%s(), len:%d\n", __func__, data->length);
1305 struct r8180_priv *priv = ieee80211_priv(dev);
1308 if(priv->ieee80211->bHwRadioOff)
1311 down(&priv->wx_sem);
1313 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1316 //printk("<======%s(), ret:%d\n", __func__, ret);
1321 static iw_handler r8180_wx_handlers[] =
1323 NULL, /* SIOCSIWCOMMIT */
1324 r8180_wx_get_name, /* SIOCGIWNAME */
1325 dummy, /* SIOCSIWNWID */
1326 dummy, /* SIOCGIWNWID */
1327 r8180_wx_set_freq, /* SIOCSIWFREQ */
1328 r8180_wx_get_freq, /* SIOCGIWFREQ */
1329 r8180_wx_set_mode, /* SIOCSIWMODE */
1330 r8180_wx_get_mode, /* SIOCGIWMODE */
1331 r8180_wx_set_sens, /* SIOCSIWSENS */
1332 r8180_wx_get_sens, /* SIOCGIWSENS */
1333 NULL, /* SIOCSIWRANGE */
1334 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1335 NULL, /* SIOCSIWPRIV */
1336 NULL, /* SIOCGIWPRIV */
1337 NULL, /* SIOCSIWSTATS */
1338 NULL, /* SIOCGIWSTATS */
1339 dummy, /* SIOCSIWSPY */
1340 dummy, /* SIOCGIWSPY */
1341 NULL, /* SIOCGIWTHRSPY */
1342 NULL, /* SIOCWIWTHRSPY */
1343 r8180_wx_set_wap, /* SIOCSIWAP */
1344 r8180_wx_get_wap, /* SIOCGIWAP */
1345 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1346 dummy, /* SIOCGIWAPLIST -- depricated */
1347 r8180_wx_set_scan, /* SIOCSIWSCAN */
1348 r8180_wx_get_scan, /* SIOCGIWSCAN */
1349 r8180_wx_set_essid, /* SIOCSIWESSID */
1350 r8180_wx_get_essid, /* SIOCGIWESSID */
1351 dummy, /* SIOCSIWNICKN */
1352 dummy, /* SIOCGIWNICKN */
1353 NULL, /* -- hole -- */
1354 NULL, /* -- hole -- */
1355 r8180_wx_set_rate, /* SIOCSIWRATE */
1356 r8180_wx_get_rate, /* SIOCGIWRATE */
1357 r8180_wx_set_rts, /* SIOCSIWRTS */
1358 r8180_wx_get_rts, /* SIOCGIWRTS */
1359 r8180_wx_set_frag, /* SIOCSIWFRAG */
1360 r8180_wx_get_frag, /* SIOCGIWFRAG */
1361 dummy, /* SIOCSIWTXPOW */
1362 dummy, /* SIOCGIWTXPOW */
1363 r8180_wx_set_retry, /* SIOCSIWRETRY */
1364 r8180_wx_get_retry, /* SIOCGIWRETRY */
1365 r8180_wx_set_enc, /* SIOCSIWENCODE */
1366 r8180_wx_get_enc, /* SIOCGIWENCODE */
1367 r8180_wx_set_power, /* SIOCSIWPOWER */
1368 r8180_wx_get_power, /* SIOCGIWPOWER */
1369 NULL, /*---hole---*/
1370 NULL, /*---hole---*/
1371 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1372 NULL, /* SIOCSIWGENIE */
1373 r8180_wx_set_auth, /* SIOCSIWAUTH */
1374 NULL, /* SIOCSIWAUTH */
1375 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1376 NULL, /* SIOCSIWENCODEEXT */
1377 NULL, /* SIOCSIWPMKSA */
1378 NULL, /*---hole---*/
1382 static const struct iw_priv_args r8180_private_args[] = {
1384 SIOCIWFIRSTPRIV + 0x0,
1385 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1387 { SIOCIWFIRSTPRIV + 0x1,
1392 SIOCIWFIRSTPRIV + 0x2,
1393 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1395 { SIOCIWFIRSTPRIV + 0x3,
1399 /* added by christian */
1401 // SIOCIWFIRSTPRIV + 0x2,
1402 // IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prismhdr"
1404 /* end added by christian */
1406 SIOCIWFIRSTPRIV + 0x4,
1407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1410 { SIOCIWFIRSTPRIV + 0x5,
1415 SIOCIWFIRSTPRIV + 0x6,
1416 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1419 { SIOCIWFIRSTPRIV + 0x7,
1424 // SIOCIWFIRSTPRIV + 0x5,
1425 // 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpsmode"
1428 // SIOCIWFIRSTPRIV + 0x6,
1429 // IW_PRIV_SIZE_FIXED, 0, "setpsmode"
1431 //set/get mode have been realized in public handlers
1434 SIOCIWFIRSTPRIV + 0x8,
1435 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1438 SIOCIWFIRSTPRIV + 0x9,
1439 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1442 SIOCIWFIRSTPRIV + 0xA,
1443 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1446 SIOCIWFIRSTPRIV + 0xB,
1447 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1449 { SIOCIWFIRSTPRIV + 0xC,
1453 SIOCIWFIRSTPRIV + 0xD,
1454 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1456 { SIOCIWFIRSTPRIV + 0xE,
1460 SIOCIWFIRSTPRIV + 0xF,
1461 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1464 SIOCIWFIRSTPRIV + 0x10,
1468 SIOCIWFIRSTPRIV + 0x11,
1472 SIOCIWFIRSTPRIV + 0x12,
1476 SIOCIWFIRSTPRIV + 0x13,
1480 SIOCIWFIRSTPRIV + 0x14,
1481 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1484 SIOCIWFIRSTPRIV + 0x15,
1485 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1488 SIOCIWFIRSTPRIV + 0x16,
1492 SIOCIWFIRSTPRIV + 0x17,
1493 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1496 SIOCIWFIRSTPRIV + 0x18,
1497 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1502 static iw_handler r8180_private_handler[] = {
1503 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1505 r8180_wx_set_beaconinterval,
1507 //r8180_wx_set_monitor_type,
1508 r8180_wx_set_scan_type,
1512 r8180_wx_set_iwmode,
1513 r8180_wx_get_iwmode,
1514 r8180_wx_set_preamble,
1515 r8180_wx_get_preamble,
1517 r8180_wx_get_siglevel,
1519 r8180_wx_get_sigqual,
1520 r8180_wx_reset_stats,
1521 dummy,//r8180_wx_get_stats
1524 r8180_wx_set_channelplan,
1525 r8180_wx_get_channelplan,
1527 r8180_wx_get_version,
1528 r8180_wx_set_forcerate,
1531 static inline int is_same_network(struct ieee80211_network *src,
1532 struct ieee80211_network *dst,
1533 struct ieee80211_device *ieee)
1535 /* A network is only a duplicate if the channel, BSSID, ESSID
1536 * and the capability field (in particular IBSS and BSS) all match.
1537 * We treat all <hidden> with the same BSSID and channel
1539 return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1540 //((src->ssid_len == dst->ssid_len) &&
1541 (src->channel == dst->channel) &&
1542 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1543 (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1544 //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
1545 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1546 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1547 ((src->capability & WLAN_CAPABILITY_BSS) ==
1548 (dst->capability & WLAN_CAPABILITY_BSS)));
1551 //WB modefied to show signal to GUI on 18-01-2008
1552 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1554 struct r8180_priv *priv = ieee80211_priv(dev);
1555 struct ieee80211_device* ieee = priv->ieee80211;
1556 struct iw_statistics* wstats = &priv->wstats;
1557 //struct ieee80211_network* target = NULL;
1561 //unsigned long flag;
1563 if (ieee->state < IEEE80211_LINKED)
1565 wstats->qual.qual = 0;
1566 wstats->qual.level = 0;
1567 wstats->qual.noise = 0;
1568 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1572 tmp_level = (&ieee->current_network)->stats.signal;
1573 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1574 tmp_noise = (&ieee->current_network)->stats.noise;
1575 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1577 // printk("level:%d\n", tmp_level);
1578 wstats->qual.level = tmp_level;
1579 wstats->qual.qual = tmp_qual;
1580 wstats->qual.noise = tmp_noise;
1581 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1585 struct iw_handler_def r8180_wx_handlers_def={
1586 .standard = r8180_wx_handlers,
1587 .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
1588 .private = r8180_private_handler,
1589 .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
1590 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1591 .get_wireless_stats = r8180_get_wireless_stats,
1592 .private_args = (struct iw_priv_args *)r8180_private_args,