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 <net/iw_handler.h>
25 #include "ieee80211/dot11d.h"
27 u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
28 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
30 #define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
32 static CHANNEL_LIST DefaultChannelPlan[] = {
33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* FCC */
34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* IC */
35 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* ETSI */
36 {{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. */
37 {{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. */
38 {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* MKK */
39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, /* MKK1 */
40 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */
41 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */
42 {{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 */
44 static int r8180_wx_get_freq(struct net_device *dev,
45 struct iw_request_info *a,
46 union iwreq_data *wrqu, char *b)
48 struct r8180_priv *priv = ieee80211_priv(dev);
50 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
54 static int r8180_wx_set_key(struct net_device *dev,
55 struct iw_request_info *info,
56 union iwreq_data *wrqu, char *key)
58 struct r8180_priv *priv = ieee80211_priv(dev);
59 struct iw_point *erq = &(wrqu->encoding);
61 if (priv->ieee80211->bHwRadioOff)
64 if (erq->length > 0) {
65 u32* tkey = (u32*) key;
66 priv->key0[0] = tkey[0];
67 priv->key0[1] = tkey[1];
68 priv->key0[2] = tkey[2];
69 priv->key0[3] = tkey[3] & 0xff;
70 DMESG("Setting wep key to %x %x %x %x",
71 tkey[0], tkey[1], tkey[2], tkey[3]);
72 rtl8180_set_hw_wep(dev);
78 static int r8180_wx_set_beaconinterval(struct net_device *dev,
79 struct iw_request_info *aa,
80 union iwreq_data *wrqu, char *b)
82 int *parms = (int *)b;
85 struct r8180_priv *priv = ieee80211_priv(dev);
87 if (priv->ieee80211->bHwRadioOff)
91 DMESG("setting beacon interval to %x", bi);
93 priv->ieee80211->current_network.beacon_interval = bi;
102 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
103 union iwreq_data *wrqu, char *b)
105 struct r8180_priv *priv = ieee80211_priv(dev);
106 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
111 static int r8180_wx_get_rate(struct net_device *dev,
112 struct iw_request_info *info,
113 union iwreq_data *wrqu, char *extra)
115 struct r8180_priv *priv = ieee80211_priv(dev);
116 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
121 static int r8180_wx_set_rate(struct net_device *dev,
122 struct iw_request_info *info,
123 union iwreq_data *wrqu, char *extra)
126 struct r8180_priv *priv = ieee80211_priv(dev);
129 if (priv->ieee80211->bHwRadioOff)
134 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
142 static int r8180_wx_set_crcmon(struct net_device *dev,
143 struct iw_request_info *info,
144 union iwreq_data *wrqu, char *extra)
146 struct r8180_priv *priv = ieee80211_priv(dev);
147 int *parms = (int *)extra;
148 int enable = (parms[0] > 0);
149 short prev = priv->crcmon;
152 if (priv->ieee80211->bHwRadioOff)
162 DMESG("bad CRC in monitor mode are %s",
163 priv->crcmon ? "accepted" : "rejected");
165 if (prev != priv->crcmon && priv->up) {
176 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
177 union iwreq_data *wrqu, char *b)
179 struct r8180_priv *priv = ieee80211_priv(dev);
183 if (priv->ieee80211->bHwRadioOff)
187 if (priv->bInactivePs) {
188 if (wrqu->mode == IW_MODE_ADHOC)
191 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
197 /* YJ,add,080819,for hidden ap */
198 struct iw_range_with_scan_capa {
199 /* Informative stuff (to choose between different interface) */
201 __u32 throughput; /* To give an idea... */
203 /* In theory this value should be the maximum benchmarked
204 * TCP/IP throughput, because with most of these devices the
205 * bit rate is meaningless (overhead an co) to estimate how
206 * fast the connection will go and pick the fastest one.
207 * I suggest people to play with Netperf or any benchmark...
210 /* NWID (or domain id) */
211 __u32 min_nwid; /* Minimal NWID we are able to set */
212 __u32 max_nwid; /* Maximal NWID we are able to set */
214 /* Old Frequency (backward compat - moved lower ) */
215 __u16 old_num_channels;
216 __u8 old_num_frequency;
218 /* Scan capabilities */
221 /* YJ,add,080819,for hidden ap */
224 static int rtl8180_wx_get_range(struct net_device *dev,
225 struct iw_request_info *info,
226 union iwreq_data *wrqu, char *extra)
228 struct iw_range *range = (struct iw_range *)extra;
229 struct r8180_priv *priv = ieee80211_priv(dev);
233 wrqu->data.length = sizeof(*range);
234 memset(range, 0, sizeof(*range));
236 /* Let's try to keep this struct in the same order as in
237 * linux/include/wireless.h
240 /* TODO: See what values we can set, and remove the ones we can't
241 * set, or fill them with some default data.
244 /* ~5 Mb/s real (802.11b) */
245 range->throughput = 5 * 1000 * 1000;
247 /* TODO: Not used in 802.11b? */
248 /* range->min_nwid; */ /* Minimal NWID we are able to set */
249 /* TODO: Not used in 802.11b? */
250 /* range->max_nwid; */ /* Maximal NWID we are able to set */
252 /* Old Frequency (backward compat - moved lower ) */
253 /* range->old_num_channels; */
254 /* range->old_num_frequency; */
255 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
256 if (priv->rf_set_sens != NULL)
257 range->sensitivity = priv->max_sens; /* signal level threshold range */
259 range->max_qual.qual = 100;
260 /* TODO: Find real max RSSI and stick here */
261 range->max_qual.level = 0;
262 range->max_qual.noise = -98;
263 range->max_qual.updated = 7; /* Updated all three */
265 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
266 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
267 range->avg_qual.level = 20 + -98;
268 range->avg_qual.noise = 0;
269 range->avg_qual.updated = 7; /* Updated all three */
271 range->num_bitrates = RATE_COUNT;
273 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
274 range->bitrate[i] = rtl8180_rates[i];
276 range->min_frag = MIN_FRAG_THRESHOLD;
277 range->max_frag = MAX_FRAG_THRESHOLD;
281 range->we_version_compiled = WIRELESS_EXT;
282 range->we_version_source = 16;
284 range->num_channels = 14;
286 for (i = 0, val = 0; i < 14; i++) {
288 /* Include only legal frequencies for some countries */
289 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
290 range->freq[val].i = i + 1;
291 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
292 range->freq[val].e = 1;
295 /* FIXME: do we need to set anything for channels */
299 if (val == IW_MAX_FREQUENCIES)
303 range->num_frequency = val;
304 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
305 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
311 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
312 union iwreq_data *wrqu, char *b)
314 struct r8180_priv *priv = ieee80211_priv(dev);
316 struct ieee80211_device* ieee = priv->ieee80211;
319 if (priv->ieee80211->bHwRadioOff)
322 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
323 struct iw_scan_req* req = (struct iw_scan_req*)b;
324 if (req->essid_len) {
325 ieee->current_network.ssid_len = req->essid_len;
326 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
332 priv->ieee80211->actscanning = true;
333 if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) {
335 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
338 /* prevent scan in BusyTraffic */
339 /* FIXME: Need to consider last scan time */
340 if ((priv->link_detect.bBusyTraffic) && (true)) {
342 printk("Now traffic is busy, please try later!\n");
344 /* prevent scan in BusyTraffic,end */
345 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
356 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
357 union iwreq_data *wrqu, char *b)
361 struct r8180_priv *priv = ieee80211_priv(dev);
365 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
374 static int r8180_wx_set_essid(struct net_device *dev,
375 struct iw_request_info *a,
376 union iwreq_data *wrqu, char *b)
378 struct r8180_priv *priv = ieee80211_priv(dev);
382 if (priv->ieee80211->bHwRadioOff)
386 if (priv->bInactivePs)
389 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
396 static int r8180_wx_get_essid(struct net_device *dev,
397 struct iw_request_info *a,
398 union iwreq_data *wrqu, char *b)
401 struct r8180_priv *priv = ieee80211_priv(dev);
405 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
413 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
414 union iwreq_data *wrqu, char *b)
417 struct r8180_priv *priv = ieee80211_priv(dev);
420 if (priv->ieee80211->bHwRadioOff)
425 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
432 static int r8180_wx_get_name(struct net_device *dev,
433 struct iw_request_info *info,
434 union iwreq_data *wrqu, char *extra)
436 struct r8180_priv *priv = ieee80211_priv(dev);
437 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
440 static int r8180_wx_set_frag(struct net_device *dev,
441 struct iw_request_info *info,
442 union iwreq_data *wrqu, char *extra)
444 struct r8180_priv *priv = ieee80211_priv(dev);
446 if (priv->ieee80211->bHwRadioOff)
449 if (wrqu->frag.disabled)
450 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
452 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
453 wrqu->frag.value > MAX_FRAG_THRESHOLD)
456 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
463 static int r8180_wx_get_frag(struct net_device *dev,
464 struct iw_request_info *info,
465 union iwreq_data *wrqu, char *extra)
467 struct r8180_priv *priv = ieee80211_priv(dev);
469 wrqu->frag.value = priv->ieee80211->fts;
470 wrqu->frag.fixed = 0; /* no auto select */
471 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
477 static int r8180_wx_set_wap(struct net_device *dev,
478 struct iw_request_info *info,
479 union iwreq_data *awrq, char *extra)
482 struct r8180_priv *priv = ieee80211_priv(dev);
484 if (priv->ieee80211->bHwRadioOff)
489 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
497 static int r8180_wx_get_wap(struct net_device *dev,
498 struct iw_request_info *info,
499 union iwreq_data *wrqu, char *extra)
501 struct r8180_priv *priv = ieee80211_priv(dev);
503 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
507 static int r8180_wx_set_enc(struct net_device *dev,
508 struct iw_request_info *info,
509 union iwreq_data *wrqu, char *key)
511 struct r8180_priv *priv = ieee80211_priv(dev);
514 if (priv->ieee80211->bHwRadioOff)
520 if (priv->hw_wep) ret = r8180_wx_set_key(dev, info, wrqu, key);
522 DMESG("Setting SW wep key");
523 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
531 static int r8180_wx_get_enc(struct net_device *dev,
532 struct iw_request_info *info,
533 union iwreq_data *wrqu, char *key)
535 struct r8180_priv *priv = ieee80211_priv(dev);
537 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
541 static int r8180_wx_set_scan_type(struct net_device *dev,
542 struct iw_request_info *aa,
543 union iwreq_data *wrqu, char *p)
546 struct r8180_priv *priv = ieee80211_priv(dev);
547 int *parms = (int*)p;
550 if (priv->ieee80211->bHwRadioOff)
553 priv->ieee80211->active_scan = mode;
558 static int r8180_wx_set_retry(struct net_device *dev,
559 struct iw_request_info *info,
560 union iwreq_data *wrqu, char *extra)
562 struct r8180_priv *priv = ieee80211_priv(dev);
565 if (priv->ieee80211->bHwRadioOff)
570 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
571 wrqu->retry.disabled) {
575 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
580 if (wrqu->retry.value > R8180_MAX_RETRY) {
584 if (wrqu->retry.flags & IW_RETRY_MAX) {
585 priv->retry_rts = wrqu->retry.value;
586 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
589 priv->retry_data = wrqu->retry.value;
590 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
594 * We might try to write directly the TX config register
595 * or to restart just the (R)TX process.
596 * I'm unsure if whole reset is really needed
606 static int r8180_wx_get_retry(struct net_device *dev,
607 struct iw_request_info *info,
608 union iwreq_data *wrqu, char *extra)
610 struct r8180_priv *priv = ieee80211_priv(dev);
613 wrqu->retry.disabled = 0; /* can't be disabled */
615 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
619 if (wrqu->retry.flags & IW_RETRY_MAX) {
620 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
621 wrqu->retry.value = priv->retry_rts;
623 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
624 wrqu->retry.value = priv->retry_data;
630 static int r8180_wx_get_sens(struct net_device *dev,
631 struct iw_request_info *info,
632 union iwreq_data *wrqu, char *extra)
634 struct r8180_priv *priv = ieee80211_priv(dev);
635 if (priv->rf_set_sens == NULL)
636 return -1; /* we have not this support for this radio */
637 wrqu->sens.value = priv->sens;
642 static int r8180_wx_set_sens(struct net_device *dev,
643 struct iw_request_info *info,
644 union iwreq_data *wrqu, char *extra)
647 struct r8180_priv *priv = ieee80211_priv(dev);
651 if (priv->ieee80211->bHwRadioOff)
655 if (priv->rf_set_sens == NULL) {
656 err = -1; /* we have not this support for this radio */
659 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
660 priv->sens = wrqu->sens.value;
671 static int r8180_wx_set_rawtx(struct net_device *dev,
672 struct iw_request_info *info,
673 union iwreq_data *wrqu, char *extra)
675 struct r8180_priv *priv = ieee80211_priv(dev);
678 if (priv->ieee80211->bHwRadioOff)
683 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
691 static int r8180_wx_get_power(struct net_device *dev,
692 struct iw_request_info *info,
693 union iwreq_data *wrqu, char *extra)
696 struct r8180_priv *priv = ieee80211_priv(dev);
700 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
707 static int r8180_wx_set_power(struct net_device *dev,
708 struct iw_request_info *info,
709 union iwreq_data *wrqu, char *extra)
712 struct r8180_priv *priv = ieee80211_priv(dev);
715 if (priv->ieee80211->bHwRadioOff)
719 printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
720 if (wrqu->power.disabled == 0) {
721 wrqu->power.flags |= IW_POWER_ALL_R;
722 wrqu->power.flags |= IW_POWER_TIMEOUT;
723 wrqu->power.value = 1000;
726 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
733 static int r8180_wx_set_rts(struct net_device *dev,
734 struct iw_request_info *info,
735 union iwreq_data *wrqu, char *extra)
737 struct r8180_priv *priv = ieee80211_priv(dev);
740 if (priv->ieee80211->bHwRadioOff)
743 if (wrqu->rts.disabled)
744 priv->rts = DEFAULT_RTS_THRESHOLD;
746 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
747 wrqu->rts.value > MAX_RTS_THRESHOLD)
750 priv->rts = wrqu->rts.value;
755 static int r8180_wx_get_rts(struct net_device *dev,
756 struct iw_request_info *info,
757 union iwreq_data *wrqu, char *extra)
759 struct r8180_priv *priv = ieee80211_priv(dev);
763 wrqu->rts.value = priv->rts;
764 wrqu->rts.fixed = 0; /* no auto select */
765 wrqu->rts.disabled = (wrqu->rts.value == 0);
769 static int dummy(struct net_device *dev, struct iw_request_info *a,
770 union iwreq_data *wrqu, char *b)
775 static int r8180_wx_get_iwmode(struct net_device *dev,
776 struct iw_request_info *info,
777 union iwreq_data *wrqu, char *extra)
779 struct r8180_priv *priv = ieee80211_priv(dev);
780 struct ieee80211_device *ieee;
787 ieee = priv->ieee80211;
789 strcpy(extra, "802.11");
790 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
792 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
794 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
801 static int r8180_wx_set_iwmode(struct net_device *dev,
802 struct iw_request_info *info,
803 union iwreq_data *wrqu, char *extra)
805 struct r8180_priv *priv = ieee80211_priv(dev);
806 struct ieee80211_device *ieee = priv->ieee80211;
807 int *param = (int *)extra;
809 int modulation = 0, mode = 0;
812 if (priv->ieee80211->bHwRadioOff)
818 modulation |= IEEE80211_CCK_MODULATION;
820 printk(KERN_INFO "B mode!\n");
821 } else if (*param == 2) {
822 modulation |= IEEE80211_OFDM_MODULATION;
824 printk(KERN_INFO "G mode!\n");
825 } else if (*param == 3) {
826 modulation |= IEEE80211_CCK_MODULATION;
827 modulation |= IEEE80211_OFDM_MODULATION;
828 mode = IEEE_B|IEEE_G;
829 printk(KERN_INFO "B/G mode!\n");
832 if (ieee->proto_started) {
833 ieee80211_stop_protocol(ieee);
835 ieee->modulation = modulation;
836 ieee80211_start_protocol(ieee);
839 ieee->modulation = modulation;
846 static int r8180_wx_get_preamble(struct net_device *dev,
847 struct iw_request_info *info,
848 union iwreq_data *wrqu, char *extra)
850 struct r8180_priv *priv = ieee80211_priv(dev);
858 *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
863 static int r8180_wx_set_preamble(struct net_device *dev,
864 struct iw_request_info *info,
865 union iwreq_data *wrqu, char *extra)
867 struct r8180_priv *priv = ieee80211_priv(dev);
871 if (priv->ieee80211->bHwRadioOff)
875 if (*extra < 0 || *extra > 2)
878 priv->plcp_preamble_mode = *((short *)extra) ;
886 static int r8180_wx_get_siglevel(struct net_device *dev,
887 struct iw_request_info *info,
888 union iwreq_data *wrqu, char *extra)
890 struct r8180_priv *priv = ieee80211_priv(dev);
896 /* Modify by hikaru 6.5 */
897 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
905 static int r8180_wx_get_sigqual(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);
915 /* Modify by hikaru 6.5 */
916 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
924 static int r8180_wx_reset_stats(struct net_device *dev,
925 struct iw_request_info *info,
926 union iwreq_data *wrqu, char *extra)
928 struct r8180_priv *priv = ieee80211_priv(dev);
931 priv->stats.txrdu = 0;
932 priv->stats.rxrdu = 0;
933 priv->stats.rxnolast = 0;
934 priv->stats.rxnodata = 0;
935 priv->stats.rxnopointer = 0;
936 priv->stats.txnperr = 0;
937 priv->stats.txresumed = 0;
938 priv->stats.rxerr = 0;
939 priv->stats.rxoverflow = 0;
940 priv->stats.rxint = 0;
942 priv->stats.txnpokint = 0;
943 priv->stats.txhpokint = 0;
944 priv->stats.txhperr = 0;
945 priv->stats.ints = 0;
946 priv->stats.shints = 0;
947 priv->stats.txoverflow = 0;
948 priv->stats.rxdmafail = 0;
949 priv->stats.txbeacon = 0;
950 priv->stats.txbeaconerr = 0;
951 priv->stats.txlpokint = 0;
952 priv->stats.txlperr = 0;
953 priv->stats.txretry = 0;/* 20060601 */
954 priv->stats.rxcrcerrmin = 0 ;
955 priv->stats.rxcrcerrmid = 0;
956 priv->stats.rxcrcerrmax = 0;
957 priv->stats.rxicverr = 0;
964 static int r8180_wx_radio_on(struct net_device *dev,
965 struct iw_request_info *info,
966 union iwreq_data *wrqu, char *extra)
968 struct r8180_priv *priv = ieee80211_priv(dev);
970 if (priv->ieee80211->bHwRadioOff)
975 priv->rf_wakeup(dev);
983 static int r8180_wx_radio_off(struct net_device *dev,
984 struct iw_request_info *info,
985 union iwreq_data *wrqu, char *extra)
987 struct r8180_priv *priv = ieee80211_priv(dev);
989 if (priv->ieee80211->bHwRadioOff)
1001 static int r8180_wx_get_channelplan(struct net_device *dev,
1002 struct iw_request_info *info,
1003 union iwreq_data *wrqu, char *extra)
1005 struct r8180_priv *priv = ieee80211_priv(dev);
1009 down(&priv->wx_sem);
1010 *extra = priv->channel_plan;
1018 static int r8180_wx_set_channelplan(struct net_device *dev,
1019 struct iw_request_info *info,
1020 union iwreq_data *wrqu, char *extra)
1022 struct r8180_priv *priv = ieee80211_priv(dev);
1023 int *val = (int *)extra;
1025 printk("-----in fun %s\n", __func__);
1027 if (priv->ieee80211->bHwRadioOff)
1030 /* unsigned long flags; */
1031 down(&priv->wx_sem);
1032 if (DefaultChannelPlan[*val].Len != 0) {
1033 priv->channel_plan = *val;
1034 /* Clear old channel map 8 */
1035 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1036 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1038 /* Set new channel map */
1039 for (i = 1; i <= DefaultChannelPlan[*val].Len; i++)
1040 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1048 static int r8180_wx_get_version(struct net_device *dev,
1049 struct iw_request_info *info,
1050 union iwreq_data *wrqu, char *extra)
1052 struct r8180_priv *priv = ieee80211_priv(dev);
1053 /* struct ieee80211_device *ieee; */
1055 down(&priv->wx_sem);
1056 strcpy(extra, "1020.0808");
1062 /* added by amy 080818 */
1063 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1064 static int r8180_wx_set_forcerate(struct net_device *dev,
1065 struct iw_request_info *info,
1066 union iwreq_data *wrqu, char *extra)
1068 struct r8180_priv *priv = ieee80211_priv(dev);
1069 u8 forcerate = *extra;
1071 down(&priv->wx_sem);
1073 printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1074 if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1075 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1076 (forcerate == 96) || (forcerate == 108))
1078 priv->ForcedDataRate = 1;
1079 priv->ieee80211->rate = forcerate * 5;
1080 } else if (forcerate == 0) {
1081 priv->ForcedDataRate = 0;
1082 printk("OK! return rate adaptive\n");
1084 printk("ERR: wrong rate\n");
1089 static int r8180_wx_set_enc_ext(struct net_device *dev,
1090 struct iw_request_info *info,
1091 union iwreq_data *wrqu, char *extra)
1094 struct r8180_priv *priv = ieee80211_priv(dev);
1098 if (priv->ieee80211->bHwRadioOff)
1101 down(&priv->wx_sem);
1102 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1107 static int r8180_wx_set_auth(struct net_device *dev,
1108 struct iw_request_info *info,
1109 union iwreq_data *wrqu, char *extra)
1111 struct r8180_priv *priv = ieee80211_priv(dev);
1114 if (priv->ieee80211->bHwRadioOff)
1117 down(&priv->wx_sem);
1118 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1123 static int r8180_wx_set_mlme(struct net_device *dev,
1124 struct iw_request_info *info,
1125 union iwreq_data *wrqu, char *extra)
1128 struct r8180_priv *priv = ieee80211_priv(dev);
1131 if (priv->ieee80211->bHwRadioOff)
1135 down(&priv->wx_sem);
1137 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1142 static int r8180_wx_set_gen_ie(struct net_device *dev,
1143 struct iw_request_info *info,
1144 union iwreq_data *wrqu, char *extra)
1147 struct r8180_priv *priv = ieee80211_priv(dev);
1150 if (priv->ieee80211->bHwRadioOff)
1153 down(&priv->wx_sem);
1155 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1163 static const iw_handler r8180_wx_handlers[] = {
1164 IW_HANDLER(SIOCGIWNAME, r8180_wx_get_name),
1165 IW_HANDLER(SIOCSIWNWID, dummy),
1166 IW_HANDLER(SIOCGIWNWID, dummy),
1167 IW_HANDLER(SIOCSIWFREQ, r8180_wx_set_freq),
1168 IW_HANDLER(SIOCGIWFREQ, r8180_wx_get_freq),
1169 IW_HANDLER(SIOCSIWMODE, r8180_wx_set_mode),
1170 IW_HANDLER(SIOCGIWMODE, r8180_wx_get_mode),
1171 IW_HANDLER(SIOCSIWSENS, r8180_wx_set_sens),
1172 IW_HANDLER(SIOCGIWSENS, r8180_wx_get_sens),
1173 IW_HANDLER(SIOCGIWRANGE, rtl8180_wx_get_range),
1174 IW_HANDLER(SIOCSIWSPY, dummy),
1175 IW_HANDLER(SIOCGIWSPY, dummy),
1176 IW_HANDLER(SIOCSIWAP, r8180_wx_set_wap),
1177 IW_HANDLER(SIOCGIWAP, r8180_wx_get_wap),
1178 IW_HANDLER(SIOCSIWMLME, r8180_wx_set_mlme),
1179 IW_HANDLER(SIOCGIWAPLIST, dummy), /* deprecated */
1180 IW_HANDLER(SIOCSIWSCAN, r8180_wx_set_scan),
1181 IW_HANDLER(SIOCGIWSCAN, r8180_wx_get_scan),
1182 IW_HANDLER(SIOCSIWESSID, r8180_wx_set_essid),
1183 IW_HANDLER(SIOCGIWESSID, r8180_wx_get_essid),
1184 IW_HANDLER(SIOCSIWNICKN, dummy),
1185 IW_HANDLER(SIOCGIWNICKN, dummy),
1186 IW_HANDLER(SIOCSIWRATE, r8180_wx_set_rate),
1187 IW_HANDLER(SIOCGIWRATE, r8180_wx_get_rate),
1188 IW_HANDLER(SIOCSIWRTS, r8180_wx_set_rts),
1189 IW_HANDLER(SIOCGIWRTS, r8180_wx_get_rts),
1190 IW_HANDLER(SIOCSIWFRAG, r8180_wx_set_frag),
1191 IW_HANDLER(SIOCGIWFRAG, r8180_wx_get_frag),
1192 IW_HANDLER(SIOCSIWTXPOW, dummy),
1193 IW_HANDLER(SIOCGIWTXPOW, dummy),
1194 IW_HANDLER(SIOCSIWRETRY, r8180_wx_set_retry),
1195 IW_HANDLER(SIOCGIWRETRY, r8180_wx_get_retry),
1196 IW_HANDLER(SIOCSIWENCODE, r8180_wx_set_enc),
1197 IW_HANDLER(SIOCGIWENCODE, r8180_wx_get_enc),
1198 IW_HANDLER(SIOCSIWPOWER, r8180_wx_set_power),
1199 IW_HANDLER(SIOCGIWPOWER, r8180_wx_get_power),
1200 IW_HANDLER(SIOCSIWGENIE, r8180_wx_set_gen_ie),
1201 IW_HANDLER(SIOCSIWAUTH, r8180_wx_set_auth),
1202 IW_HANDLER(SIOCSIWENCODEEXT, r8180_wx_set_enc_ext),
1205 static const struct iw_priv_args r8180_private_args[] = {
1207 SIOCIWFIRSTPRIV + 0x0,
1208 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1210 { SIOCIWFIRSTPRIV + 0x1,
1215 SIOCIWFIRSTPRIV + 0x2,
1216 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1218 { SIOCIWFIRSTPRIV + 0x3,
1223 SIOCIWFIRSTPRIV + 0x4,
1224 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1227 { SIOCIWFIRSTPRIV + 0x5,
1232 SIOCIWFIRSTPRIV + 0x6,
1233 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1236 { SIOCIWFIRSTPRIV + 0x7,
1241 SIOCIWFIRSTPRIV + 0x8,
1242 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1245 SIOCIWFIRSTPRIV + 0x9,
1246 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1249 SIOCIWFIRSTPRIV + 0xA,
1250 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1253 SIOCIWFIRSTPRIV + 0xB,
1254 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1256 { SIOCIWFIRSTPRIV + 0xC,
1260 SIOCIWFIRSTPRIV + 0xD,
1261 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1263 { SIOCIWFIRSTPRIV + 0xE,
1267 SIOCIWFIRSTPRIV + 0xF,
1268 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1271 SIOCIWFIRSTPRIV + 0x10,
1275 SIOCIWFIRSTPRIV + 0x11,
1279 SIOCIWFIRSTPRIV + 0x12,
1283 SIOCIWFIRSTPRIV + 0x13,
1287 SIOCIWFIRSTPRIV + 0x14,
1288 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1291 SIOCIWFIRSTPRIV + 0x15,
1292 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1295 SIOCIWFIRSTPRIV + 0x16,
1299 SIOCIWFIRSTPRIV + 0x17,
1300 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1303 SIOCIWFIRSTPRIV + 0x18,
1304 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1309 static iw_handler r8180_private_handler[] = {
1310 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1312 r8180_wx_set_beaconinterval,
1314 /* r8180_wx_set_monitor_type, */
1315 r8180_wx_set_scan_type,
1319 r8180_wx_set_iwmode,
1320 r8180_wx_get_iwmode,
1321 r8180_wx_set_preamble,
1322 r8180_wx_get_preamble,
1324 r8180_wx_get_siglevel,
1326 r8180_wx_get_sigqual,
1327 r8180_wx_reset_stats,
1328 dummy,/* r8180_wx_get_stats */
1331 r8180_wx_set_channelplan,
1332 r8180_wx_get_channelplan,
1334 r8180_wx_get_version,
1335 r8180_wx_set_forcerate,
1338 static inline int is_same_network(struct ieee80211_network *src,
1339 struct ieee80211_network *dst,
1340 struct ieee80211_device *ieee)
1342 /* A network is only a duplicate if the channel, BSSID, ESSID
1343 * and the capability field (in particular IBSS and BSS) all match.
1344 * We treat all <hidden> with the same BSSID and channel
1347 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1348 (src->channel == dst->channel) &&
1349 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1350 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1351 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1352 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1353 ((src->capability & WLAN_CAPABILITY_BSS) ==
1354 (dst->capability & WLAN_CAPABILITY_BSS)));
1357 /* WB modified to show signal to GUI on 18-01-2008 */
1358 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1360 struct r8180_priv *priv = ieee80211_priv(dev);
1361 struct ieee80211_device* ieee = priv->ieee80211;
1362 struct iw_statistics* wstats = &priv->wstats;
1367 if (ieee->state < IEEE80211_LINKED) {
1368 wstats->qual.qual = 0;
1369 wstats->qual.level = 0;
1370 wstats->qual.noise = 0;
1371 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1375 tmp_level = (&ieee->current_network)->stats.signal;
1376 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1377 tmp_noise = (&ieee->current_network)->stats.noise;
1379 wstats->qual.level = tmp_level;
1380 wstats->qual.qual = tmp_qual;
1381 wstats->qual.noise = tmp_noise;
1382 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1386 struct iw_handler_def r8180_wx_handlers_def = {
1387 .standard = r8180_wx_handlers,
1388 .num_standard = ARRAY_SIZE(r8180_wx_handlers),
1389 .private = r8180_private_handler,
1390 .num_private = ARRAY_SIZE(r8180_private_handler),
1391 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1392 .get_wireless_stats = r8180_get_wireless_stats,
1393 .private_args = (struct iw_priv_args *)r8180_private_args,