2 This file contains wireless extension handlers.
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
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 thanks the Authors of those projects and the Ndiswrapper
24 #include "ieee80211/dot11d.h"
26 u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
27 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
29 #define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
31 static CHANNEL_LIST DefaultChannelPlan[] = {
32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* FCC */
33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* IC */
34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* ETSI */
35 {{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. */
36 {{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. */
37 {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* MKK */
38 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, /* MKK1 */
39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */
40 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */
41 {{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 */
43 static int r8180_wx_get_freq(struct net_device *dev,
44 struct iw_request_info *a,
45 union iwreq_data *wrqu, char *b)
47 struct r8180_priv *priv = ieee80211_priv(dev);
49 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
53 static int r8180_wx_set_key(struct net_device *dev,
54 struct iw_request_info *info,
55 union iwreq_data *wrqu, char *key)
57 struct r8180_priv *priv = ieee80211_priv(dev);
58 struct iw_point *erq = &(wrqu->encoding);
60 if (priv->ieee80211->bHwRadioOff)
63 if (erq->length > 0) {
64 u32* tkey = (u32*) key;
65 priv->key0[0] = tkey[0];
66 priv->key0[1] = tkey[1];
67 priv->key0[2] = tkey[2];
68 priv->key0[3] = tkey[3] & 0xff;
69 DMESG("Setting wep key to %x %x %x %x",
70 tkey[0], tkey[1], tkey[2], tkey[3]);
71 rtl8180_set_hw_wep(dev);
77 static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
78 union iwreq_data *wrqu, char *b)
80 int *parms = (int *)b;
83 struct r8180_priv *priv = ieee80211_priv(dev);
85 if (priv->ieee80211->bHwRadioOff)
89 DMESG("setting beacon interval to %x", bi);
91 priv->ieee80211->current_network.beacon_interval = bi;
100 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
101 union iwreq_data *wrqu, char *b)
103 struct r8180_priv *priv = ieee80211_priv(dev);
104 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
109 static int r8180_wx_get_rate(struct net_device *dev,
110 struct iw_request_info *info,
111 union iwreq_data *wrqu, char *extra)
113 struct r8180_priv *priv = ieee80211_priv(dev);
114 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
119 static int r8180_wx_set_rate(struct net_device *dev,
120 struct iw_request_info *info,
121 union iwreq_data *wrqu, char *extra)
124 struct r8180_priv *priv = ieee80211_priv(dev);
127 if (priv->ieee80211->bHwRadioOff)
132 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
140 static int r8180_wx_set_crcmon(struct net_device *dev,
141 struct iw_request_info *info,
142 union iwreq_data *wrqu, char *extra)
144 struct r8180_priv *priv = ieee80211_priv(dev);
145 int *parms = (int *)extra;
146 int enable = (parms[0] > 0);
147 short prev = priv->crcmon;
150 if (priv->ieee80211->bHwRadioOff)
160 DMESG("bad CRC in monitor mode are %s",
161 priv->crcmon ? "accepted" : "rejected");
163 if (prev != priv->crcmon && priv->up) {
174 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
175 union iwreq_data *wrqu, char *b)
177 struct r8180_priv *priv = ieee80211_priv(dev);
181 if (priv->ieee80211->bHwRadioOff)
185 if (priv->bInactivePs) {
186 if (wrqu->mode == IW_MODE_ADHOC)
189 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
195 /* YJ,add,080819,for hidden ap */
196 struct iw_range_with_scan_capa {
197 /* Informative stuff (to choose between different interface) */
199 __u32 throughput; /* To give an idea... */
201 /* In theory this value should be the maximum benchmarked
202 * TCP/IP throughput, because with most of these devices the
203 * bit rate is meaningless (overhead an co) to estimate how
204 * fast the connection will go and pick the fastest one.
205 * I suggest people to play with Netperf or any benchmark...
208 /* NWID (or domain id) */
209 __u32 min_nwid; /* Minimal NWID we are able to set */
210 __u32 max_nwid; /* Maximal NWID we are able to set */
212 /* Old Frequency (backward compat - moved lower ) */
213 __u16 old_num_channels;
214 __u8 old_num_frequency;
216 /* Scan capabilities */
219 /* YJ,add,080819,for hidden ap */
222 static int rtl8180_wx_get_range(struct net_device *dev,
223 struct iw_request_info *info,
224 union iwreq_data *wrqu, char *extra)
226 struct iw_range *range = (struct iw_range *)extra;
227 struct r8180_priv *priv = ieee80211_priv(dev);
231 wrqu->data.length = sizeof(*range);
232 memset(range, 0, sizeof(*range));
234 /* Let's try to keep this struct in the same order as in
235 * linux/include/wireless.h
238 /* TODO: See what values we can set, and remove the ones we can't
239 * set, or fill them with some default data.
242 /* ~5 Mb/s real (802.11b) */
243 range->throughput = 5 * 1000 * 1000;
245 /* TODO: Not used in 802.11b? */
246 /* range->min_nwid; */ /* Minimal NWID we are able to set */
247 /* TODO: Not used in 802.11b? */
248 /* range->max_nwid; */ /* Maximal NWID we are able to set */
250 /* Old Frequency (backward compat - moved lower ) */
251 /* range->old_num_channels; */
252 /* range->old_num_frequency; */
253 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
254 if (priv->rf_set_sens != NULL)
255 range->sensitivity = priv->max_sens; /* signal level threshold range */
257 range->max_qual.qual = 100;
258 /* TODO: Find real max RSSI and stick here */
259 range->max_qual.level = 0;
260 range->max_qual.noise = -98;
261 range->max_qual.updated = 7; /* Updated all three */
263 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
264 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
265 range->avg_qual.level = 20 + -98;
266 range->avg_qual.noise = 0;
267 range->avg_qual.updated = 7; /* Updated all three */
269 range->num_bitrates = RATE_COUNT;
271 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
272 range->bitrate[i] = rtl8180_rates[i];
274 range->min_frag = MIN_FRAG_THRESHOLD;
275 range->max_frag = MAX_FRAG_THRESHOLD;
279 range->we_version_compiled = WIRELESS_EXT;
280 range->we_version_source = 16;
282 range->num_channels = 14;
284 for (i = 0, val = 0; i < 14; i++) {
286 /* Include only legal frequencies for some countries */
287 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
288 range->freq[val].i = i + 1;
289 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
290 range->freq[val].e = 1;
293 /* FIXME: do we need to set anything for channels */
297 if (val == IW_MAX_FREQUENCIES)
301 range->num_frequency = val;
302 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
303 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
309 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
310 union iwreq_data *wrqu, char *b)
312 struct r8180_priv *priv = ieee80211_priv(dev);
314 struct ieee80211_device* ieee = priv->ieee80211;
317 if (priv->ieee80211->bHwRadioOff)
320 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
321 struct iw_scan_req* req = (struct iw_scan_req*)b;
322 if (req->essid_len) {
323 ieee->current_network.ssid_len = req->essid_len;
324 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
330 priv->ieee80211->actscanning = true;
331 if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) {
333 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
336 /* prevent scan in BusyTraffic */
337 /* FIXME: Need to consider last scan time */
338 if ((priv->link_detect.bBusyTraffic) && (true)) {
340 printk("Now traffic is busy, please try later!\n");
342 /* prevent scan in BusyTraffic,end */
343 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
354 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
355 union iwreq_data *wrqu, char *b)
359 struct r8180_priv *priv = ieee80211_priv(dev);
363 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
372 static int r8180_wx_set_essid(struct net_device *dev,
373 struct iw_request_info *a,
374 union iwreq_data *wrqu, char *b)
376 struct r8180_priv *priv = ieee80211_priv(dev);
380 if (priv->ieee80211->bHwRadioOff)
384 if (priv->bInactivePs)
387 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
394 static int r8180_wx_get_essid(struct net_device *dev,
395 struct iw_request_info *a,
396 union iwreq_data *wrqu, char *b)
399 struct r8180_priv *priv = ieee80211_priv(dev);
403 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
411 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
412 union iwreq_data *wrqu, char *b)
415 struct r8180_priv *priv = ieee80211_priv(dev);
418 if (priv->ieee80211->bHwRadioOff)
423 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
430 static int r8180_wx_get_name(struct net_device *dev,
431 struct iw_request_info *info,
432 union iwreq_data *wrqu, char *extra)
434 struct r8180_priv *priv = ieee80211_priv(dev);
435 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
438 static int r8180_wx_set_frag(struct net_device *dev,
439 struct iw_request_info *info,
440 union iwreq_data *wrqu, char *extra)
442 struct r8180_priv *priv = ieee80211_priv(dev);
444 if (priv->ieee80211->bHwRadioOff)
447 if (wrqu->frag.disabled)
448 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
450 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
451 wrqu->frag.value > MAX_FRAG_THRESHOLD)
454 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
461 static int r8180_wx_get_frag(struct net_device *dev,
462 struct iw_request_info *info,
463 union iwreq_data *wrqu, char *extra)
465 struct r8180_priv *priv = ieee80211_priv(dev);
467 wrqu->frag.value = priv->ieee80211->fts;
468 wrqu->frag.fixed = 0; /* no auto select */
469 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
475 static int r8180_wx_set_wap(struct net_device *dev,
476 struct iw_request_info *info,
477 union iwreq_data *awrq,
481 struct r8180_priv *priv = ieee80211_priv(dev);
483 if (priv->ieee80211->bHwRadioOff)
488 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
496 static int r8180_wx_get_wap(struct net_device *dev,
497 struct iw_request_info *info,
498 union iwreq_data *wrqu, char *extra)
500 struct r8180_priv *priv = ieee80211_priv(dev);
502 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
506 static int r8180_wx_set_enc(struct net_device *dev,
507 struct iw_request_info *info,
508 union iwreq_data *wrqu, char *key)
510 struct r8180_priv *priv = ieee80211_priv(dev);
513 if (priv->ieee80211->bHwRadioOff)
519 if (priv->hw_wep) ret = r8180_wx_set_key(dev, info, wrqu, key);
521 DMESG("Setting SW wep key");
522 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
530 static int r8180_wx_get_enc(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *key)
534 struct r8180_priv *priv = ieee80211_priv(dev);
536 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
540 static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
541 iwreq_data *wrqu, char *p) {
543 struct r8180_priv *priv = ieee80211_priv(dev);
544 int *parms = (int*)p;
547 if (priv->ieee80211->bHwRadioOff)
550 priv->ieee80211->active_scan = mode;
555 static int r8180_wx_set_retry(struct net_device *dev,
556 struct iw_request_info *info,
557 union iwreq_data *wrqu, char *extra)
559 struct r8180_priv *priv = ieee80211_priv(dev);
562 if (priv->ieee80211->bHwRadioOff)
567 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
568 wrqu->retry.disabled) {
572 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
577 if (wrqu->retry.value > R8180_MAX_RETRY) {
581 if (wrqu->retry.flags & IW_RETRY_MAX) {
582 priv->retry_rts = wrqu->retry.value;
583 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
586 priv->retry_data = wrqu->retry.value;
587 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
591 * We might try to write directly the TX config register
592 * or to restart just the (R)TX process.
593 * I'm unsure if whole reset is really needed
603 static int r8180_wx_get_retry(struct net_device *dev,
604 struct iw_request_info *info,
605 union iwreq_data *wrqu, char *extra)
607 struct r8180_priv *priv = ieee80211_priv(dev);
610 wrqu->retry.disabled = 0; /* can't be disabled */
612 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
616 if (wrqu->retry.flags & IW_RETRY_MAX) {
617 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
618 wrqu->retry.value = priv->retry_rts;
620 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
621 wrqu->retry.value = priv->retry_data;
627 static int r8180_wx_get_sens(struct net_device *dev,
628 struct iw_request_info *info,
629 union iwreq_data *wrqu, char *extra)
631 struct r8180_priv *priv = ieee80211_priv(dev);
632 if (priv->rf_set_sens == NULL)
633 return -1; /* we have not this support for this radio */
634 wrqu->sens.value = priv->sens;
639 static int r8180_wx_set_sens(struct net_device *dev,
640 struct iw_request_info *info,
641 union iwreq_data *wrqu, char *extra)
644 struct r8180_priv *priv = ieee80211_priv(dev);
648 if (priv->ieee80211->bHwRadioOff)
652 if (priv->rf_set_sens == NULL) {
653 err = -1; /* we have not this support for this radio */
656 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
657 priv->sens = wrqu->sens.value;
668 static int r8180_wx_set_rawtx(struct net_device *dev,
669 struct iw_request_info *info,
670 union iwreq_data *wrqu, char *extra)
672 struct r8180_priv *priv = ieee80211_priv(dev);
675 if (priv->ieee80211->bHwRadioOff)
680 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
688 static int r8180_wx_get_power(struct net_device *dev,
689 struct iw_request_info *info,
690 union iwreq_data *wrqu, char *extra)
693 struct r8180_priv *priv = ieee80211_priv(dev);
697 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
704 static int r8180_wx_set_power(struct net_device *dev,
705 struct iw_request_info *info,
706 union iwreq_data *wrqu, char *extra)
709 struct r8180_priv *priv = ieee80211_priv(dev);
712 if (priv->ieee80211->bHwRadioOff)
716 printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
717 if (wrqu->power.disabled == 0) {
718 wrqu->power.flags |= IW_POWER_ALL_R;
719 wrqu->power.flags |= IW_POWER_TIMEOUT;
720 wrqu->power.value = 1000;
723 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
730 static int r8180_wx_set_rts(struct net_device *dev,
731 struct iw_request_info *info,
732 union iwreq_data *wrqu, char *extra)
734 struct r8180_priv *priv = ieee80211_priv(dev);
737 if (priv->ieee80211->bHwRadioOff)
740 if (wrqu->rts.disabled)
741 priv->rts = DEFAULT_RTS_THRESHOLD;
743 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
744 wrqu->rts.value > MAX_RTS_THRESHOLD)
747 priv->rts = wrqu->rts.value;
752 static int r8180_wx_get_rts(struct net_device *dev,
753 struct iw_request_info *info,
754 union iwreq_data *wrqu, char *extra)
756 struct r8180_priv *priv = ieee80211_priv(dev);
760 wrqu->rts.value = priv->rts;
761 wrqu->rts.fixed = 0; /* no auto select */
762 wrqu->rts.disabled = (wrqu->rts.value == 0);
766 static int dummy(struct net_device *dev, struct iw_request_info *a,
767 union iwreq_data *wrqu, char *b)
772 static int r8180_wx_get_iwmode(struct net_device *dev,
773 struct iw_request_info *info,
774 union iwreq_data *wrqu, char *extra)
776 struct r8180_priv *priv = ieee80211_priv(dev);
777 struct ieee80211_device *ieee;
784 ieee = priv->ieee80211;
786 strcpy(extra, "802.11");
787 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
789 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
791 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
798 static int r8180_wx_set_iwmode(struct net_device *dev,
799 struct iw_request_info *info,
800 union iwreq_data *wrqu, char *extra)
802 struct r8180_priv *priv = ieee80211_priv(dev);
803 struct ieee80211_device *ieee = priv->ieee80211;
804 int *param = (int *)extra;
806 int modulation = 0, mode = 0;
809 if (priv->ieee80211->bHwRadioOff)
815 modulation |= IEEE80211_CCK_MODULATION;
817 printk(KERN_INFO "B mode!\n");
818 } else if (*param == 2) {
819 modulation |= IEEE80211_OFDM_MODULATION;
821 printk(KERN_INFO "G mode!\n");
822 } else if (*param == 3) {
823 modulation |= IEEE80211_CCK_MODULATION;
824 modulation |= IEEE80211_OFDM_MODULATION;
825 mode = IEEE_B|IEEE_G;
826 printk(KERN_INFO "B/G mode!\n");
829 if (ieee->proto_started) {
830 ieee80211_stop_protocol(ieee);
832 ieee->modulation = modulation;
833 ieee80211_start_protocol(ieee);
836 ieee->modulation = modulation;
843 static int r8180_wx_get_preamble(struct net_device *dev,
844 struct iw_request_info *info,
845 union iwreq_data *wrqu, char *extra)
847 struct r8180_priv *priv = ieee80211_priv(dev);
855 *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
860 static int r8180_wx_set_preamble(struct net_device *dev,
861 struct iw_request_info *info,
862 union iwreq_data *wrqu, char *extra)
864 struct r8180_priv *priv = ieee80211_priv(dev);
868 if (priv->ieee80211->bHwRadioOff)
872 if (*extra < 0 || *extra > 2)
875 priv->plcp_preamble_mode = *((short *)extra) ;
883 static int r8180_wx_get_siglevel(struct net_device *dev,
884 struct iw_request_info *info,
885 union iwreq_data *wrqu, char *extra)
887 struct r8180_priv *priv = ieee80211_priv(dev);
893 /* Modify by hikaru 6.5 */
894 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
902 static int r8180_wx_get_sigqual(struct net_device *dev,
903 struct iw_request_info *info,
904 union iwreq_data *wrqu, char *extra)
906 struct r8180_priv *priv = ieee80211_priv(dev);
912 /* Modify by hikaru 6.5 */
913 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
921 static int r8180_wx_reset_stats(struct net_device *dev,
922 struct iw_request_info *info,
923 union iwreq_data *wrqu, char *extra)
925 struct r8180_priv *priv = ieee80211_priv(dev);
928 priv->stats.txrdu = 0;
929 priv->stats.rxrdu = 0;
930 priv->stats.rxnolast = 0;
931 priv->stats.rxnodata = 0;
932 priv->stats.rxnopointer = 0;
933 priv->stats.txnperr = 0;
934 priv->stats.txresumed = 0;
935 priv->stats.rxerr = 0;
936 priv->stats.rxoverflow = 0;
937 priv->stats.rxint = 0;
939 priv->stats.txnpokint = 0;
940 priv->stats.txhpokint = 0;
941 priv->stats.txhperr = 0;
942 priv->stats.ints = 0;
943 priv->stats.shints = 0;
944 priv->stats.txoverflow = 0;
945 priv->stats.rxdmafail = 0;
946 priv->stats.txbeacon = 0;
947 priv->stats.txbeaconerr = 0;
948 priv->stats.txlpokint = 0;
949 priv->stats.txlperr = 0;
950 priv->stats.txretry = 0;/* 20060601 */
951 priv->stats.rxcrcerrmin = 0 ;
952 priv->stats.rxcrcerrmid = 0;
953 priv->stats.rxcrcerrmax = 0;
954 priv->stats.rxicverr = 0;
961 static int r8180_wx_radio_on(struct net_device *dev,
962 struct iw_request_info *info,
963 union iwreq_data *wrqu, char *extra)
965 struct r8180_priv *priv = ieee80211_priv(dev);
967 if (priv->ieee80211->bHwRadioOff)
972 priv->rf_wakeup(dev);
980 static int r8180_wx_radio_off(struct net_device *dev,
981 struct iw_request_info *info,
982 union iwreq_data *wrqu, char *extra)
984 struct r8180_priv *priv = ieee80211_priv(dev);
986 if (priv->ieee80211->bHwRadioOff)
998 static int r8180_wx_get_channelplan(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);
1007 *extra = priv->channel_plan;
1015 static int r8180_wx_set_channelplan(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);
1020 int *val = (int *)extra;
1022 printk("-----in fun %s\n", __func__);
1024 if (priv->ieee80211->bHwRadioOff)
1027 /* unsigned long flags; */
1028 down(&priv->wx_sem);
1029 if (DefaultChannelPlan[*val].Len != 0) {
1030 priv->channel_plan = *val;
1031 /* Clear old channel map 8 */
1032 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1033 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1035 /* Set new channel map */
1036 for (i = 1; i <= DefaultChannelPlan[*val].Len; i++)
1037 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1045 static int r8180_wx_get_version(struct net_device *dev,
1046 struct iw_request_info *info,
1047 union iwreq_data *wrqu, char *extra)
1049 struct r8180_priv *priv = ieee80211_priv(dev);
1050 /* struct ieee80211_device *ieee; */
1052 down(&priv->wx_sem);
1053 strcpy(extra, "1020.0808");
1059 /* added by amy 080818 */
1060 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1061 static int r8180_wx_set_forcerate(struct net_device *dev,
1062 struct iw_request_info *info,
1063 union iwreq_data *wrqu, char *extra)
1065 struct r8180_priv *priv = ieee80211_priv(dev);
1066 u8 forcerate = *extra;
1068 down(&priv->wx_sem);
1070 printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1071 if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1072 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1073 (forcerate == 96) || (forcerate == 108))
1075 priv->ForcedDataRate = 1;
1076 priv->ieee80211->rate = forcerate * 5;
1077 } else if (forcerate == 0) {
1078 priv->ForcedDataRate = 0;
1079 printk("OK! return rate adaptive\n");
1081 printk("ERR: wrong rate\n");
1086 static int r8180_wx_set_enc_ext(struct net_device *dev,
1087 struct iw_request_info *info,
1088 union iwreq_data *wrqu, char *extra)
1091 struct r8180_priv *priv = ieee80211_priv(dev);
1095 if (priv->ieee80211->bHwRadioOff)
1098 down(&priv->wx_sem);
1099 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1104 static int r8180_wx_set_auth(struct net_device *dev,
1105 struct iw_request_info *info,
1106 union iwreq_data *wrqu, char *extra)
1108 struct r8180_priv *priv = ieee80211_priv(dev);
1111 if (priv->ieee80211->bHwRadioOff)
1114 down(&priv->wx_sem);
1115 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1120 static int r8180_wx_set_mlme(struct net_device *dev,
1121 struct iw_request_info *info,
1122 union iwreq_data *wrqu, char *extra)
1125 struct r8180_priv *priv = ieee80211_priv(dev);
1128 if (priv->ieee80211->bHwRadioOff)
1132 down(&priv->wx_sem);
1134 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1139 static int r8180_wx_set_gen_ie(struct net_device *dev,
1140 struct iw_request_info *info,
1141 union iwreq_data *wrqu, char *extra)
1144 struct r8180_priv *priv = ieee80211_priv(dev);
1147 if (priv->ieee80211->bHwRadioOff)
1150 down(&priv->wx_sem);
1152 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1159 static iw_handler r8180_wx_handlers[] = {
1160 NULL, /* SIOCSIWCOMMIT */
1161 r8180_wx_get_name, /* SIOCGIWNAME */
1162 dummy, /* SIOCSIWNWID */
1163 dummy, /* SIOCGIWNWID */
1164 r8180_wx_set_freq, /* SIOCSIWFREQ */
1165 r8180_wx_get_freq, /* SIOCGIWFREQ */
1166 r8180_wx_set_mode, /* SIOCSIWMODE */
1167 r8180_wx_get_mode, /* SIOCGIWMODE */
1168 r8180_wx_set_sens, /* SIOCSIWSENS */
1169 r8180_wx_get_sens, /* SIOCGIWSENS */
1170 NULL, /* SIOCSIWRANGE */
1171 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1172 NULL, /* SIOCSIWPRIV */
1173 NULL, /* SIOCGIWPRIV */
1174 NULL, /* SIOCSIWSTATS */
1175 NULL, /* SIOCGIWSTATS */
1176 dummy, /* SIOCSIWSPY */
1177 dummy, /* SIOCGIWSPY */
1178 NULL, /* SIOCGIWTHRSPY */
1179 NULL, /* SIOCWIWTHRSPY */
1180 r8180_wx_set_wap, /* SIOCSIWAP */
1181 r8180_wx_get_wap, /* SIOCGIWAP */
1182 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1183 dummy, /* SIOCGIWAPLIST -- deprecated */
1184 r8180_wx_set_scan, /* SIOCSIWSCAN */
1185 r8180_wx_get_scan, /* SIOCGIWSCAN */
1186 r8180_wx_set_essid, /* SIOCSIWESSID */
1187 r8180_wx_get_essid, /* SIOCGIWESSID */
1188 dummy, /* SIOCSIWNICKN */
1189 dummy, /* SIOCGIWNICKN */
1190 NULL, /* -- hole -- */
1191 NULL, /* -- hole -- */
1192 r8180_wx_set_rate, /* SIOCSIWRATE */
1193 r8180_wx_get_rate, /* SIOCGIWRATE */
1194 r8180_wx_set_rts, /* SIOCSIWRTS */
1195 r8180_wx_get_rts, /* SIOCGIWRTS */
1196 r8180_wx_set_frag, /* SIOCSIWFRAG */
1197 r8180_wx_get_frag, /* SIOCGIWFRAG */
1198 dummy, /* SIOCSIWTXPOW */
1199 dummy, /* SIOCGIWTXPOW */
1200 r8180_wx_set_retry, /* SIOCSIWRETRY */
1201 r8180_wx_get_retry, /* SIOCGIWRETRY */
1202 r8180_wx_set_enc, /* SIOCSIWENCODE */
1203 r8180_wx_get_enc, /* SIOCGIWENCODE */
1204 r8180_wx_set_power, /* SIOCSIWPOWER */
1205 r8180_wx_get_power, /* SIOCGIWPOWER */
1206 NULL, /*---hole---*/
1207 NULL, /*---hole---*/
1208 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1209 NULL, /* SIOCSIWGENIE */
1210 r8180_wx_set_auth, /* SIOCSIWAUTH */
1211 NULL, /* SIOCSIWAUTH */
1212 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1213 NULL, /* SIOCSIWENCODEEXT */
1214 NULL, /* SIOCSIWPMKSA */
1215 NULL, /*---hole---*/
1219 static const struct iw_priv_args r8180_private_args[] = {
1221 SIOCIWFIRSTPRIV + 0x0,
1222 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1224 { SIOCIWFIRSTPRIV + 0x1,
1229 SIOCIWFIRSTPRIV + 0x2,
1230 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1232 { SIOCIWFIRSTPRIV + 0x3,
1237 SIOCIWFIRSTPRIV + 0x4,
1238 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1241 { SIOCIWFIRSTPRIV + 0x5,
1246 SIOCIWFIRSTPRIV + 0x6,
1247 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1250 { SIOCIWFIRSTPRIV + 0x7,
1255 SIOCIWFIRSTPRIV + 0x8,
1256 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1259 SIOCIWFIRSTPRIV + 0x9,
1260 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1263 SIOCIWFIRSTPRIV + 0xA,
1264 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1267 SIOCIWFIRSTPRIV + 0xB,
1268 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1270 { SIOCIWFIRSTPRIV + 0xC,
1274 SIOCIWFIRSTPRIV + 0xD,
1275 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1277 { SIOCIWFIRSTPRIV + 0xE,
1281 SIOCIWFIRSTPRIV + 0xF,
1282 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1285 SIOCIWFIRSTPRIV + 0x10,
1289 SIOCIWFIRSTPRIV + 0x11,
1293 SIOCIWFIRSTPRIV + 0x12,
1297 SIOCIWFIRSTPRIV + 0x13,
1301 SIOCIWFIRSTPRIV + 0x14,
1302 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1305 SIOCIWFIRSTPRIV + 0x15,
1306 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1309 SIOCIWFIRSTPRIV + 0x16,
1313 SIOCIWFIRSTPRIV + 0x17,
1314 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1317 SIOCIWFIRSTPRIV + 0x18,
1318 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1323 static iw_handler r8180_private_handler[] = {
1324 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1326 r8180_wx_set_beaconinterval,
1328 /* r8180_wx_set_monitor_type, */
1329 r8180_wx_set_scan_type,
1333 r8180_wx_set_iwmode,
1334 r8180_wx_get_iwmode,
1335 r8180_wx_set_preamble,
1336 r8180_wx_get_preamble,
1338 r8180_wx_get_siglevel,
1340 r8180_wx_get_sigqual,
1341 r8180_wx_reset_stats,
1342 dummy,/* r8180_wx_get_stats */
1345 r8180_wx_set_channelplan,
1346 r8180_wx_get_channelplan,
1348 r8180_wx_get_version,
1349 r8180_wx_set_forcerate,
1352 static inline int is_same_network(struct ieee80211_network *src,
1353 struct ieee80211_network *dst,
1354 struct ieee80211_device *ieee)
1356 /* A network is only a duplicate if the channel, BSSID, ESSID
1357 * and the capability field (in particular IBSS and BSS) all match.
1358 * We treat all <hidden> with the same BSSID and channel
1361 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1362 (src->channel == dst->channel) &&
1363 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1364 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1365 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1366 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1367 ((src->capability & WLAN_CAPABILITY_BSS) ==
1368 (dst->capability & WLAN_CAPABILITY_BSS)));
1371 /* WB modified to show signal to GUI on 18-01-2008 */
1372 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1374 struct r8180_priv *priv = ieee80211_priv(dev);
1375 struct ieee80211_device* ieee = priv->ieee80211;
1376 struct iw_statistics* wstats = &priv->wstats;
1381 if (ieee->state < IEEE80211_LINKED) {
1382 wstats->qual.qual = 0;
1383 wstats->qual.level = 0;
1384 wstats->qual.noise = 0;
1385 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1389 tmp_level = (&ieee->current_network)->stats.signal;
1390 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1391 tmp_noise = (&ieee->current_network)->stats.noise;
1393 wstats->qual.level = tmp_level;
1394 wstats->qual.qual = tmp_qual;
1395 wstats->qual.noise = tmp_noise;
1396 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1400 struct iw_handler_def r8180_wx_handlers_def = {
1401 .standard = r8180_wx_handlers,
1402 .num_standard = ARRAY_SIZE(r8180_wx_handlers),
1403 .private = r8180_private_handler,
1404 .num_private = ARRAY_SIZE(r8180_private_handler),
1405 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1406 .get_wireless_stats = r8180_get_wireless_stats,
1407 .private_args = (struct iw_priv_args *)r8180_private_args,