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 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 int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
54 union iwreq_data *wrqu, char *key)
56 struct r8180_priv *priv = ieee80211_priv(dev);
57 struct iw_point *erq = &(wrqu->encoding);
59 if (priv->ieee80211->bHwRadioOff)
62 if (erq->flags & IW_ENCODE_DISABLED)
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, struct iw_request_info *aa,
79 union iwreq_data *wrqu, char *b)
81 int *parms = (int *)b;
84 struct r8180_priv *priv = ieee80211_priv(dev);
86 if (priv->ieee80211->bHwRadioOff)
90 DMESG("setting beacon interval to %x", bi);
92 priv->ieee80211->current_network.beacon_interval = bi;
101 static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
102 union iwreq_data *wrqu, char *b)
104 struct r8180_priv *priv = ieee80211_priv(dev);
105 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
110 static int r8180_wx_get_rate(struct net_device *dev,
111 struct iw_request_info *info,
112 union iwreq_data *wrqu, char *extra)
114 struct r8180_priv *priv = ieee80211_priv(dev);
115 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
120 static int r8180_wx_set_rate(struct net_device *dev,
121 struct iw_request_info *info,
122 union iwreq_data *wrqu, char *extra)
125 struct r8180_priv *priv = ieee80211_priv(dev);
128 if (priv->ieee80211->bHwRadioOff)
133 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
141 static int r8180_wx_set_crcmon(struct net_device *dev,
142 struct iw_request_info *info,
143 union iwreq_data *wrqu, char *extra)
145 struct r8180_priv *priv = ieee80211_priv(dev);
146 int *parms = (int *)extra;
147 int enable = (parms[0] > 0);
148 short prev = priv->crcmon;
151 if (priv->ieee80211->bHwRadioOff)
161 DMESG("bad CRC in monitor mode are %s",
162 priv->crcmon ? "accepted" : "rejected");
164 if (prev != priv->crcmon && priv->up) {
175 static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
176 union iwreq_data *wrqu, char *b)
178 struct r8180_priv *priv = ieee80211_priv(dev);
182 if (priv->ieee80211->bHwRadioOff)
186 if (priv->bInactivePs) {
187 if (wrqu->mode == IW_MODE_ADHOC)
190 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
196 /* YJ,add,080819,for hidden ap */
197 struct iw_range_with_scan_capa {
198 /* Informative stuff (to choose between different interface) */
200 __u32 throughput; /* To give an idea... */
202 /* In theory this value should be the maximum benchmarked
203 * TCP/IP throughput, because with most of these devices the
204 * bit rate is meaningless (overhead an co) to estimate how
205 * fast the connection will go and pick the fastest one.
206 * I suggest people to play with Netperf or any benchmark...
209 /* NWID (or domain id) */
210 __u32 min_nwid; /* Minimal NWID we are able to set */
211 __u32 max_nwid; /* Maximal NWID we are able to set */
213 /* Old Frequency (backward compat - moved lower ) */
214 __u16 old_num_channels;
215 __u8 old_num_frequency;
217 /* Scan capabilities */
220 /* YJ,add,080819,for hidden ap */
223 static int rtl8180_wx_get_range(struct net_device *dev,
224 struct iw_request_info *info,
225 union iwreq_data *wrqu, char *extra)
227 struct iw_range *range = (struct iw_range *)extra;
228 struct r8180_priv *priv = ieee80211_priv(dev);
232 wrqu->data.length = sizeof(*range);
233 memset(range, 0, sizeof(*range));
235 /* Let's try to keep this struct in the same order as in
236 * linux/include/wireless.h
239 /* TODO: See what values we can set, and remove the ones we can't
240 * set, or fill them with some default data.
243 /* ~5 Mb/s real (802.11b) */
244 range->throughput = 5 * 1000 * 1000;
246 /* TODO: Not used in 802.11b? */
247 /* range->min_nwid; */ /* Minimal NWID we are able to set */
248 /* TODO: Not used in 802.11b? */
249 /* range->max_nwid; */ /* Maximal NWID we are able to set */
251 /* Old Frequency (backward compat - moved lower ) */
252 /* range->old_num_channels; */
253 /* range->old_num_frequency; */
254 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
255 if (priv->rf_set_sens != NULL)
256 range->sensitivity = priv->max_sens; /* signal level threshold range */
258 range->max_qual.qual = 100;
259 /* TODO: Find real max RSSI and stick here */
260 range->max_qual.level = 0;
261 range->max_qual.noise = -98;
262 range->max_qual.updated = 7; /* Updated all three */
264 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
265 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
266 range->avg_qual.level = 20 + -98;
267 range->avg_qual.noise = 0;
268 range->avg_qual.updated = 7; /* Updated all three */
270 range->num_bitrates = RATE_COUNT;
272 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
273 range->bitrate[i] = rtl8180_rates[i];
275 range->min_frag = MIN_FRAG_THRESHOLD;
276 range->max_frag = MAX_FRAG_THRESHOLD;
280 range->we_version_compiled = WIRELESS_EXT;
281 range->we_version_source = 16;
283 range->num_channels = 14;
285 for (i = 0, val = 0; i < 14; i++) {
287 /* Include only legal frequencies for some countries */
288 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
289 range->freq[val].i = i + 1;
290 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
291 range->freq[val].e = 1;
294 /* FIXME: do we need to set anything for channels */
298 if (val == IW_MAX_FREQUENCIES)
302 range->num_frequency = val;
303 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
304 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
310 static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
311 union iwreq_data *wrqu, char *b)
313 struct r8180_priv *priv = ieee80211_priv(dev);
315 struct ieee80211_device* ieee = priv->ieee80211;
318 if (priv->ieee80211->bHwRadioOff)
321 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
322 struct iw_scan_req* req = (struct iw_scan_req*)b;
323 if (req->essid_len) {
324 ieee->current_network.ssid_len = req->essid_len;
325 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
331 priv->ieee80211->actscanning = true;
332 if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) {
334 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
337 /* prevent scan in BusyTraffic */
338 /* FIXME: Need to consider last scan time */
339 if ((priv->link_detect.bBusyTraffic) && (true)) {
341 printk("Now traffic is busy, please try later!\n");
343 /* prevent scan in BusyTraffic,end */
344 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
355 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
356 union iwreq_data *wrqu, char *b)
360 struct r8180_priv *priv = ieee80211_priv(dev);
364 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
373 static int r8180_wx_set_essid(struct net_device *dev,
374 struct iw_request_info *a,
375 union iwreq_data *wrqu, char *b)
377 struct r8180_priv *priv = ieee80211_priv(dev);
381 if (priv->ieee80211->bHwRadioOff)
385 if (priv->bInactivePs)
388 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
395 static int r8180_wx_get_essid(struct net_device *dev,
396 struct iw_request_info *a,
397 union iwreq_data *wrqu, char *b)
400 struct r8180_priv *priv = ieee80211_priv(dev);
404 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
412 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
413 union iwreq_data *wrqu, char *b)
416 struct r8180_priv *priv = ieee80211_priv(dev);
419 if (priv->ieee80211->bHwRadioOff)
424 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
431 static int r8180_wx_get_name(struct net_device *dev,
432 struct iw_request_info *info,
433 union iwreq_data *wrqu, char *extra)
435 struct r8180_priv *priv = ieee80211_priv(dev);
436 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
439 static int r8180_wx_set_frag(struct net_device *dev,
440 struct iw_request_info *info,
441 union iwreq_data *wrqu, char *extra)
443 struct r8180_priv *priv = ieee80211_priv(dev);
445 if (priv->ieee80211->bHwRadioOff)
448 if (wrqu->frag.disabled)
449 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
451 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
452 wrqu->frag.value > MAX_FRAG_THRESHOLD)
455 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
462 static int r8180_wx_get_frag(struct net_device *dev,
463 struct iw_request_info *info,
464 union iwreq_data *wrqu, char *extra)
466 struct r8180_priv *priv = ieee80211_priv(dev);
468 wrqu->frag.value = priv->ieee80211->fts;
469 wrqu->frag.fixed = 0; /* no auto select */
470 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
476 static int r8180_wx_set_wap(struct net_device *dev,
477 struct iw_request_info *info,
478 union iwreq_data *awrq,
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, struct iw_request_info *aa, union
542 iwreq_data *wrqu, char *p) {
544 struct r8180_priv *priv = ieee80211_priv(dev);
545 int *parms = (int*)p;
548 if (priv->ieee80211->bHwRadioOff)
551 priv->ieee80211->active_scan = mode;
556 static int r8180_wx_set_retry(struct net_device *dev,
557 struct iw_request_info *info,
558 union iwreq_data *wrqu, char *extra)
560 struct r8180_priv *priv = ieee80211_priv(dev);
563 if (priv->ieee80211->bHwRadioOff)
568 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
569 wrqu->retry.disabled) {
573 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
578 if (wrqu->retry.value > R8180_MAX_RETRY) {
582 if (wrqu->retry.flags & IW_RETRY_MAX) {
583 priv->retry_rts = wrqu->retry.value;
584 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
587 priv->retry_data = wrqu->retry.value;
588 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
592 * We might try to write directly the TX config register
593 * or to restart just the (R)TX process.
594 * I'm unsure if whole reset is really needed
604 static int r8180_wx_get_retry(struct net_device *dev,
605 struct iw_request_info *info,
606 union iwreq_data *wrqu, char *extra)
608 struct r8180_priv *priv = ieee80211_priv(dev);
611 wrqu->retry.disabled = 0; /* can't be disabled */
613 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
617 if (wrqu->retry.flags & IW_RETRY_MAX) {
618 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
619 wrqu->retry.value = priv->retry_rts;
621 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
622 wrqu->retry.value = priv->retry_data;
628 static int r8180_wx_get_sens(struct net_device *dev,
629 struct iw_request_info *info,
630 union iwreq_data *wrqu, char *extra)
632 struct r8180_priv *priv = ieee80211_priv(dev);
633 if (priv->rf_set_sens == NULL)
634 return -1; /* we have not this support for this radio */
635 wrqu->sens.value = priv->sens;
640 static int r8180_wx_set_sens(struct net_device *dev,
641 struct iw_request_info *info,
642 union iwreq_data *wrqu, char *extra)
645 struct r8180_priv *priv = ieee80211_priv(dev);
649 if (priv->ieee80211->bHwRadioOff)
653 if (priv->rf_set_sens == NULL) {
654 err = -1; /* we have not this support for this radio */
657 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
658 priv->sens = wrqu->sens.value;
669 static int r8180_wx_set_rawtx(struct net_device *dev,
670 struct iw_request_info *info,
671 union iwreq_data *wrqu, char *extra)
673 struct r8180_priv *priv = ieee80211_priv(dev);
676 if (priv->ieee80211->bHwRadioOff)
681 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
689 static int r8180_wx_get_power(struct net_device *dev,
690 struct iw_request_info *info,
691 union iwreq_data *wrqu, char *extra)
694 struct r8180_priv *priv = ieee80211_priv(dev);
698 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
705 static int r8180_wx_set_power(struct net_device *dev,
706 struct iw_request_info *info,
707 union iwreq_data *wrqu, char *extra)
710 struct r8180_priv *priv = ieee80211_priv(dev);
713 if (priv->ieee80211->bHwRadioOff)
717 printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
718 if (wrqu->power.disabled == 0) {
719 wrqu->power.flags |= IW_POWER_ALL_R;
720 wrqu->power.flags |= IW_POWER_TIMEOUT;
721 wrqu->power.value = 1000;
724 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
731 static int r8180_wx_set_rts(struct net_device *dev,
732 struct iw_request_info *info,
733 union iwreq_data *wrqu, char *extra)
735 struct r8180_priv *priv = ieee80211_priv(dev);
738 if (priv->ieee80211->bHwRadioOff)
741 if (wrqu->rts.disabled)
742 priv->rts = DEFAULT_RTS_THRESHOLD;
744 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
745 wrqu->rts.value > MAX_RTS_THRESHOLD)
748 priv->rts = wrqu->rts.value;
753 static int r8180_wx_get_rts(struct net_device *dev,
754 struct iw_request_info *info,
755 union iwreq_data *wrqu, char *extra)
757 struct r8180_priv *priv = ieee80211_priv(dev);
761 wrqu->rts.value = priv->rts;
762 wrqu->rts.fixed = 0; /* no auto select */
763 wrqu->rts.disabled = (wrqu->rts.value == 0);
767 static int dummy(struct net_device *dev, struct iw_request_info *a,
768 union iwreq_data *wrqu, char *b)
773 static int r8180_wx_get_iwmode(struct net_device *dev,
774 struct iw_request_info *info,
775 union iwreq_data *wrqu, char *extra)
777 struct r8180_priv *priv = ieee80211_priv(dev);
778 struct ieee80211_device *ieee;
785 ieee = priv->ieee80211;
787 strcpy(extra, "802.11");
788 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
790 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
792 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
799 static int r8180_wx_set_iwmode(struct net_device *dev,
800 struct iw_request_info *info,
801 union iwreq_data *wrqu, char *extra)
803 struct r8180_priv *priv = ieee80211_priv(dev);
804 struct ieee80211_device *ieee = priv->ieee80211;
805 int *param = (int *)extra;
807 int modulation = 0, mode = 0;
810 if (priv->ieee80211->bHwRadioOff)
816 modulation |= IEEE80211_CCK_MODULATION;
818 printk(KERN_INFO "B mode!\n");
819 } else if (*param == 2) {
820 modulation |= IEEE80211_OFDM_MODULATION;
822 printk(KERN_INFO "G mode!\n");
823 } else if (*param == 3) {
824 modulation |= IEEE80211_CCK_MODULATION;
825 modulation |= IEEE80211_OFDM_MODULATION;
826 mode = IEEE_B|IEEE_G;
827 printk(KERN_INFO "B/G mode!\n");
830 if (ieee->proto_started) {
831 ieee80211_stop_protocol(ieee);
833 ieee->modulation = modulation;
834 ieee80211_start_protocol(ieee);
837 ieee->modulation = modulation;
844 static int r8180_wx_get_preamble(struct net_device *dev,
845 struct iw_request_info *info,
846 union iwreq_data *wrqu, char *extra)
848 struct r8180_priv *priv = ieee80211_priv(dev);
856 *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
861 static int r8180_wx_set_preamble(struct net_device *dev,
862 struct iw_request_info *info,
863 union iwreq_data *wrqu, char *extra)
865 struct r8180_priv *priv = ieee80211_priv(dev);
869 if (priv->ieee80211->bHwRadioOff)
873 if (*extra < 0 || *extra > 2)
876 priv->plcp_preamble_mode = *((short *)extra) ;
884 static int r8180_wx_get_siglevel(struct net_device *dev,
885 struct iw_request_info *info,
886 union iwreq_data *wrqu, char *extra)
888 struct r8180_priv *priv = ieee80211_priv(dev);
894 /* Modify by hikaru 6.5 */
895 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
903 static int r8180_wx_get_sigqual(struct net_device *dev,
904 struct iw_request_info *info,
905 union iwreq_data *wrqu, char *extra)
907 struct r8180_priv *priv = ieee80211_priv(dev);
913 /* Modify by hikaru 6.5 */
914 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
922 static int r8180_wx_reset_stats(struct net_device *dev,
923 struct iw_request_info *info,
924 union iwreq_data *wrqu, char *extra)
926 struct r8180_priv *priv = ieee80211_priv(dev);
929 priv->stats.txrdu = 0;
930 priv->stats.rxrdu = 0;
931 priv->stats.rxnolast = 0;
932 priv->stats.rxnodata = 0;
933 priv->stats.rxnopointer = 0;
934 priv->stats.txnperr = 0;
935 priv->stats.txresumed = 0;
936 priv->stats.rxerr = 0;
937 priv->stats.rxoverflow = 0;
938 priv->stats.rxint = 0;
940 priv->stats.txnpokint = 0;
941 priv->stats.txhpokint = 0;
942 priv->stats.txhperr = 0;
943 priv->stats.ints = 0;
944 priv->stats.shints = 0;
945 priv->stats.txoverflow = 0;
946 priv->stats.rxdmafail = 0;
947 priv->stats.txbeacon = 0;
948 priv->stats.txbeaconerr = 0;
949 priv->stats.txlpokint = 0;
950 priv->stats.txlperr = 0;
951 priv->stats.txretry = 0;/* 20060601 */
952 priv->stats.rxcrcerrmin = 0 ;
953 priv->stats.rxcrcerrmid = 0;
954 priv->stats.rxcrcerrmax = 0;
955 priv->stats.rxicverr = 0;
962 static int r8180_wx_radio_on(struct net_device *dev,
963 struct iw_request_info *info,
964 union iwreq_data *wrqu, char *extra)
966 struct r8180_priv *priv = ieee80211_priv(dev);
968 if (priv->ieee80211->bHwRadioOff)
973 priv->rf_wakeup(dev);
981 static int r8180_wx_radio_off(struct net_device *dev,
982 struct iw_request_info *info,
983 union iwreq_data *wrqu, char *extra)
985 struct r8180_priv *priv = ieee80211_priv(dev);
987 if (priv->ieee80211->bHwRadioOff)
999 static int r8180_wx_get_channelplan(struct net_device *dev,
1000 struct iw_request_info *info,
1001 union iwreq_data *wrqu, char *extra)
1003 struct r8180_priv *priv = ieee80211_priv(dev);
1007 down(&priv->wx_sem);
1008 *extra = priv->channel_plan;
1016 static int r8180_wx_set_channelplan(struct net_device *dev,
1017 struct iw_request_info *info,
1018 union iwreq_data *wrqu, char *extra)
1020 struct r8180_priv *priv = ieee80211_priv(dev);
1021 int *val = (int *)extra;
1023 printk("-----in fun %s\n", __func__);
1025 if (priv->ieee80211->bHwRadioOff)
1028 /* unsigned long flags; */
1029 down(&priv->wx_sem);
1030 if (DefaultChannelPlan[*val].Len != 0) {
1031 priv->channel_plan = *val;
1032 /* Clear old channel map 8 */
1033 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1034 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1036 /* Set new channel map */
1037 for (i = 1; i <= DefaultChannelPlan[*val].Len; i++)
1038 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1046 static int r8180_wx_get_version(struct net_device *dev,
1047 struct iw_request_info *info,
1048 union iwreq_data *wrqu, char *extra)
1050 struct r8180_priv *priv = ieee80211_priv(dev);
1051 /* struct ieee80211_device *ieee; */
1053 down(&priv->wx_sem);
1054 strcpy(extra, "1020.0808");
1060 /* added by amy 080818 */
1061 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1062 static int r8180_wx_set_forcerate(struct net_device *dev,
1063 struct iw_request_info *info,
1064 union iwreq_data *wrqu, char *extra)
1066 struct r8180_priv *priv = ieee80211_priv(dev);
1067 u8 forcerate = *extra;
1069 down(&priv->wx_sem);
1071 printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1072 if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1073 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1074 (forcerate == 96) || (forcerate == 108))
1076 priv->ForcedDataRate = 1;
1077 priv->ieee80211->rate = forcerate * 5;
1078 } else if (forcerate == 0) {
1079 priv->ForcedDataRate = 0;
1080 printk("OK! return rate adaptive\n");
1082 printk("ERR: wrong rate\n");
1087 static int r8180_wx_set_enc_ext(struct net_device *dev,
1088 struct iw_request_info *info,
1089 union iwreq_data *wrqu, char *extra)
1092 struct r8180_priv *priv = ieee80211_priv(dev);
1096 if (priv->ieee80211->bHwRadioOff)
1099 down(&priv->wx_sem);
1100 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1105 static int r8180_wx_set_auth(struct net_device *dev,
1106 struct iw_request_info *info,
1107 union iwreq_data *wrqu, char *extra)
1109 struct r8180_priv *priv = ieee80211_priv(dev);
1112 if (priv->ieee80211->bHwRadioOff)
1115 down(&priv->wx_sem);
1116 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1121 static int r8180_wx_set_mlme(struct net_device *dev,
1122 struct iw_request_info *info,
1123 union iwreq_data *wrqu, char *extra)
1126 struct r8180_priv *priv = ieee80211_priv(dev);
1129 if (priv->ieee80211->bHwRadioOff)
1133 down(&priv->wx_sem);
1135 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1140 static int r8180_wx_set_gen_ie(struct net_device *dev,
1141 struct iw_request_info *info,
1142 union iwreq_data *wrqu, char *extra)
1145 struct r8180_priv *priv = ieee80211_priv(dev);
1148 if (priv->ieee80211->bHwRadioOff)
1151 down(&priv->wx_sem);
1153 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1160 static iw_handler r8180_wx_handlers[] = {
1161 NULL, /* SIOCSIWCOMMIT */
1162 r8180_wx_get_name, /* SIOCGIWNAME */
1163 dummy, /* SIOCSIWNWID */
1164 dummy, /* SIOCGIWNWID */
1165 r8180_wx_set_freq, /* SIOCSIWFREQ */
1166 r8180_wx_get_freq, /* SIOCGIWFREQ */
1167 r8180_wx_set_mode, /* SIOCSIWMODE */
1168 r8180_wx_get_mode, /* SIOCGIWMODE */
1169 r8180_wx_set_sens, /* SIOCSIWSENS */
1170 r8180_wx_get_sens, /* SIOCGIWSENS */
1171 NULL, /* SIOCSIWRANGE */
1172 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1173 NULL, /* SIOCSIWPRIV */
1174 NULL, /* SIOCGIWPRIV */
1175 NULL, /* SIOCSIWSTATS */
1176 NULL, /* SIOCGIWSTATS */
1177 dummy, /* SIOCSIWSPY */
1178 dummy, /* SIOCGIWSPY */
1179 NULL, /* SIOCGIWTHRSPY */
1180 NULL, /* SIOCWIWTHRSPY */
1181 r8180_wx_set_wap, /* SIOCSIWAP */
1182 r8180_wx_get_wap, /* SIOCGIWAP */
1183 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1184 dummy, /* SIOCGIWAPLIST -- deprecated */
1185 r8180_wx_set_scan, /* SIOCSIWSCAN */
1186 r8180_wx_get_scan, /* SIOCGIWSCAN */
1187 r8180_wx_set_essid, /* SIOCSIWESSID */
1188 r8180_wx_get_essid, /* SIOCGIWESSID */
1189 dummy, /* SIOCSIWNICKN */
1190 dummy, /* SIOCGIWNICKN */
1191 NULL, /* -- hole -- */
1192 NULL, /* -- hole -- */
1193 r8180_wx_set_rate, /* SIOCSIWRATE */
1194 r8180_wx_get_rate, /* SIOCGIWRATE */
1195 r8180_wx_set_rts, /* SIOCSIWRTS */
1196 r8180_wx_get_rts, /* SIOCGIWRTS */
1197 r8180_wx_set_frag, /* SIOCSIWFRAG */
1198 r8180_wx_get_frag, /* SIOCGIWFRAG */
1199 dummy, /* SIOCSIWTXPOW */
1200 dummy, /* SIOCGIWTXPOW */
1201 r8180_wx_set_retry, /* SIOCSIWRETRY */
1202 r8180_wx_get_retry, /* SIOCGIWRETRY */
1203 r8180_wx_set_enc, /* SIOCSIWENCODE */
1204 r8180_wx_get_enc, /* SIOCGIWENCODE */
1205 r8180_wx_set_power, /* SIOCSIWPOWER */
1206 r8180_wx_get_power, /* SIOCGIWPOWER */
1207 NULL, /*---hole---*/
1208 NULL, /*---hole---*/
1209 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1210 NULL, /* SIOCSIWGENIE */
1211 r8180_wx_set_auth, /* SIOCSIWAUTH */
1212 NULL, /* SIOCSIWAUTH */
1213 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1214 NULL, /* SIOCSIWENCODEEXT */
1215 NULL, /* SIOCSIWPMKSA */
1216 NULL, /*---hole---*/
1220 static const struct iw_priv_args r8180_private_args[] = {
1222 SIOCIWFIRSTPRIV + 0x0,
1223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1225 { SIOCIWFIRSTPRIV + 0x1,
1230 SIOCIWFIRSTPRIV + 0x2,
1231 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1233 { SIOCIWFIRSTPRIV + 0x3,
1238 SIOCIWFIRSTPRIV + 0x4,
1239 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1242 { SIOCIWFIRSTPRIV + 0x5,
1247 SIOCIWFIRSTPRIV + 0x6,
1248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1251 { SIOCIWFIRSTPRIV + 0x7,
1256 SIOCIWFIRSTPRIV + 0x8,
1257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1260 SIOCIWFIRSTPRIV + 0x9,
1261 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1264 SIOCIWFIRSTPRIV + 0xA,
1265 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1268 SIOCIWFIRSTPRIV + 0xB,
1269 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1271 { SIOCIWFIRSTPRIV + 0xC,
1275 SIOCIWFIRSTPRIV + 0xD,
1276 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1278 { SIOCIWFIRSTPRIV + 0xE,
1282 SIOCIWFIRSTPRIV + 0xF,
1283 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1286 SIOCIWFIRSTPRIV + 0x10,
1290 SIOCIWFIRSTPRIV + 0x11,
1294 SIOCIWFIRSTPRIV + 0x12,
1298 SIOCIWFIRSTPRIV + 0x13,
1302 SIOCIWFIRSTPRIV + 0x14,
1303 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1306 SIOCIWFIRSTPRIV + 0x15,
1307 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1310 SIOCIWFIRSTPRIV + 0x16,
1314 SIOCIWFIRSTPRIV + 0x17,
1315 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1318 SIOCIWFIRSTPRIV + 0x18,
1319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1324 static iw_handler r8180_private_handler[] = {
1325 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1327 r8180_wx_set_beaconinterval,
1329 /* r8180_wx_set_monitor_type, */
1330 r8180_wx_set_scan_type,
1334 r8180_wx_set_iwmode,
1335 r8180_wx_get_iwmode,
1336 r8180_wx_set_preamble,
1337 r8180_wx_get_preamble,
1339 r8180_wx_get_siglevel,
1341 r8180_wx_get_sigqual,
1342 r8180_wx_reset_stats,
1343 dummy,/* r8180_wx_get_stats */
1346 r8180_wx_set_channelplan,
1347 r8180_wx_get_channelplan,
1349 r8180_wx_get_version,
1350 r8180_wx_set_forcerate,
1353 static inline int is_same_network(struct ieee80211_network *src,
1354 struct ieee80211_network *dst,
1355 struct ieee80211_device *ieee)
1357 /* A network is only a duplicate if the channel, BSSID, ESSID
1358 * and the capability field (in particular IBSS and BSS) all match.
1359 * We treat all <hidden> with the same BSSID and channel
1362 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1363 (src->channel == dst->channel) &&
1364 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1365 (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1366 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1367 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1368 ((src->capability & WLAN_CAPABILITY_BSS) ==
1369 (dst->capability & WLAN_CAPABILITY_BSS)));
1372 /* WB modified to show signal to GUI on 18-01-2008 */
1373 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1375 struct r8180_priv *priv = ieee80211_priv(dev);
1376 struct ieee80211_device* ieee = priv->ieee80211;
1377 struct iw_statistics* wstats = &priv->wstats;
1382 if (ieee->state < IEEE80211_LINKED) {
1383 wstats->qual.qual = 0;
1384 wstats->qual.level = 0;
1385 wstats->qual.noise = 0;
1386 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1390 tmp_level = (&ieee->current_network)->stats.signal;
1391 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1392 tmp_noise = (&ieee->current_network)->stats.noise;
1394 wstats->qual.level = tmp_level;
1395 wstats->qual.qual = tmp_qual;
1396 wstats->qual.noise = tmp_noise;
1397 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1401 struct iw_handler_def r8180_wx_handlers_def = {
1402 .standard = r8180_wx_handlers,
1403 .num_standard = ARRAY_SIZE(r8180_wx_handlers),
1404 .private = r8180_private_handler,
1405 .num_private = ARRAY_SIZE(r8180_private_handler),
1406 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1407 .get_wireless_stats = r8180_get_wireless_stats,
1408 .private_args = (struct iw_priv_args *)r8180_private_args,