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
23 #include "r8180_sa2400.h"
25 #include "ieee80211/dot11d.h"
27 //#define RATE_COUNT 4
28 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
29 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31 #define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
33 static CHANNEL_LIST DefaultChannelPlan[] = {
34 // {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //Default channel plan
35 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
36 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
37 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
38 {{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.
39 {{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.
40 {{14,36,40,44,48,52,56,60,64},9}, //MKK
41 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
42 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
43 {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
44 {{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
46 static int r8180_wx_get_freq(struct net_device *dev,
47 struct iw_request_info *a,
48 union iwreq_data *wrqu, char *b)
50 struct r8180_priv *priv = ieee80211_priv(dev);
52 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
56 int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
57 union iwreq_data *wrqu, char *key)
59 struct r8180_priv *priv = ieee80211_priv(dev);
60 struct iw_point *erq = &(wrqu->encoding);
62 if(priv->ieee80211->bHwRadioOff)
65 if (erq->flags & IW_ENCODE_DISABLED) {
69 /* i = erq->flags & IW_ENCODE_INDEX;
73 if (erq->length > 0) {
75 //int len = erq->length <= 5 ? 5 : 13;
77 u32* tkey= (u32*) key;
78 priv->key0[0] = tkey[0];
79 priv->key0[1] = tkey[1];
80 priv->key0[2] = tkey[2];
81 priv->key0[3] = tkey[3] &0xff;
82 DMESG("Setting wep key to %x %x %x %x",
83 tkey[0],tkey[1],tkey[2],tkey[3]);
84 rtl8180_set_hw_wep(dev);
90 static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
91 union iwreq_data *wrqu, char *b)
93 int *parms = (int *)b;
96 struct r8180_priv *priv = ieee80211_priv(dev);
98 if(priv->ieee80211->bHwRadioOff)
102 DMESG("setting beacon interval to %x",bi);
104 priv->ieee80211->current_network.beacon_interval=bi;
113 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
114 union iwreq_data *wrqu, char *b)
116 struct r8180_priv *priv = ieee80211_priv(dev);
117 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
122 static int r8180_wx_get_rate(struct net_device *dev,
123 struct iw_request_info *info,
124 union iwreq_data *wrqu, char *extra)
126 struct r8180_priv *priv = ieee80211_priv(dev);
127 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
132 static int r8180_wx_set_rate(struct net_device *dev,
133 struct iw_request_info *info,
134 union iwreq_data *wrqu, char *extra)
137 struct r8180_priv *priv = ieee80211_priv(dev);
140 if(priv->ieee80211->bHwRadioOff)
145 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
153 static int r8180_wx_set_crcmon(struct net_device *dev,
154 struct iw_request_info *info,
155 union iwreq_data *wrqu, char *extra)
157 struct r8180_priv *priv = ieee80211_priv(dev);
158 int *parms = (int *)extra;
159 int enable = (parms[0] > 0);
160 short prev = priv->crcmon;
163 if(priv->ieee80211->bHwRadioOff)
173 DMESG("bad CRC in monitor mode are %s",
174 priv->crcmon ? "accepted" : "rejected");
176 if(prev != priv->crcmon && priv->up){
187 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
188 union iwreq_data *wrqu, char *b)
190 struct r8180_priv *priv = ieee80211_priv(dev);
194 if(priv->ieee80211->bHwRadioOff)
199 // printk("set mode ENABLE_IPS\n");
200 if(priv->bInactivePs){
201 if(wrqu->mode == IW_MODE_ADHOC)
205 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
207 //rtl8180_commit(dev);
213 //YJ,add,080819,for hidden ap
214 struct iw_range_with_scan_capa
216 /* Informative stuff (to choose between different interface) */
217 __u32 throughput; /* To give an idea... */
218 /* In theory this value should be the maximum benchmarked
219 * TCP/IP throughput, because with most of these devices the
220 * bit rate is meaningless (overhead an co) to estimate how
221 * fast the connection will go and pick the fastest one.
222 * I suggest people to play with Netperf or any benchmark...
225 /* NWID (or domain id) */
226 __u32 min_nwid; /* Minimal NWID we are able to set */
227 __u32 max_nwid; /* Maximal NWID we are able to set */
229 /* Old Frequency (backward compat - moved lower ) */
230 __u16 old_num_channels;
231 __u8 old_num_frequency;
233 /* Scan capabilities */
236 //YJ,add,080819,for hidden ap
239 static int rtl8180_wx_get_range(struct net_device *dev,
240 struct iw_request_info *info,
241 union iwreq_data *wrqu, char *extra)
243 struct iw_range *range = (struct iw_range *)extra;
244 struct r8180_priv *priv = ieee80211_priv(dev);
247 //struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
249 wrqu->data.length = sizeof(*range);
250 memset(range, 0, sizeof(*range));
252 /* Let's try to keep this struct in the same order as in
253 * linux/include/wireless.h
256 /* TODO: See what values we can set, and remove the ones we can't
257 * set, or fill them with some default data.
260 /* ~5 Mb/s real (802.11b) */
261 range->throughput = 5 * 1000 * 1000;
263 // TODO: Not used in 802.11b?
264 // range->min_nwid; /* Minimal NWID we are able to set */
265 // TODO: Not used in 802.11b?
266 // range->max_nwid; /* Maximal NWID we are able to set */
268 /* Old Frequency (backward compat - moved lower ) */
269 // range->old_num_channels;
270 // range->old_num_frequency;
271 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
272 if(priv->rf_set_sens != NULL)
273 range->sensitivity = priv->max_sens; /* signal level threshold range */
275 range->max_qual.qual = 100;
276 /* TODO: Find real max RSSI and stick here */
277 range->max_qual.level = 0;
278 range->max_qual.noise = -98;
279 range->max_qual.updated = 7; /* Updated all three */
281 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
282 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
283 range->avg_qual.level = 20 + -98;
284 range->avg_qual.noise = 0;
285 range->avg_qual.updated = 7; /* Updated all three */
287 range->num_bitrates = RATE_COUNT;
289 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
290 range->bitrate[i] = rtl8180_rates[i];
293 range->min_frag = MIN_FRAG_THRESHOLD;
294 range->max_frag = MAX_FRAG_THRESHOLD;
298 range->we_version_compiled = WIRELESS_EXT;
299 range->we_version_source = 16;
301 // range->retry_capa; /* What retry options are supported */
302 // range->retry_flags; /* How to decode max/min retry limit */
303 // range->r_time_flags; /* How to decode max/min retry life */
304 // range->min_retry; /* Minimal number of retries */
305 // range->max_retry; /* Maximal number of retries */
306 // range->min_r_time; /* Minimal retry lifetime */
307 // range->max_r_time; /* Maximal retry lifetime */
309 range->num_channels = 14;
311 for (i = 0, val = 0; i < 14; i++) {
313 // Include only legal frequencies for some countries
314 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
315 range->freq[val].i = i + 1;
316 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
317 range->freq[val].e = 1;
320 // FIXME: do we need to set anything for channels
324 if (val == IW_MAX_FREQUENCIES)
328 range->num_frequency = val;
329 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
330 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
332 //tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
338 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
339 union iwreq_data *wrqu, char *b)
341 struct r8180_priv *priv = ieee80211_priv(dev);
343 struct ieee80211_device* ieee = priv->ieee80211;
346 if(priv->ieee80211->bHwRadioOff)
349 //YJ,add,080819, for hidden ap
350 //printk("==*&*&*&==>%s in\n", __func__);
351 //printk("=*&*&*&*===>flag:%x, %x\n", wrqu->data.flags, IW_SCAN_THIS_ESSID);
352 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
354 struct iw_scan_req* req = (struct iw_scan_req*)b;
357 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
358 ieee->current_network.ssid_len = req->essid_len;
359 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
360 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
363 //YJ,add,080819, for hidden ap, end
368 // printk("set scan ENABLE_IPS\n");
369 priv->ieee80211->actscanning = true;
370 if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
372 // down(&priv->ieee80211->wx_sem);
374 // if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || !(priv->ieee80211->proto_started)){
376 // up(&priv->ieee80211->wx_sem);
377 // up(&priv->wx_sem);
381 // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
382 //printk("start scan============================>\n");
383 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
384 //ieee80211_start_scan(priv->ieee80211);
385 /* intentionally forget to up sem */
386 // up(&priv->ieee80211->wx_sem);
392 //YJ,add,080828, prevent scan in BusyTraffic
393 //FIXME: Need to consider last scan time
394 if ((priv->link_detect.bBusyTraffic) && (true))
397 printk("Now traffic is busy, please try later!\n");
400 //YJ,add,080828, prevent scan in BusyTraffic,end
401 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
413 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
414 union iwreq_data *wrqu, char *b)
418 struct r8180_priv *priv = ieee80211_priv(dev);
422 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
431 static int r8180_wx_set_essid(struct net_device *dev,
432 struct iw_request_info *a,
433 union iwreq_data *wrqu, char *b)
435 struct r8180_priv *priv = ieee80211_priv(dev);
439 if(priv->ieee80211->bHwRadioOff)
444 //printk("set essid ENABLE_IPS\n");
445 if(priv->bInactivePs)
448 // printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b, wrqu->essid.length, wrqu->essid.flags);
450 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
457 static int r8180_wx_get_essid(struct net_device *dev,
458 struct iw_request_info *a,
459 union iwreq_data *wrqu, char *b)
462 struct r8180_priv *priv = ieee80211_priv(dev);
466 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
474 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
475 union iwreq_data *wrqu, char *b)
478 struct r8180_priv *priv = ieee80211_priv(dev);
481 if(priv->ieee80211->bHwRadioOff)
486 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
493 static int r8180_wx_get_name(struct net_device *dev,
494 struct iw_request_info *info,
495 union iwreq_data *wrqu, char *extra)
497 struct r8180_priv *priv = ieee80211_priv(dev);
498 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
501 static int r8180_wx_set_frag(struct net_device *dev,
502 struct iw_request_info *info,
503 union iwreq_data *wrqu, char *extra)
505 struct r8180_priv *priv = ieee80211_priv(dev);
507 if(priv->ieee80211->bHwRadioOff)
510 if (wrqu->frag.disabled)
511 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
513 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
514 wrqu->frag.value > MAX_FRAG_THRESHOLD)
517 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
524 static int r8180_wx_get_frag(struct net_device *dev,
525 struct iw_request_info *info,
526 union iwreq_data *wrqu, char *extra)
528 struct r8180_priv *priv = ieee80211_priv(dev);
530 wrqu->frag.value = priv->ieee80211->fts;
531 wrqu->frag.fixed = 0; /* no auto select */
532 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
538 static int r8180_wx_set_wap(struct net_device *dev,
539 struct iw_request_info *info,
540 union iwreq_data *awrq,
544 struct r8180_priv *priv = ieee80211_priv(dev);
546 if(priv->ieee80211->bHwRadioOff)
551 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
559 static int r8180_wx_get_wap(struct net_device *dev,
560 struct iw_request_info *info,
561 union iwreq_data *wrqu, char *extra)
563 struct r8180_priv *priv = ieee80211_priv(dev);
565 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
569 static int r8180_wx_set_enc(struct net_device *dev,
570 struct iw_request_info *info,
571 union iwreq_data *wrqu, char *key)
573 struct r8180_priv *priv = ieee80211_priv(dev);
576 if(priv->ieee80211->bHwRadioOff)
582 if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
584 DMESG("Setting SW wep key");
585 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
593 static int r8180_wx_get_enc(struct net_device *dev,
594 struct iw_request_info *info,
595 union iwreq_data *wrqu, char *key)
597 struct r8180_priv *priv = ieee80211_priv(dev);
599 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
603 static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
604 iwreq_data *wrqu, char *p){
606 struct r8180_priv *priv = ieee80211_priv(dev);
610 if(priv->ieee80211->bHwRadioOff)
613 priv->ieee80211->active_scan = mode;
619 /* added by christian */
621 static int r8180_wx_set_monitor_type(struct net_device *dev, struct iw_request_info *aa, union
622 iwreq_data *wrqu, char *p){
624 struct r8180_priv *priv = ieee80211_priv(dev);
628 if(priv->ieee80211->iw_mode != IW_MODE_MONITOR) return -1;
629 priv->prism_hdr = mode;
630 if(!mode)dev->type=ARPHRD_IEEE80211;
631 else dev->type=ARPHRD_IEEE80211_PRISM;
632 DMESG("using %s RX encap", mode ? "AVS":"80211");
637 //of r8180_wx_set_monitor_type
638 /* end added christian */
640 static int r8180_wx_set_retry(struct net_device *dev,
641 struct iw_request_info *info,
642 union iwreq_data *wrqu, char *extra)
644 struct r8180_priv *priv = ieee80211_priv(dev);
647 if(priv->ieee80211->bHwRadioOff)
652 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
653 wrqu->retry.disabled){
657 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
662 if(wrqu->retry.value > R8180_MAX_RETRY){
666 if (wrqu->retry.flags & IW_RETRY_MAX) {
667 priv->retry_rts = wrqu->retry.value;
668 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
671 priv->retry_data = wrqu->retry.value;
672 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
676 * We might try to write directly the TX config register
677 * or to restart just the (R)TX process.
678 * I'm unsure if whole reset is really needed
684 rtl8180_rtx_disable(dev);
685 rtl8180_rx_enable(dev);
686 rtl8180_tx_enable(dev);
696 static int r8180_wx_get_retry(struct net_device *dev,
697 struct iw_request_info *info,
698 union iwreq_data *wrqu, char *extra)
700 struct r8180_priv *priv = ieee80211_priv(dev);
703 wrqu->retry.disabled = 0; /* can't be disabled */
705 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
709 if (wrqu->retry.flags & IW_RETRY_MAX) {
710 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
711 wrqu->retry.value = priv->retry_rts;
713 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
714 wrqu->retry.value = priv->retry_data;
716 //DMESG("returning %d",wrqu->retry.value);
722 static int r8180_wx_get_sens(struct net_device *dev,
723 struct iw_request_info *info,
724 union iwreq_data *wrqu, char *extra)
726 struct r8180_priv *priv = ieee80211_priv(dev);
727 if(priv->rf_set_sens == NULL)
728 return -1; /* we have not this support for this radio */
729 wrqu->sens.value = priv->sens;
734 static int r8180_wx_set_sens(struct net_device *dev,
735 struct iw_request_info *info,
736 union iwreq_data *wrqu, char *extra)
739 struct r8180_priv *priv = ieee80211_priv(dev);
743 if(priv->ieee80211->bHwRadioOff)
747 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
748 if(priv->rf_set_sens == NULL) {
749 err= -1; /* we have not this support for this radio */
752 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
753 priv->sens = wrqu->sens.value;
764 static int r8180_wx_set_rawtx(struct net_device *dev,
765 struct iw_request_info *info,
766 union iwreq_data *wrqu, char *extra)
768 struct r8180_priv *priv = ieee80211_priv(dev);
771 if(priv->ieee80211->bHwRadioOff)
776 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
784 static int r8180_wx_get_power(struct net_device *dev,
785 struct iw_request_info *info,
786 union iwreq_data *wrqu, char *extra)
789 struct r8180_priv *priv = ieee80211_priv(dev);
793 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
800 static int r8180_wx_set_power(struct net_device *dev,
801 struct iw_request_info *info,
802 union iwreq_data *wrqu, char *extra)
805 struct r8180_priv *priv = ieee80211_priv(dev);
808 if(priv->ieee80211->bHwRadioOff)
812 printk("=>>>>>>>>>>=============================>set power:%d,%d!\n",wrqu->power.disabled, wrqu->power.flags);
813 if (wrqu->power.disabled==0) {
814 wrqu->power.flags|=IW_POWER_ALL_R;
815 wrqu->power.flags|=IW_POWER_TIMEOUT;
816 wrqu->power.value =1000;
819 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
826 static int r8180_wx_set_rts(struct net_device *dev,
827 struct iw_request_info *info,
828 union iwreq_data *wrqu, char *extra)
830 struct r8180_priv *priv = ieee80211_priv(dev);
833 if(priv->ieee80211->bHwRadioOff)
836 if (wrqu->rts.disabled)
837 priv->rts = DEFAULT_RTS_THRESHOLD;
839 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
840 wrqu->rts.value > MAX_RTS_THRESHOLD)
843 priv->rts = wrqu->rts.value;
848 static int r8180_wx_get_rts(struct net_device *dev,
849 struct iw_request_info *info,
850 union iwreq_data *wrqu, char *extra)
852 struct r8180_priv *priv = ieee80211_priv(dev);
856 wrqu->rts.value = priv->rts;
857 wrqu->rts.fixed = 0; /* no auto select */
858 wrqu->rts.disabled = (wrqu->rts.value == 0);
862 static int dummy(struct net_device *dev, struct iw_request_info *a,
863 union iwreq_data *wrqu,char *b)
869 static int r8180_wx_get_psmode(struct net_device *dev,
870 struct iw_request_info *info,
871 union iwreq_data *wrqu, char *extra)
873 struct r8180_priv *priv = ieee80211_priv(dev);
874 struct ieee80211_device *ieee;
882 ieee = priv->ieee80211;
883 if(ieee->ps == IEEE80211_PS_DISABLED) {
884 *((unsigned int *)extra) = IEEE80211_PS_DISABLED;
887 *((unsigned int *)extra) = IW_POWER_TIMEOUT;
888 if (ieee->ps & IEEE80211_PS_MBCAST)
889 *((unsigned int *)extra) |= IW_POWER_ALL_R;
891 *((unsigned int *)extra) |= IW_POWER_UNICAST_R;
899 static int r8180_wx_set_psmode(struct net_device *dev,
900 struct iw_request_info *info,
901 union iwreq_data *wrqu, char *extra)
903 struct r8180_priv *priv = ieee80211_priv(dev);
904 //struct ieee80211_device *ieee;
911 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
920 static int r8180_wx_get_iwmode(struct net_device *dev,
921 struct iw_request_info *info,
922 union iwreq_data *wrqu, char *extra)
924 struct r8180_priv *priv = ieee80211_priv(dev);
925 struct ieee80211_device *ieee;
932 ieee = priv->ieee80211;
934 strcpy(extra, "802.11");
935 if(ieee->modulation & IEEE80211_CCK_MODULATION) {
937 if(ieee->modulation & IEEE80211_OFDM_MODULATION)
939 } else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
946 static int r8180_wx_set_iwmode(struct net_device *dev,
947 struct iw_request_info *info,
948 union iwreq_data *wrqu, char *extra)
950 struct r8180_priv *priv = ieee80211_priv(dev);
951 struct ieee80211_device *ieee = priv->ieee80211;
952 int *param = (int *)extra;
954 int modulation = 0, mode = 0;
957 if(priv->ieee80211->bHwRadioOff)
963 modulation |= IEEE80211_CCK_MODULATION;
965 printk(KERN_INFO "B mode!\n");
966 } else if (*param == 2) {
967 modulation |= IEEE80211_OFDM_MODULATION;
969 printk(KERN_INFO "G mode!\n");
970 } else if (*param == 3) {
971 modulation |= IEEE80211_CCK_MODULATION;
972 modulation |= IEEE80211_OFDM_MODULATION;
973 mode = IEEE_B|IEEE_G;
974 printk(KERN_INFO "B/G mode!\n");
977 if(ieee->proto_started) {
978 ieee80211_stop_protocol(ieee);
980 ieee->modulation = modulation;
981 ieee80211_start_protocol(ieee);
984 ieee->modulation = modulation;
985 // ieee80211_start_protocol(ieee);
992 static int r8180_wx_get_preamble(struct net_device *dev,
993 struct iw_request_info *info,
994 union iwreq_data *wrqu, char *extra)
996 struct r8180_priv *priv = ieee80211_priv(dev);
1000 down(&priv->wx_sem);
1004 *extra = (char) priv->plcp_preamble_mode; // 0:auto 1:short 2:long
1009 static int r8180_wx_set_preamble(struct net_device *dev,
1010 struct iw_request_info *info,
1011 union iwreq_data *wrqu, char *extra)
1013 struct r8180_priv *priv = ieee80211_priv(dev);
1017 if(priv->ieee80211->bHwRadioOff)
1020 down(&priv->wx_sem);
1021 if (*extra<0||*extra>2)
1024 priv->plcp_preamble_mode = *((short *)extra) ;
1032 static int r8180_wx_get_siglevel(struct net_device *dev,
1033 struct iw_request_info *info,
1034 union iwreq_data *wrqu, char *extra)
1036 struct r8180_priv *priv = ieee80211_priv(dev);
1037 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1042 down(&priv->wx_sem);
1043 // Modify by hikaru 6.5
1044 *((int *)extra) = priv->wstats.qual.level;//for interface test ,it should be the priv->wstats.qual.level;
1052 static int r8180_wx_get_sigqual(struct net_device *dev,
1053 struct iw_request_info *info,
1054 union iwreq_data *wrqu, char *extra)
1056 struct r8180_priv *priv = ieee80211_priv(dev);
1057 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1062 down(&priv->wx_sem);
1063 // Modify by hikaru 6.5
1064 *((int *)extra) = priv->wstats.qual.qual;//for interface test ,it should be the priv->wstats.qual.qual;
1072 static int r8180_wx_reset_stats(struct net_device *dev,
1073 struct iw_request_info *info,
1074 union iwreq_data *wrqu, char *extra)
1076 struct r8180_priv *priv =ieee80211_priv(dev);
1077 down(&priv->wx_sem);
1079 priv->stats.txrdu = 0;
1080 priv->stats.rxrdu = 0;
1081 priv->stats.rxnolast = 0;
1082 priv->stats.rxnodata = 0;
1083 priv->stats.rxnopointer = 0;
1084 priv->stats.txnperr = 0;
1085 priv->stats.txresumed = 0;
1086 priv->stats.rxerr = 0;
1087 priv->stats.rxoverflow = 0;
1088 priv->stats.rxint = 0;
1090 priv->stats.txnpokint = 0;
1091 priv->stats.txhpokint = 0;
1092 priv->stats.txhperr = 0;
1093 priv->stats.ints = 0;
1094 priv->stats.shints = 0;
1095 priv->stats.txoverflow = 0;
1096 priv->stats.rxdmafail = 0;
1097 priv->stats.txbeacon = 0;
1098 priv->stats.txbeaconerr = 0;
1099 priv->stats.txlpokint = 0;
1100 priv->stats.txlperr = 0;
1101 priv->stats.txretry =0;//20060601
1102 priv->stats.rxcrcerrmin=0;
1103 priv->stats.rxcrcerrmid=0;
1104 priv->stats.rxcrcerrmax=0;
1105 priv->stats.rxicverr=0;
1112 static int r8180_wx_radio_on(struct net_device *dev,
1113 struct iw_request_info *info,
1114 union iwreq_data *wrqu, char *extra)
1116 struct r8180_priv *priv =ieee80211_priv(dev);
1118 if(priv->ieee80211->bHwRadioOff)
1122 down(&priv->wx_sem);
1123 priv->rf_wakeup(dev);
1131 static int r8180_wx_radio_off(struct net_device *dev,
1132 struct iw_request_info *info,
1133 union iwreq_data *wrqu, char *extra)
1135 struct r8180_priv *priv =ieee80211_priv(dev);
1137 if(priv->ieee80211->bHwRadioOff)
1141 down(&priv->wx_sem);
1142 priv->rf_sleep(dev);
1149 static int r8180_wx_get_channelplan(struct net_device *dev,
1150 struct iw_request_info *info,
1151 union iwreq_data *wrqu, char *extra)
1153 struct r8180_priv *priv = ieee80211_priv(dev);
1157 down(&priv->wx_sem);
1158 *extra = priv->channel_plan;
1166 static int r8180_wx_set_channelplan(struct net_device *dev,
1167 struct iw_request_info *info,
1168 union iwreq_data *wrqu, char *extra)
1170 struct r8180_priv *priv = ieee80211_priv(dev);
1171 //struct ieee80211_device *ieee = netdev_priv(dev);
1172 int *val = (int *)extra;
1174 printk("-----in fun %s\n", __func__);
1176 if(priv->ieee80211->bHwRadioOff)
1179 //unsigned long flags;
1180 down(&priv->wx_sem);
1181 if (DefaultChannelPlan[*val].Len != 0){
1182 priv ->channel_plan = *val;
1183 // Clear old channel map
1184 for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
1186 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1188 // Set new channel map
1189 for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
1191 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1199 static int r8180_wx_get_version(struct net_device *dev,
1200 struct iw_request_info *info,
1201 union iwreq_data *wrqu, char *extra)
1203 struct r8180_priv *priv = ieee80211_priv(dev);
1204 //struct ieee80211_device *ieee;
1206 down(&priv->wx_sem);
1207 strcpy(extra, "1020.0808");
1213 //added by amy 080818
1214 //receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive.
1215 static int r8180_wx_set_forcerate(struct net_device *dev,
1216 struct iw_request_info *info,
1217 union iwreq_data *wrqu, char *extra)
1219 struct r8180_priv *priv = ieee80211_priv(dev);
1220 u8 forcerate = *extra;
1222 down(&priv->wx_sem);
1224 printk("==============>%s(): forcerate is %d\n",__func__,forcerate);
1225 if((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1226 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1227 (forcerate == 96) || (forcerate == 108))
1229 priv->ForcedDataRate = 1;
1230 priv->ieee80211->rate = forcerate * 5;
1232 else if(forcerate == 0)
1234 priv->ForcedDataRate = 0;
1235 printk("OK! return rate adaptive\n");
1238 printk("ERR: wrong rate\n");
1243 static int r8180_wx_set_enc_ext(struct net_device *dev,
1244 struct iw_request_info *info,
1245 union iwreq_data *wrqu, char *extra)
1248 struct r8180_priv *priv = ieee80211_priv(dev);
1249 //printk("===>%s()\n", __func__);
1253 if(priv->ieee80211->bHwRadioOff)
1256 down(&priv->wx_sem);
1257 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1262 static int r8180_wx_set_auth(struct net_device *dev,
1263 struct iw_request_info *info,
1264 union iwreq_data *wrqu, char *extra)
1266 //printk("====>%s()\n", __func__);
1267 struct r8180_priv *priv = ieee80211_priv(dev);
1270 if(priv->ieee80211->bHwRadioOff)
1273 down(&priv->wx_sem);
1274 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1279 static int r8180_wx_set_mlme(struct net_device *dev,
1280 struct iw_request_info *info,
1281 union iwreq_data *wrqu, char *extra)
1283 //printk("====>%s()\n", __func__);
1286 struct r8180_priv *priv = ieee80211_priv(dev);
1289 if(priv->ieee80211->bHwRadioOff)
1293 down(&priv->wx_sem);
1295 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1300 static int r8180_wx_set_gen_ie(struct net_device *dev,
1301 struct iw_request_info *info,
1302 union iwreq_data *wrqu, char *extra)
1304 // printk("====>%s(), len:%d\n", __func__, data->length);
1306 struct r8180_priv *priv = ieee80211_priv(dev);
1309 if(priv->ieee80211->bHwRadioOff)
1312 down(&priv->wx_sem);
1314 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1317 //printk("<======%s(), ret:%d\n", __func__, ret);
1322 static iw_handler r8180_wx_handlers[] =
1324 NULL, /* SIOCSIWCOMMIT */
1325 r8180_wx_get_name, /* SIOCGIWNAME */
1326 dummy, /* SIOCSIWNWID */
1327 dummy, /* SIOCGIWNWID */
1328 r8180_wx_set_freq, /* SIOCSIWFREQ */
1329 r8180_wx_get_freq, /* SIOCGIWFREQ */
1330 r8180_wx_set_mode, /* SIOCSIWMODE */
1331 r8180_wx_get_mode, /* SIOCGIWMODE */
1332 r8180_wx_set_sens, /* SIOCSIWSENS */
1333 r8180_wx_get_sens, /* SIOCGIWSENS */
1334 NULL, /* SIOCSIWRANGE */
1335 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1336 NULL, /* SIOCSIWPRIV */
1337 NULL, /* SIOCGIWPRIV */
1338 NULL, /* SIOCSIWSTATS */
1339 NULL, /* SIOCGIWSTATS */
1340 dummy, /* SIOCSIWSPY */
1341 dummy, /* SIOCGIWSPY */
1342 NULL, /* SIOCGIWTHRSPY */
1343 NULL, /* SIOCWIWTHRSPY */
1344 r8180_wx_set_wap, /* SIOCSIWAP */
1345 r8180_wx_get_wap, /* SIOCGIWAP */
1346 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1347 dummy, /* SIOCGIWAPLIST -- depricated */
1348 r8180_wx_set_scan, /* SIOCSIWSCAN */
1349 r8180_wx_get_scan, /* SIOCGIWSCAN */
1350 r8180_wx_set_essid, /* SIOCSIWESSID */
1351 r8180_wx_get_essid, /* SIOCGIWESSID */
1352 dummy, /* SIOCSIWNICKN */
1353 dummy, /* SIOCGIWNICKN */
1354 NULL, /* -- hole -- */
1355 NULL, /* -- hole -- */
1356 r8180_wx_set_rate, /* SIOCSIWRATE */
1357 r8180_wx_get_rate, /* SIOCGIWRATE */
1358 r8180_wx_set_rts, /* SIOCSIWRTS */
1359 r8180_wx_get_rts, /* SIOCGIWRTS */
1360 r8180_wx_set_frag, /* SIOCSIWFRAG */
1361 r8180_wx_get_frag, /* SIOCGIWFRAG */
1362 dummy, /* SIOCSIWTXPOW */
1363 dummy, /* SIOCGIWTXPOW */
1364 r8180_wx_set_retry, /* SIOCSIWRETRY */
1365 r8180_wx_get_retry, /* SIOCGIWRETRY */
1366 r8180_wx_set_enc, /* SIOCSIWENCODE */
1367 r8180_wx_get_enc, /* SIOCGIWENCODE */
1368 r8180_wx_set_power, /* SIOCSIWPOWER */
1369 r8180_wx_get_power, /* SIOCGIWPOWER */
1370 NULL, /*---hole---*/
1371 NULL, /*---hole---*/
1372 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1373 NULL, /* SIOCSIWGENIE */
1374 r8180_wx_set_auth, /* SIOCSIWAUTH */
1375 NULL, /* SIOCSIWAUTH */
1376 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1377 NULL, /* SIOCSIWENCODEEXT */
1378 NULL, /* SIOCSIWPMKSA */
1379 NULL, /*---hole---*/
1383 static const struct iw_priv_args r8180_private_args[] = {
1385 SIOCIWFIRSTPRIV + 0x0,
1386 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1388 { SIOCIWFIRSTPRIV + 0x1,
1393 SIOCIWFIRSTPRIV + 0x2,
1394 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1396 { SIOCIWFIRSTPRIV + 0x3,
1400 /* added by christian */
1402 // SIOCIWFIRSTPRIV + 0x2,
1403 // IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prismhdr"
1405 /* end added by christian */
1407 SIOCIWFIRSTPRIV + 0x4,
1408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1411 { SIOCIWFIRSTPRIV + 0x5,
1416 SIOCIWFIRSTPRIV + 0x6,
1417 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1420 { SIOCIWFIRSTPRIV + 0x7,
1425 // SIOCIWFIRSTPRIV + 0x5,
1426 // 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpsmode"
1429 // SIOCIWFIRSTPRIV + 0x6,
1430 // IW_PRIV_SIZE_FIXED, 0, "setpsmode"
1432 //set/get mode have been realized in public handlers
1435 SIOCIWFIRSTPRIV + 0x8,
1436 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1439 SIOCIWFIRSTPRIV + 0x9,
1440 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1443 SIOCIWFIRSTPRIV + 0xA,
1444 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1447 SIOCIWFIRSTPRIV + 0xB,
1448 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1450 { SIOCIWFIRSTPRIV + 0xC,
1454 SIOCIWFIRSTPRIV + 0xD,
1455 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1457 { SIOCIWFIRSTPRIV + 0xE,
1461 SIOCIWFIRSTPRIV + 0xF,
1462 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1465 SIOCIWFIRSTPRIV + 0x10,
1469 SIOCIWFIRSTPRIV + 0x11,
1473 SIOCIWFIRSTPRIV + 0x12,
1477 SIOCIWFIRSTPRIV + 0x13,
1481 SIOCIWFIRSTPRIV + 0x14,
1482 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1485 SIOCIWFIRSTPRIV + 0x15,
1486 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1489 SIOCIWFIRSTPRIV + 0x16,
1493 SIOCIWFIRSTPRIV + 0x17,
1494 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1497 SIOCIWFIRSTPRIV + 0x18,
1498 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1503 static iw_handler r8180_private_handler[] = {
1504 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1506 r8180_wx_set_beaconinterval,
1508 //r8180_wx_set_monitor_type,
1509 r8180_wx_set_scan_type,
1513 r8180_wx_set_iwmode,
1514 r8180_wx_get_iwmode,
1515 r8180_wx_set_preamble,
1516 r8180_wx_get_preamble,
1518 r8180_wx_get_siglevel,
1520 r8180_wx_get_sigqual,
1521 r8180_wx_reset_stats,
1522 dummy,//r8180_wx_get_stats
1525 r8180_wx_set_channelplan,
1526 r8180_wx_get_channelplan,
1528 r8180_wx_get_version,
1529 r8180_wx_set_forcerate,
1532 static inline int is_same_network(struct ieee80211_network *src,
1533 struct ieee80211_network *dst,
1534 struct ieee80211_device *ieee)
1536 /* A network is only a duplicate if the channel, BSSID, ESSID
1537 * and the capability field (in particular IBSS and BSS) all match.
1538 * We treat all <hidden> with the same BSSID and channel
1540 return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1541 //((src->ssid_len == dst->ssid_len) &&
1542 (src->channel == dst->channel) &&
1543 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1544 (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1545 //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
1546 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1547 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1548 ((src->capability & WLAN_CAPABILITY_BSS) ==
1549 (dst->capability & WLAN_CAPABILITY_BSS)));
1552 //WB modefied to show signal to GUI on 18-01-2008
1553 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1555 struct r8180_priv *priv = ieee80211_priv(dev);
1556 struct ieee80211_device* ieee = priv->ieee80211;
1557 struct iw_statistics* wstats = &priv->wstats;
1558 //struct ieee80211_network* target = NULL;
1562 //unsigned long flag;
1564 if (ieee->state < IEEE80211_LINKED)
1566 wstats->qual.qual = 0;
1567 wstats->qual.level = 0;
1568 wstats->qual.noise = 0;
1569 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1573 spin_lock_irqsave(&ieee->lock, flag);
1574 list_for_each_entry(target, &ieee->network_list, list)
1576 if (is_same_network(target, &ieee->current_network, ieee))
1578 printk("it's same network:%s\n", target->ssid);
1582 tmp_level = target->stats.signalstrength;
1583 tmp_qual = target->stats.signal;
1588 tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
1589 tmp_qual = (15*tmp_qual + target->stats.signal)/16;
1592 tmp_level = target->stats.signal;
1593 tmp_qual = target->stats.signalstrength;
1594 tmp_noise = target->stats.noise;
1595 printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1600 spin_unlock_irqrestore(&ieee->lock, flag);
1602 tmp_level = (&ieee->current_network)->stats.signal;
1603 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1604 tmp_noise = (&ieee->current_network)->stats.noise;
1605 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1607 // printk("level:%d\n", tmp_level);
1608 wstats->qual.level = tmp_level;
1609 wstats->qual.qual = tmp_qual;
1610 wstats->qual.noise = tmp_noise;
1611 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1615 struct iw_handler_def r8180_wx_handlers_def={
1616 .standard = r8180_wx_handlers,
1617 .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
1618 .private = r8180_private_handler,
1619 .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
1620 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1621 .get_wireless_stats = r8180_get_wireless_stats,
1622 .private_args = (struct iw_priv_args *)r8180_private_args,