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 static 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 struct rtl8187se_channel_list default_channel_plan[] = {
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.b_busy_traffic) && (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)
521 ret = r8180_wx_set_key(dev, info, wrqu, key);
523 DMESG("Setting SW wep key");
524 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
532 static int r8180_wx_get_enc(struct net_device *dev,
533 struct iw_request_info *info,
534 union iwreq_data *wrqu, char *key)
536 struct r8180_priv *priv = ieee80211_priv(dev);
538 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
542 static int r8180_wx_set_scan_type(struct net_device *dev,
543 struct iw_request_info *aa,
544 union iwreq_data *wrqu, char *p)
547 struct r8180_priv *priv = ieee80211_priv(dev);
548 int *parms = (int *)p;
551 if (priv->ieee80211->bHwRadioOff)
554 priv->ieee80211->active_scan = mode;
559 static int r8180_wx_set_retry(struct net_device *dev,
560 struct iw_request_info *info,
561 union iwreq_data *wrqu, char *extra)
563 struct r8180_priv *priv = ieee80211_priv(dev);
566 if (priv->ieee80211->bHwRadioOff)
571 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
572 wrqu->retry.disabled) {
576 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
581 if (wrqu->retry.value > R8180_MAX_RETRY) {
585 if (wrqu->retry.flags & IW_RETRY_MAX) {
586 priv->retry_rts = wrqu->retry.value;
587 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
590 priv->retry_data = wrqu->retry.value;
591 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
595 * We might try to write directly the TX config register
596 * or to restart just the (R)TX process.
597 * I'm unsure if whole reset is really needed
607 static int r8180_wx_get_retry(struct net_device *dev,
608 struct iw_request_info *info,
609 union iwreq_data *wrqu, char *extra)
611 struct r8180_priv *priv = ieee80211_priv(dev);
614 wrqu->retry.disabled = 0; /* can't be disabled */
616 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
620 if (wrqu->retry.flags & IW_RETRY_MAX) {
621 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
622 wrqu->retry.value = priv->retry_rts;
624 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
625 wrqu->retry.value = priv->retry_data;
631 static int r8180_wx_get_sens(struct net_device *dev,
632 struct iw_request_info *info,
633 union iwreq_data *wrqu, char *extra)
635 struct r8180_priv *priv = ieee80211_priv(dev);
636 if (priv->rf_set_sens == NULL)
637 return -1; /* we have not this support for this radio */
638 wrqu->sens.value = priv->sens;
643 static int r8180_wx_set_sens(struct net_device *dev,
644 struct iw_request_info *info,
645 union iwreq_data *wrqu, char *extra)
648 struct r8180_priv *priv = ieee80211_priv(dev);
652 if (priv->ieee80211->bHwRadioOff)
656 if (priv->rf_set_sens == NULL) {
657 err = -1; /* we have not this support for this radio */
660 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
661 priv->sens = wrqu->sens.value;
672 static int r8180_wx_set_rawtx(struct net_device *dev,
673 struct iw_request_info *info,
674 union iwreq_data *wrqu, char *extra)
676 struct r8180_priv *priv = ieee80211_priv(dev);
679 if (priv->ieee80211->bHwRadioOff)
684 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
692 static int r8180_wx_get_power(struct net_device *dev,
693 struct iw_request_info *info,
694 union iwreq_data *wrqu, char *extra)
697 struct r8180_priv *priv = ieee80211_priv(dev);
701 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
708 static int r8180_wx_set_power(struct net_device *dev,
709 struct iw_request_info *info,
710 union iwreq_data *wrqu, char *extra)
713 struct r8180_priv *priv = ieee80211_priv(dev);
716 if (priv->ieee80211->bHwRadioOff)
720 printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
721 if (wrqu->power.disabled == 0) {
722 wrqu->power.flags |= IW_POWER_ALL_R;
723 wrqu->power.flags |= IW_POWER_TIMEOUT;
724 wrqu->power.value = 1000;
727 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
734 static int r8180_wx_set_rts(struct net_device *dev,
735 struct iw_request_info *info,
736 union iwreq_data *wrqu, char *extra)
738 struct r8180_priv *priv = ieee80211_priv(dev);
741 if (priv->ieee80211->bHwRadioOff)
744 if (wrqu->rts.disabled)
745 priv->rts = DEFAULT_RTS_THRESHOLD;
747 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
748 wrqu->rts.value > MAX_RTS_THRESHOLD)
751 priv->rts = wrqu->rts.value;
756 static int r8180_wx_get_rts(struct net_device *dev,
757 struct iw_request_info *info,
758 union iwreq_data *wrqu, char *extra)
760 struct r8180_priv *priv = ieee80211_priv(dev);
764 wrqu->rts.value = priv->rts;
765 wrqu->rts.fixed = 0; /* no auto select */
766 wrqu->rts.disabled = (wrqu->rts.value == 0);
770 static int dummy(struct net_device *dev, struct iw_request_info *a,
771 union iwreq_data *wrqu, char *b)
776 static int r8180_wx_get_iwmode(struct net_device *dev,
777 struct iw_request_info *info,
778 union iwreq_data *wrqu, char *extra)
780 struct r8180_priv *priv = ieee80211_priv(dev);
781 struct ieee80211_device *ieee;
788 ieee = priv->ieee80211;
790 strcpy(extra, "802.11");
791 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
793 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
795 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
802 static int r8180_wx_set_iwmode(struct net_device *dev,
803 struct iw_request_info *info,
804 union iwreq_data *wrqu, char *extra)
806 struct r8180_priv *priv = ieee80211_priv(dev);
807 struct ieee80211_device *ieee = priv->ieee80211;
808 int *param = (int *)extra;
810 int modulation = 0, mode = 0;
813 if (priv->ieee80211->bHwRadioOff)
819 modulation |= IEEE80211_CCK_MODULATION;
821 printk(KERN_INFO "B mode!\n");
822 } else if (*param == 2) {
823 modulation |= IEEE80211_OFDM_MODULATION;
825 printk(KERN_INFO "G mode!\n");
826 } else if (*param == 3) {
827 modulation |= IEEE80211_CCK_MODULATION;
828 modulation |= IEEE80211_OFDM_MODULATION;
829 mode = IEEE_B|IEEE_G;
830 printk(KERN_INFO "B/G mode!\n");
833 if (ieee->proto_started) {
834 ieee80211_stop_protocol(ieee);
836 ieee->modulation = modulation;
837 ieee80211_start_protocol(ieee);
840 ieee->modulation = modulation;
847 static int r8180_wx_get_preamble(struct net_device *dev,
848 struct iw_request_info *info,
849 union iwreq_data *wrqu, char *extra)
851 struct r8180_priv *priv = ieee80211_priv(dev);
859 *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
864 static int r8180_wx_set_preamble(struct net_device *dev,
865 struct iw_request_info *info,
866 union iwreq_data *wrqu, char *extra)
868 struct r8180_priv *priv = ieee80211_priv(dev);
872 if (priv->ieee80211->bHwRadioOff)
876 if (*extra < 0 || *extra > 2)
879 priv->plcp_preamble_mode = *((short *)extra);
887 static int r8180_wx_get_siglevel(struct net_device *dev,
888 struct iw_request_info *info,
889 union iwreq_data *wrqu, char *extra)
891 struct r8180_priv *priv = ieee80211_priv(dev);
897 /* Modify by hikaru 6.5 */
898 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
906 static int r8180_wx_get_sigqual(struct net_device *dev,
907 struct iw_request_info *info,
908 union iwreq_data *wrqu, char *extra)
910 struct r8180_priv *priv = ieee80211_priv(dev);
916 /* Modify by hikaru 6.5 */
917 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
925 static int r8180_wx_reset_stats(struct net_device *dev,
926 struct iw_request_info *info,
927 union iwreq_data *wrqu, char *extra)
929 struct r8180_priv *priv = ieee80211_priv(dev);
932 priv->stats.txrdu = 0;
933 priv->stats.rxrdu = 0;
934 priv->stats.rxnolast = 0;
935 priv->stats.rxnodata = 0;
936 priv->stats.rxnopointer = 0;
937 priv->stats.txnperr = 0;
938 priv->stats.txresumed = 0;
939 priv->stats.rxerr = 0;
940 priv->stats.rxoverflow = 0;
941 priv->stats.rxint = 0;
943 priv->stats.txnpokint = 0;
944 priv->stats.txhpokint = 0;
945 priv->stats.txhperr = 0;
946 priv->stats.ints = 0;
947 priv->stats.shints = 0;
948 priv->stats.txoverflow = 0;
949 priv->stats.rxdmafail = 0;
950 priv->stats.txbeacon = 0;
951 priv->stats.txbeaconerr = 0;
952 priv->stats.txlpokint = 0;
953 priv->stats.txlperr = 0;
954 priv->stats.txretry = 0;/* 20060601 */
955 priv->stats.rxcrcerrmin = 0 ;
956 priv->stats.rxcrcerrmid = 0;
957 priv->stats.rxcrcerrmax = 0;
958 priv->stats.rxicverr = 0;
965 static int r8180_wx_radio_on(struct net_device *dev,
966 struct iw_request_info *info,
967 union iwreq_data *wrqu, char *extra)
969 struct r8180_priv *priv = ieee80211_priv(dev);
971 if (priv->ieee80211->bHwRadioOff)
976 priv->rf_wakeup(dev);
984 static int r8180_wx_radio_off(struct net_device *dev,
985 struct iw_request_info *info,
986 union iwreq_data *wrqu, char *extra)
988 struct r8180_priv *priv = ieee80211_priv(dev);
990 if (priv->ieee80211->bHwRadioOff)
1002 static int r8180_wx_get_channelplan(struct net_device *dev,
1003 struct iw_request_info *info,
1004 union iwreq_data *wrqu, char *extra)
1006 struct r8180_priv *priv = ieee80211_priv(dev);
1010 down(&priv->wx_sem);
1011 *extra = priv->channel_plan;
1019 static int r8180_wx_set_channelplan(struct net_device *dev,
1020 struct iw_request_info *info,
1021 union iwreq_data *wrqu, char *extra)
1023 struct r8180_priv *priv = ieee80211_priv(dev);
1024 int *val = (int *)extra;
1026 printk("-----in fun %s\n", __func__);
1028 if (priv->ieee80211->bHwRadioOff)
1031 /* unsigned long flags; */
1032 down(&priv->wx_sem);
1033 if (default_channel_plan[*val].len != 0) {
1034 priv->channel_plan = *val;
1035 /* Clear old channel map 8 */
1036 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1037 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1039 /* Set new channel map */
1040 for (i = 1; i <= default_channel_plan[*val].len; i++)
1041 GET_DOT11D_INFO(priv->ieee80211)->channel_map[default_channel_plan[*val].channel[i-1]] = 1;
1049 static int r8180_wx_get_version(struct net_device *dev,
1050 struct iw_request_info *info,
1051 union iwreq_data *wrqu, char *extra)
1053 struct r8180_priv *priv = ieee80211_priv(dev);
1054 /* struct ieee80211_device *ieee; */
1056 down(&priv->wx_sem);
1057 strcpy(extra, "1020.0808");
1063 /* added by amy 080818 */
1064 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1065 static int r8180_wx_set_forcerate(struct net_device *dev,
1066 struct iw_request_info *info,
1067 union iwreq_data *wrqu, char *extra)
1069 struct r8180_priv *priv = ieee80211_priv(dev);
1070 u8 forcerate = *extra;
1072 down(&priv->wx_sem);
1074 printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1075 if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1076 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1077 (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 if (src->channel != dst->channel)
1350 if (memcmp(src->bssid, dst->bssid, ETH_ALEN) != 0)
1353 if (ieee->iw_mode != IW_MODE_INFRA) {
1354 if (src->ssid_len != dst->ssid_len)
1356 if (memcmp(src->ssid, dst->ssid, src->ssid_len) != 0)
1360 if ((src->capability & WLAN_CAPABILITY_IBSS) !=
1361 (dst->capability & WLAN_CAPABILITY_IBSS))
1363 if ((src->capability & WLAN_CAPABILITY_BSS) !=
1364 (dst->capability & WLAN_CAPABILITY_BSS))
1370 /* WB modified to show signal to GUI on 18-01-2008 */
1371 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1373 struct r8180_priv *priv = ieee80211_priv(dev);
1374 struct ieee80211_device *ieee = priv->ieee80211;
1375 struct iw_statistics *wstats = &priv->wstats;
1380 if (ieee->state < IEEE80211_LINKED) {
1381 wstats->qual.qual = 0;
1382 wstats->qual.level = 0;
1383 wstats->qual.noise = 0;
1384 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1388 tmp_level = (&ieee->current_network)->stats.signal;
1389 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1390 tmp_noise = (&ieee->current_network)->stats.noise;
1392 wstats->qual.level = tmp_level;
1393 wstats->qual.qual = tmp_qual;
1394 wstats->qual.noise = tmp_noise;
1395 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1399 struct iw_handler_def r8180_wx_handlers_def = {
1400 .standard = r8180_wx_handlers,
1401 .num_standard = ARRAY_SIZE(r8180_wx_handlers),
1402 .private = r8180_private_handler,
1403 .num_private = ARRAY_SIZE(r8180_private_handler),
1404 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1405 .get_wireless_stats = r8180_get_wireless_stats,
1406 .private_args = (struct iw_priv_args *)r8180_private_args,