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"
29 //#define RATE_COUNT 4
30 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
31 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
33 #define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
35 static CHANNEL_LIST DefaultChannelPlan[] = {
36 // {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //Default channel plan
37 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
38 {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
39 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
40 {{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.
41 {{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.
42 {{14,36,40,44,48,52,56,60,64},9}, //MKK
43 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
44 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
45 {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
46 {{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
48 static int r8180_wx_get_freq(struct net_device *dev,
49 struct iw_request_info *a,
50 union iwreq_data *wrqu, char *b)
52 struct r8180_priv *priv = ieee80211_priv(dev);
54 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
58 int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
59 union iwreq_data *wrqu, char *key)
61 struct r8180_priv *priv = ieee80211_priv(dev);
62 struct iw_point *erq = &(wrqu->encoding);
64 if(priv->ieee80211->bHwRadioOff)
67 if (erq->flags & IW_ENCODE_DISABLED) {
71 /* i = erq->flags & IW_ENCODE_INDEX;
75 if (erq->length > 0) {
77 //int len = erq->length <= 5 ? 5 : 13;
79 u32* tkey= (u32*) key;
80 priv->key0[0] = tkey[0];
81 priv->key0[1] = tkey[1];
82 priv->key0[2] = tkey[2];
83 priv->key0[3] = tkey[3] &0xff;
84 DMESG("Setting wep key to %x %x %x %x",
85 tkey[0],tkey[1],tkey[2],tkey[3]);
86 rtl8180_set_hw_wep(dev);
92 static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
93 union iwreq_data *wrqu, char *b)
95 int *parms = (int *)b;
98 struct r8180_priv *priv = ieee80211_priv(dev);
100 if(priv->ieee80211->bHwRadioOff)
104 DMESG("setting beacon interval to %x",bi);
106 priv->ieee80211->current_network.beacon_interval=bi;
115 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
116 union iwreq_data *wrqu, char *b)
118 struct r8180_priv *priv = ieee80211_priv(dev);
119 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
124 static int r8180_wx_get_rate(struct net_device *dev,
125 struct iw_request_info *info,
126 union iwreq_data *wrqu, char *extra)
128 struct r8180_priv *priv = ieee80211_priv(dev);
129 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
134 static int r8180_wx_set_rate(struct net_device *dev,
135 struct iw_request_info *info,
136 union iwreq_data *wrqu, char *extra)
139 struct r8180_priv *priv = ieee80211_priv(dev);
142 if(priv->ieee80211->bHwRadioOff)
147 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
155 static int r8180_wx_set_crcmon(struct net_device *dev,
156 struct iw_request_info *info,
157 union iwreq_data *wrqu, char *extra)
159 struct r8180_priv *priv = ieee80211_priv(dev);
160 int *parms = (int *)extra;
161 int enable = (parms[0] > 0);
162 short prev = priv->crcmon;
165 if(priv->ieee80211->bHwRadioOff)
175 DMESG("bad CRC in monitor mode are %s",
176 priv->crcmon ? "accepted" : "rejected");
178 if(prev != priv->crcmon && priv->up){
189 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
190 union iwreq_data *wrqu, char *b)
192 struct r8180_priv *priv = ieee80211_priv(dev);
196 if(priv->ieee80211->bHwRadioOff)
201 // printk("set mode ENABLE_IPS\n");
202 if(priv->bInactivePs){
203 if(wrqu->mode == IW_MODE_ADHOC)
207 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
209 //rtl8180_commit(dev);
215 //YJ,add,080819,for hidden ap
216 struct iw_range_with_scan_capa
218 /* Informative stuff (to choose between different interface) */
219 __u32 throughput; /* To give an idea... */
220 /* In theory this value should be the maximum benchmarked
221 * TCP/IP throughput, because with most of these devices the
222 * bit rate is meaningless (overhead an co) to estimate how
223 * fast the connection will go and pick the fastest one.
224 * I suggest people to play with Netperf or any benchmark...
227 /* NWID (or domain id) */
228 __u32 min_nwid; /* Minimal NWID we are able to set */
229 __u32 max_nwid; /* Maximal NWID we are able to set */
231 /* Old Frequency (backward compat - moved lower ) */
232 __u16 old_num_channels;
233 __u8 old_num_frequency;
235 /* Scan capabilities */
238 //YJ,add,080819,for hidden ap
241 static int rtl8180_wx_get_range(struct net_device *dev,
242 struct iw_request_info *info,
243 union iwreq_data *wrqu, char *extra)
245 struct iw_range *range = (struct iw_range *)extra;
246 struct r8180_priv *priv = ieee80211_priv(dev);
249 //struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
251 wrqu->data.length = sizeof(*range);
252 memset(range, 0, sizeof(*range));
254 /* Let's try to keep this struct in the same order as in
255 * linux/include/wireless.h
258 /* TODO: See what values we can set, and remove the ones we can't
259 * set, or fill them with some default data.
262 /* ~5 Mb/s real (802.11b) */
263 range->throughput = 5 * 1000 * 1000;
265 // TODO: Not used in 802.11b?
266 // range->min_nwid; /* Minimal NWID we are able to set */
267 // TODO: Not used in 802.11b?
268 // range->max_nwid; /* Maximal NWID we are able to set */
270 /* Old Frequency (backward compat - moved lower ) */
271 // range->old_num_channels;
272 // range->old_num_frequency;
273 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
274 if(priv->rf_set_sens != NULL)
275 range->sensitivity = priv->max_sens; /* signal level threshold range */
277 range->max_qual.qual = 100;
278 /* TODO: Find real max RSSI and stick here */
279 range->max_qual.level = 0;
280 range->max_qual.noise = -98;
281 range->max_qual.updated = 7; /* Updated all three */
283 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
284 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
285 range->avg_qual.level = 20 + -98;
286 range->avg_qual.noise = 0;
287 range->avg_qual.updated = 7; /* Updated all three */
289 range->num_bitrates = RATE_COUNT;
291 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
292 range->bitrate[i] = rtl8180_rates[i];
295 range->min_frag = MIN_FRAG_THRESHOLD;
296 range->max_frag = MAX_FRAG_THRESHOLD;
300 range->we_version_compiled = WIRELESS_EXT;
301 range->we_version_source = 16;
303 // range->retry_capa; /* What retry options are supported */
304 // range->retry_flags; /* How to decode max/min retry limit */
305 // range->r_time_flags; /* How to decode max/min retry life */
306 // range->min_retry; /* Minimal number of retries */
307 // range->max_retry; /* Maximal number of retries */
308 // range->min_r_time; /* Minimal retry lifetime */
309 // range->max_r_time; /* Maximal retry lifetime */
311 range->num_channels = 14;
313 for (i = 0, val = 0; i < 14; i++) {
315 // Include only legal frequencies for some countries
317 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
319 if ((priv->ieee80211->channel_map)[i+1]) {
321 range->freq[val].i = i + 1;
322 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
323 range->freq[val].e = 1;
326 // FIXME: do we need to set anything for channels
330 if (val == IW_MAX_FREQUENCIES)
334 range->num_frequency = val;
335 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
336 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
338 //tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
344 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
345 union iwreq_data *wrqu, char *b)
347 struct r8180_priv *priv = ieee80211_priv(dev);
349 struct ieee80211_device* ieee = priv->ieee80211;
352 if(priv->ieee80211->bHwRadioOff)
355 //YJ,add,080819, for hidden ap
356 //printk("==*&*&*&==>%s in\n", __func__);
357 //printk("=*&*&*&*===>flag:%x, %x\n", wrqu->data.flags, IW_SCAN_THIS_ESSID);
358 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
360 struct iw_scan_req* req = (struct iw_scan_req*)b;
363 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
364 ieee->current_network.ssid_len = req->essid_len;
365 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
366 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
369 //YJ,add,080819, for hidden ap, end
374 // printk("set scan ENABLE_IPS\n");
375 priv->ieee80211->actscanning = true;
376 if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
378 // down(&priv->ieee80211->wx_sem);
380 // if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || !(priv->ieee80211->proto_started)){
382 // up(&priv->ieee80211->wx_sem);
383 // up(&priv->wx_sem);
387 // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
388 //printk("start scan============================>\n");
389 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
390 //ieee80211_start_scan(priv->ieee80211);
391 /* intentionally forget to up sem */
392 // up(&priv->ieee80211->wx_sem);
398 //YJ,add,080828, prevent scan in BusyTraffic
399 //FIXME: Need to consider last scan time
400 if ((priv->link_detect.bBusyTraffic) && (true))
403 printk("Now traffic is busy, please try later!\n");
406 //YJ,add,080828, prevent scan in BusyTraffic,end
407 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
419 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
420 union iwreq_data *wrqu, char *b)
424 struct r8180_priv *priv = ieee80211_priv(dev);
428 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
437 static int r8180_wx_set_essid(struct net_device *dev,
438 struct iw_request_info *a,
439 union iwreq_data *wrqu, char *b)
441 struct r8180_priv *priv = ieee80211_priv(dev);
445 if(priv->ieee80211->bHwRadioOff)
450 //printk("set essid ENABLE_IPS\n");
451 if(priv->bInactivePs)
454 // printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b, wrqu->essid.length, wrqu->essid.flags);
456 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
463 static int r8180_wx_get_essid(struct net_device *dev,
464 struct iw_request_info *a,
465 union iwreq_data *wrqu, char *b)
468 struct r8180_priv *priv = ieee80211_priv(dev);
472 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
480 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
481 union iwreq_data *wrqu, char *b)
484 struct r8180_priv *priv = ieee80211_priv(dev);
487 if(priv->ieee80211->bHwRadioOff)
492 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
499 static int r8180_wx_get_name(struct net_device *dev,
500 struct iw_request_info *info,
501 union iwreq_data *wrqu, char *extra)
503 struct r8180_priv *priv = ieee80211_priv(dev);
504 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
507 static int r8180_wx_set_frag(struct net_device *dev,
508 struct iw_request_info *info,
509 union iwreq_data *wrqu, char *extra)
511 struct r8180_priv *priv = ieee80211_priv(dev);
513 if(priv->ieee80211->bHwRadioOff)
516 if (wrqu->frag.disabled)
517 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
519 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
520 wrqu->frag.value > MAX_FRAG_THRESHOLD)
523 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
530 static int r8180_wx_get_frag(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *extra)
534 struct r8180_priv *priv = ieee80211_priv(dev);
536 wrqu->frag.value = priv->ieee80211->fts;
537 wrqu->frag.fixed = 0; /* no auto select */
538 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
544 static int r8180_wx_set_wap(struct net_device *dev,
545 struct iw_request_info *info,
546 union iwreq_data *awrq,
550 struct r8180_priv *priv = ieee80211_priv(dev);
552 if(priv->ieee80211->bHwRadioOff)
557 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
565 static int r8180_wx_get_wap(struct net_device *dev,
566 struct iw_request_info *info,
567 union iwreq_data *wrqu, char *extra)
569 struct r8180_priv *priv = ieee80211_priv(dev);
571 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
575 static int r8180_wx_set_enc(struct net_device *dev,
576 struct iw_request_info *info,
577 union iwreq_data *wrqu, char *key)
579 struct r8180_priv *priv = ieee80211_priv(dev);
582 if(priv->ieee80211->bHwRadioOff)
588 if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
590 DMESG("Setting SW wep key");
591 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
599 static int r8180_wx_get_enc(struct net_device *dev,
600 struct iw_request_info *info,
601 union iwreq_data *wrqu, char *key)
603 struct r8180_priv *priv = ieee80211_priv(dev);
605 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
609 static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
610 iwreq_data *wrqu, char *p){
612 struct r8180_priv *priv = ieee80211_priv(dev);
616 if(priv->ieee80211->bHwRadioOff)
619 priv->ieee80211->active_scan = mode;
625 /* added by christian */
627 static int r8180_wx_set_monitor_type(struct net_device *dev, struct iw_request_info *aa, union
628 iwreq_data *wrqu, char *p){
630 struct r8180_priv *priv = ieee80211_priv(dev);
634 if(priv->ieee80211->iw_mode != IW_MODE_MONITOR) return -1;
635 priv->prism_hdr = mode;
636 if(!mode)dev->type=ARPHRD_IEEE80211;
637 else dev->type=ARPHRD_IEEE80211_PRISM;
638 DMESG("using %s RX encap", mode ? "AVS":"80211");
643 //of r8180_wx_set_monitor_type
644 /* end added christian */
646 static int r8180_wx_set_retry(struct net_device *dev,
647 struct iw_request_info *info,
648 union iwreq_data *wrqu, char *extra)
650 struct r8180_priv *priv = ieee80211_priv(dev);
653 if(priv->ieee80211->bHwRadioOff)
658 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
659 wrqu->retry.disabled){
663 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
668 if(wrqu->retry.value > R8180_MAX_RETRY){
672 if (wrqu->retry.flags & IW_RETRY_MAX) {
673 priv->retry_rts = wrqu->retry.value;
674 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
677 priv->retry_data = wrqu->retry.value;
678 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
682 * We might try to write directly the TX config register
683 * or to restart just the (R)TX process.
684 * I'm unsure if whole reset is really needed
690 rtl8180_rtx_disable(dev);
691 rtl8180_rx_enable(dev);
692 rtl8180_tx_enable(dev);
702 static int r8180_wx_get_retry(struct net_device *dev,
703 struct iw_request_info *info,
704 union iwreq_data *wrqu, char *extra)
706 struct r8180_priv *priv = ieee80211_priv(dev);
709 wrqu->retry.disabled = 0; /* can't be disabled */
711 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
715 if (wrqu->retry.flags & IW_RETRY_MAX) {
716 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
717 wrqu->retry.value = priv->retry_rts;
719 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
720 wrqu->retry.value = priv->retry_data;
722 //DMESG("returning %d",wrqu->retry.value);
728 static int r8180_wx_get_sens(struct net_device *dev,
729 struct iw_request_info *info,
730 union iwreq_data *wrqu, char *extra)
732 struct r8180_priv *priv = ieee80211_priv(dev);
733 if(priv->rf_set_sens == NULL)
734 return -1; /* we have not this support for this radio */
735 wrqu->sens.value = priv->sens;
740 static int r8180_wx_set_sens(struct net_device *dev,
741 struct iw_request_info *info,
742 union iwreq_data *wrqu, char *extra)
745 struct r8180_priv *priv = ieee80211_priv(dev);
749 if(priv->ieee80211->bHwRadioOff)
753 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
754 if(priv->rf_set_sens == NULL) {
755 err= -1; /* we have not this support for this radio */
758 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
759 priv->sens = wrqu->sens.value;
770 static int r8180_wx_set_rawtx(struct net_device *dev,
771 struct iw_request_info *info,
772 union iwreq_data *wrqu, char *extra)
774 struct r8180_priv *priv = ieee80211_priv(dev);
777 if(priv->ieee80211->bHwRadioOff)
782 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
790 static int r8180_wx_get_power(struct net_device *dev,
791 struct iw_request_info *info,
792 union iwreq_data *wrqu, char *extra)
795 struct r8180_priv *priv = ieee80211_priv(dev);
799 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
806 static int r8180_wx_set_power(struct net_device *dev,
807 struct iw_request_info *info,
808 union iwreq_data *wrqu, char *extra)
811 struct r8180_priv *priv = ieee80211_priv(dev);
814 if(priv->ieee80211->bHwRadioOff)
818 printk("=>>>>>>>>>>=============================>set power:%d,%d!\n",wrqu->power.disabled, wrqu->power.flags);
819 if (wrqu->power.disabled==0) {
820 wrqu->power.flags|=IW_POWER_ALL_R;
821 wrqu->power.flags|=IW_POWER_TIMEOUT;
822 wrqu->power.value =1000;
825 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
832 static int r8180_wx_set_rts(struct net_device *dev,
833 struct iw_request_info *info,
834 union iwreq_data *wrqu, char *extra)
836 struct r8180_priv *priv = ieee80211_priv(dev);
839 if(priv->ieee80211->bHwRadioOff)
842 if (wrqu->rts.disabled)
843 priv->rts = DEFAULT_RTS_THRESHOLD;
845 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
846 wrqu->rts.value > MAX_RTS_THRESHOLD)
849 priv->rts = wrqu->rts.value;
854 static int r8180_wx_get_rts(struct net_device *dev,
855 struct iw_request_info *info,
856 union iwreq_data *wrqu, char *extra)
858 struct r8180_priv *priv = ieee80211_priv(dev);
862 wrqu->rts.value = priv->rts;
863 wrqu->rts.fixed = 0; /* no auto select */
864 wrqu->rts.disabled = (wrqu->rts.value == 0);
868 static int dummy(struct net_device *dev, struct iw_request_info *a,
869 union iwreq_data *wrqu,char *b)
875 static int r8180_wx_get_psmode(struct net_device *dev,
876 struct iw_request_info *info,
877 union iwreq_data *wrqu, char *extra)
879 struct r8180_priv *priv = ieee80211_priv(dev);
880 struct ieee80211_device *ieee;
888 ieee = priv->ieee80211;
889 if(ieee->ps == IEEE80211_PS_DISABLED) {
890 *((unsigned int *)extra) = IEEE80211_PS_DISABLED;
893 *((unsigned int *)extra) = IW_POWER_TIMEOUT;
894 if (ieee->ps & IEEE80211_PS_MBCAST)
895 *((unsigned int *)extra) |= IW_POWER_ALL_R;
897 *((unsigned int *)extra) |= IW_POWER_UNICAST_R;
905 static int r8180_wx_set_psmode(struct net_device *dev,
906 struct iw_request_info *info,
907 union iwreq_data *wrqu, char *extra)
909 struct r8180_priv *priv = ieee80211_priv(dev);
910 //struct ieee80211_device *ieee;
917 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
926 static int r8180_wx_get_iwmode(struct net_device *dev,
927 struct iw_request_info *info,
928 union iwreq_data *wrqu, char *extra)
930 struct r8180_priv *priv = ieee80211_priv(dev);
931 struct ieee80211_device *ieee;
938 ieee = priv->ieee80211;
940 strcpy(extra, "802.11");
941 if(ieee->modulation & IEEE80211_CCK_MODULATION) {
943 if(ieee->modulation & IEEE80211_OFDM_MODULATION)
945 } else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
952 static int r8180_wx_set_iwmode(struct net_device *dev,
953 struct iw_request_info *info,
954 union iwreq_data *wrqu, char *extra)
956 struct r8180_priv *priv = ieee80211_priv(dev);
957 struct ieee80211_device *ieee = priv->ieee80211;
958 int *param = (int *)extra;
960 int modulation = 0, mode = 0;
963 if(priv->ieee80211->bHwRadioOff)
969 modulation |= IEEE80211_CCK_MODULATION;
971 printk(KERN_INFO "B mode!\n");
972 } else if (*param == 2) {
973 modulation |= IEEE80211_OFDM_MODULATION;
975 printk(KERN_INFO "G mode!\n");
976 } else if (*param == 3) {
977 modulation |= IEEE80211_CCK_MODULATION;
978 modulation |= IEEE80211_OFDM_MODULATION;
979 mode = IEEE_B|IEEE_G;
980 printk(KERN_INFO "B/G mode!\n");
983 if(ieee->proto_started) {
984 ieee80211_stop_protocol(ieee);
986 ieee->modulation = modulation;
987 ieee80211_start_protocol(ieee);
990 ieee->modulation = modulation;
991 // ieee80211_start_protocol(ieee);
998 static int r8180_wx_get_preamble(struct net_device *dev,
999 struct iw_request_info *info,
1000 union iwreq_data *wrqu, char *extra)
1002 struct r8180_priv *priv = ieee80211_priv(dev);
1006 down(&priv->wx_sem);
1010 *extra = (char) priv->plcp_preamble_mode; // 0:auto 1:short 2:long
1015 static int r8180_wx_set_preamble(struct net_device *dev,
1016 struct iw_request_info *info,
1017 union iwreq_data *wrqu, char *extra)
1019 struct r8180_priv *priv = ieee80211_priv(dev);
1023 if(priv->ieee80211->bHwRadioOff)
1026 down(&priv->wx_sem);
1027 if (*extra<0||*extra>2)
1030 priv->plcp_preamble_mode = *((short *)extra) ;
1038 static int r8180_wx_get_siglevel(struct net_device *dev,
1039 struct iw_request_info *info,
1040 union iwreq_data *wrqu, char *extra)
1042 struct r8180_priv *priv = ieee80211_priv(dev);
1043 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1048 down(&priv->wx_sem);
1049 // Modify by hikaru 6.5
1050 *((int *)extra) = priv->wstats.qual.level;//for interface test ,it should be the priv->wstats.qual.level;
1058 static int r8180_wx_get_sigqual(struct net_device *dev,
1059 struct iw_request_info *info,
1060 union iwreq_data *wrqu, char *extra)
1062 struct r8180_priv *priv = ieee80211_priv(dev);
1063 //struct ieee80211_network *network = &(priv->ieee80211->current_network);
1068 down(&priv->wx_sem);
1069 // Modify by hikaru 6.5
1070 *((int *)extra) = priv->wstats.qual.qual;//for interface test ,it should be the priv->wstats.qual.qual;
1078 static int r8180_wx_reset_stats(struct net_device *dev,
1079 struct iw_request_info *info,
1080 union iwreq_data *wrqu, char *extra)
1082 struct r8180_priv *priv =ieee80211_priv(dev);
1083 down(&priv->wx_sem);
1085 priv->stats.txrdu = 0;
1086 priv->stats.rxrdu = 0;
1087 priv->stats.rxnolast = 0;
1088 priv->stats.rxnodata = 0;
1089 priv->stats.rxnopointer = 0;
1090 priv->stats.txnperr = 0;
1091 priv->stats.txresumed = 0;
1092 priv->stats.rxerr = 0;
1093 priv->stats.rxoverflow = 0;
1094 priv->stats.rxint = 0;
1096 priv->stats.txnpokint = 0;
1097 priv->stats.txhpokint = 0;
1098 priv->stats.txhperr = 0;
1099 priv->stats.ints = 0;
1100 priv->stats.shints = 0;
1101 priv->stats.txoverflow = 0;
1102 priv->stats.rxdmafail = 0;
1103 priv->stats.txbeacon = 0;
1104 priv->stats.txbeaconerr = 0;
1105 priv->stats.txlpokint = 0;
1106 priv->stats.txlperr = 0;
1107 priv->stats.txretry =0;//20060601
1108 priv->stats.rxcrcerrmin=0;
1109 priv->stats.rxcrcerrmid=0;
1110 priv->stats.rxcrcerrmax=0;
1111 priv->stats.rxicverr=0;
1118 static int r8180_wx_radio_on(struct net_device *dev,
1119 struct iw_request_info *info,
1120 union iwreq_data *wrqu, char *extra)
1122 struct r8180_priv *priv =ieee80211_priv(dev);
1124 if(priv->ieee80211->bHwRadioOff)
1128 down(&priv->wx_sem);
1129 priv->rf_wakeup(dev);
1137 static int r8180_wx_radio_off(struct net_device *dev,
1138 struct iw_request_info *info,
1139 union iwreq_data *wrqu, char *extra)
1141 struct r8180_priv *priv =ieee80211_priv(dev);
1143 if(priv->ieee80211->bHwRadioOff)
1147 down(&priv->wx_sem);
1148 priv->rf_sleep(dev);
1155 static int r8180_wx_get_channelplan(struct net_device *dev,
1156 struct iw_request_info *info,
1157 union iwreq_data *wrqu, char *extra)
1159 struct r8180_priv *priv = ieee80211_priv(dev);
1163 down(&priv->wx_sem);
1164 *extra = priv->channel_plan;
1172 static int r8180_wx_set_channelplan(struct net_device *dev,
1173 struct iw_request_info *info,
1174 union iwreq_data *wrqu, char *extra)
1176 struct r8180_priv *priv = ieee80211_priv(dev);
1177 //struct ieee80211_device *ieee = netdev_priv(dev);
1178 int *val = (int *)extra;
1180 printk("-----in fun %s\n", __func__);
1182 if(priv->ieee80211->bHwRadioOff)
1185 //unsigned long flags;
1186 down(&priv->wx_sem);
1187 if (DefaultChannelPlan[*val].Len != 0){
1188 priv ->channel_plan = *val;
1189 // Clear old channel map
1190 for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
1192 #ifdef ENABLE_DOT11D
1193 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1195 priv->ieee80211->channel_map[i] = 0;
1198 // Set new channel map
1199 for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
1201 #ifdef ENABLE_DOT11D
1202 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1204 priv->ieee80211->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1213 static int r8180_wx_get_version(struct net_device *dev,
1214 struct iw_request_info *info,
1215 union iwreq_data *wrqu, char *extra)
1217 struct r8180_priv *priv = ieee80211_priv(dev);
1218 //struct ieee80211_device *ieee;
1220 down(&priv->wx_sem);
1221 strcpy(extra, "1020.0808");
1227 //added by amy 080818
1228 //receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive.
1229 static int r8180_wx_set_forcerate(struct net_device *dev,
1230 struct iw_request_info *info,
1231 union iwreq_data *wrqu, char *extra)
1233 struct r8180_priv *priv = ieee80211_priv(dev);
1234 u8 forcerate = *extra;
1236 down(&priv->wx_sem);
1238 printk("==============>%s(): forcerate is %d\n",__func__,forcerate);
1239 if((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1240 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1241 (forcerate == 96) || (forcerate == 108))
1243 priv->ForcedDataRate = 1;
1244 priv->ieee80211->rate = forcerate * 5;
1246 else if(forcerate == 0)
1248 priv->ForcedDataRate = 0;
1249 printk("OK! return rate adaptive\n");
1252 printk("ERR: wrong rate\n");
1257 static int r8180_wx_set_enc_ext(struct net_device *dev,
1258 struct iw_request_info *info,
1259 union iwreq_data *wrqu, char *extra)
1262 struct r8180_priv *priv = ieee80211_priv(dev);
1263 //printk("===>%s()\n", __func__);
1267 if(priv->ieee80211->bHwRadioOff)
1270 down(&priv->wx_sem);
1271 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1276 static int r8180_wx_set_auth(struct net_device *dev,
1277 struct iw_request_info *info,
1278 union iwreq_data *wrqu, char *extra)
1280 //printk("====>%s()\n", __func__);
1281 struct r8180_priv *priv = ieee80211_priv(dev);
1284 if(priv->ieee80211->bHwRadioOff)
1287 down(&priv->wx_sem);
1288 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1293 static int r8180_wx_set_mlme(struct net_device *dev,
1294 struct iw_request_info *info,
1295 union iwreq_data *wrqu, char *extra)
1297 //printk("====>%s()\n", __func__);
1300 struct r8180_priv *priv = ieee80211_priv(dev);
1303 if(priv->ieee80211->bHwRadioOff)
1307 down(&priv->wx_sem);
1309 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1314 static int r8180_wx_set_gen_ie(struct net_device *dev,
1315 struct iw_request_info *info,
1316 union iwreq_data *wrqu, char *extra)
1318 // printk("====>%s(), len:%d\n", __func__, data->length);
1320 struct r8180_priv *priv = ieee80211_priv(dev);
1323 if(priv->ieee80211->bHwRadioOff)
1326 down(&priv->wx_sem);
1328 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1331 //printk("<======%s(), ret:%d\n", __func__, ret);
1336 static iw_handler r8180_wx_handlers[] =
1338 NULL, /* SIOCSIWCOMMIT */
1339 r8180_wx_get_name, /* SIOCGIWNAME */
1340 dummy, /* SIOCSIWNWID */
1341 dummy, /* SIOCGIWNWID */
1342 r8180_wx_set_freq, /* SIOCSIWFREQ */
1343 r8180_wx_get_freq, /* SIOCGIWFREQ */
1344 r8180_wx_set_mode, /* SIOCSIWMODE */
1345 r8180_wx_get_mode, /* SIOCGIWMODE */
1346 r8180_wx_set_sens, /* SIOCSIWSENS */
1347 r8180_wx_get_sens, /* SIOCGIWSENS */
1348 NULL, /* SIOCSIWRANGE */
1349 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1350 NULL, /* SIOCSIWPRIV */
1351 NULL, /* SIOCGIWPRIV */
1352 NULL, /* SIOCSIWSTATS */
1353 NULL, /* SIOCGIWSTATS */
1354 dummy, /* SIOCSIWSPY */
1355 dummy, /* SIOCGIWSPY */
1356 NULL, /* SIOCGIWTHRSPY */
1357 NULL, /* SIOCWIWTHRSPY */
1358 r8180_wx_set_wap, /* SIOCSIWAP */
1359 r8180_wx_get_wap, /* SIOCGIWAP */
1360 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1361 dummy, /* SIOCGIWAPLIST -- depricated */
1362 r8180_wx_set_scan, /* SIOCSIWSCAN */
1363 r8180_wx_get_scan, /* SIOCGIWSCAN */
1364 r8180_wx_set_essid, /* SIOCSIWESSID */
1365 r8180_wx_get_essid, /* SIOCGIWESSID */
1366 dummy, /* SIOCSIWNICKN */
1367 dummy, /* SIOCGIWNICKN */
1368 NULL, /* -- hole -- */
1369 NULL, /* -- hole -- */
1370 r8180_wx_set_rate, /* SIOCSIWRATE */
1371 r8180_wx_get_rate, /* SIOCGIWRATE */
1372 r8180_wx_set_rts, /* SIOCSIWRTS */
1373 r8180_wx_get_rts, /* SIOCGIWRTS */
1374 r8180_wx_set_frag, /* SIOCSIWFRAG */
1375 r8180_wx_get_frag, /* SIOCGIWFRAG */
1376 dummy, /* SIOCSIWTXPOW */
1377 dummy, /* SIOCGIWTXPOW */
1378 r8180_wx_set_retry, /* SIOCSIWRETRY */
1379 r8180_wx_get_retry, /* SIOCGIWRETRY */
1380 r8180_wx_set_enc, /* SIOCSIWENCODE */
1381 r8180_wx_get_enc, /* SIOCGIWENCODE */
1382 r8180_wx_set_power, /* SIOCSIWPOWER */
1383 r8180_wx_get_power, /* SIOCGIWPOWER */
1384 NULL, /*---hole---*/
1385 NULL, /*---hole---*/
1386 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1387 NULL, /* SIOCSIWGENIE */
1388 r8180_wx_set_auth, /* SIOCSIWAUTH */
1389 NULL, /* SIOCSIWAUTH */
1390 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1391 NULL, /* SIOCSIWENCODEEXT */
1392 NULL, /* SIOCSIWPMKSA */
1393 NULL, /*---hole---*/
1397 static const struct iw_priv_args r8180_private_args[] = {
1399 SIOCIWFIRSTPRIV + 0x0,
1400 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1402 { SIOCIWFIRSTPRIV + 0x1,
1407 SIOCIWFIRSTPRIV + 0x2,
1408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1410 { SIOCIWFIRSTPRIV + 0x3,
1414 /* added by christian */
1416 // SIOCIWFIRSTPRIV + 0x2,
1417 // IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prismhdr"
1419 /* end added by christian */
1421 SIOCIWFIRSTPRIV + 0x4,
1422 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1425 { SIOCIWFIRSTPRIV + 0x5,
1430 SIOCIWFIRSTPRIV + 0x6,
1431 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1434 { SIOCIWFIRSTPRIV + 0x7,
1439 // SIOCIWFIRSTPRIV + 0x5,
1440 // 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpsmode"
1443 // SIOCIWFIRSTPRIV + 0x6,
1444 // IW_PRIV_SIZE_FIXED, 0, "setpsmode"
1446 //set/get mode have been realized in public handlers
1449 SIOCIWFIRSTPRIV + 0x8,
1450 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1453 SIOCIWFIRSTPRIV + 0x9,
1454 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1457 SIOCIWFIRSTPRIV + 0xA,
1458 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1461 SIOCIWFIRSTPRIV + 0xB,
1462 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1464 { SIOCIWFIRSTPRIV + 0xC,
1468 SIOCIWFIRSTPRIV + 0xD,
1469 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1471 { SIOCIWFIRSTPRIV + 0xE,
1475 SIOCIWFIRSTPRIV + 0xF,
1476 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1479 SIOCIWFIRSTPRIV + 0x10,
1483 SIOCIWFIRSTPRIV + 0x11,
1487 SIOCIWFIRSTPRIV + 0x12,
1491 SIOCIWFIRSTPRIV + 0x13,
1495 SIOCIWFIRSTPRIV + 0x14,
1496 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1499 SIOCIWFIRSTPRIV + 0x15,
1500 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1503 SIOCIWFIRSTPRIV + 0x16,
1507 SIOCIWFIRSTPRIV + 0x17,
1508 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1511 SIOCIWFIRSTPRIV + 0x18,
1512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1517 static iw_handler r8180_private_handler[] = {
1518 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1520 r8180_wx_set_beaconinterval,
1522 //r8180_wx_set_monitor_type,
1523 r8180_wx_set_scan_type,
1527 r8180_wx_set_iwmode,
1528 r8180_wx_get_iwmode,
1529 r8180_wx_set_preamble,
1530 r8180_wx_get_preamble,
1532 r8180_wx_get_siglevel,
1534 r8180_wx_get_sigqual,
1535 r8180_wx_reset_stats,
1536 dummy,//r8180_wx_get_stats
1539 r8180_wx_set_channelplan,
1540 r8180_wx_get_channelplan,
1542 r8180_wx_get_version,
1543 r8180_wx_set_forcerate,
1546 #if WIRELESS_EXT >= 17
1547 static inline int is_same_network(struct ieee80211_network *src,
1548 struct ieee80211_network *dst,
1549 struct ieee80211_device *ieee)
1551 /* A network is only a duplicate if the channel, BSSID, ESSID
1552 * and the capability field (in particular IBSS and BSS) all match.
1553 * We treat all <hidden> with the same BSSID and channel
1555 return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1556 //((src->ssid_len == dst->ssid_len) &&
1557 (src->channel == dst->channel) &&
1558 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1559 (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
1560 //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
1561 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1562 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1563 ((src->capability & WLAN_CAPABILITY_BSS) ==
1564 (dst->capability & WLAN_CAPABILITY_BSS)));
1567 //WB modefied to show signal to GUI on 18-01-2008
1568 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1570 struct r8180_priv *priv = ieee80211_priv(dev);
1571 struct ieee80211_device* ieee = priv->ieee80211;
1572 struct iw_statistics* wstats = &priv->wstats;
1573 //struct ieee80211_network* target = NULL;
1577 //unsigned long flag;
1579 if (ieee->state < IEEE80211_LINKED)
1581 wstats->qual.qual = 0;
1582 wstats->qual.level = 0;
1583 wstats->qual.noise = 0;
1584 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1588 spin_lock_irqsave(&ieee->lock, flag);
1589 list_for_each_entry(target, &ieee->network_list, list)
1591 if (is_same_network(target, &ieee->current_network, ieee))
1593 printk("it's same network:%s\n", target->ssid);
1597 tmp_level = target->stats.signalstrength;
1598 tmp_qual = target->stats.signal;
1603 tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
1604 tmp_qual = (15*tmp_qual + target->stats.signal)/16;
1607 tmp_level = target->stats.signal;
1608 tmp_qual = target->stats.signalstrength;
1609 tmp_noise = target->stats.noise;
1610 printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1615 spin_unlock_irqrestore(&ieee->lock, flag);
1617 tmp_level = (&ieee->current_network)->stats.signal;
1618 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1619 tmp_noise = (&ieee->current_network)->stats.noise;
1620 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1622 // printk("level:%d\n", tmp_level);
1623 wstats->qual.level = tmp_level;
1624 wstats->qual.qual = tmp_qual;
1625 wstats->qual.noise = tmp_noise;
1626 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1632 struct iw_handler_def r8180_wx_handlers_def={
1633 .standard = r8180_wx_handlers,
1634 .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
1635 .private = r8180_private_handler,
1636 .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
1637 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1638 #if WIRELESS_EXT >= 17
1639 .get_wireless_stats = r8180_get_wireless_stats,
1641 .private_args = (struct iw_priv_args *)r8180_private_args,