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 thank the Authors of those projects and the Ndiswrapper
20 #include <linux/string.h>
22 #include "r8192U_hw.h"
25 #include "r8192U_wx.h"
28 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
29 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
36 static int r8192_wx_get_freq(struct net_device *dev,
37 struct iw_request_info *a,
38 union iwreq_data *wrqu, char *b)
40 struct r8192_priv *priv = ieee80211_priv(dev);
42 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47 union iwreq_data *wrqu, char *b)
49 struct r8192_priv *priv = ieee80211_priv(dev);
51 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
56 static int r8192_wx_get_rate(struct net_device *dev,
57 struct iw_request_info *info,
58 union iwreq_data *wrqu, char *extra)
60 struct r8192_priv *priv = ieee80211_priv(dev);
62 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
67 static int r8192_wx_set_rate(struct net_device *dev,
68 struct iw_request_info *info,
69 union iwreq_data *wrqu, char *extra)
72 struct r8192_priv *priv = ieee80211_priv(dev);
76 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
84 static int r8192_wx_set_rts(struct net_device *dev,
85 struct iw_request_info *info,
86 union iwreq_data *wrqu, char *extra)
89 struct r8192_priv *priv = ieee80211_priv(dev);
93 ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
100 static int r8192_wx_get_rts(struct net_device *dev,
101 struct iw_request_info *info,
102 union iwreq_data *wrqu, char *extra)
104 struct r8192_priv *priv = ieee80211_priv(dev);
106 return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
109 static int r8192_wx_set_power(struct net_device *dev,
110 struct iw_request_info *info,
111 union iwreq_data *wrqu, char *extra)
114 struct r8192_priv *priv = ieee80211_priv(dev);
118 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
125 static int r8192_wx_get_power(struct net_device *dev,
126 struct iw_request_info *info,
127 union iwreq_data *wrqu, char *extra)
129 struct r8192_priv *priv = ieee80211_priv(dev);
131 return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
134 static int r8192_wx_force_reset(struct net_device *dev,
135 struct iw_request_info *info,
136 union iwreq_data *wrqu, char *extra)
138 struct r8192_priv *priv = ieee80211_priv(dev);
142 printk("%s(): force reset ! extra is %d\n", __func__, *extra);
143 priv->force_reset = *extra;
150 static int r8192_wx_set_rawtx(struct net_device *dev,
151 struct iw_request_info *info,
152 union iwreq_data *wrqu, char *extra)
154 struct r8192_priv *priv = ieee80211_priv(dev);
159 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
167 static int r8192_wx_set_crcmon(struct net_device *dev,
168 struct iw_request_info *info,
169 union iwreq_data *wrqu, char *extra)
171 struct r8192_priv *priv = ieee80211_priv(dev);
172 int *parms = (int *)extra;
173 int enable = (parms[0] > 0);
174 short prev = priv->crcmon;
183 DMESG("bad CRC in monitor mode are %s",
184 priv->crcmon ? "accepted" : "rejected");
186 if (prev != priv->crcmon && priv->up) {
187 /* rtl8180_down(dev); */
188 /* rtl8180_up(dev); */
196 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
197 union iwreq_data *wrqu, char *b)
199 struct r8192_priv *priv = ieee80211_priv(dev);
204 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
206 rtl8192_set_rxconf(dev);
212 struct iw_range_with_scan_capa {
213 /* Informative stuff (to choose between different interface) */
214 __u32 throughput; /* To give an idea... */
215 /* In theory this value should be the maximum benchmarked
216 * TCP/IP throughput, because with most of these devices the
217 * bit rate is meaningless (overhead an co) to estimate how
218 * fast the connection will go and pick the fastest one.
219 * I suggest people to play with Netperf or any benchmark...
222 /* NWID (or domain id) */
223 __u32 min_nwid; /* Minimal NWID we are able to set */
224 __u32 max_nwid; /* Maximal NWID we are able to set */
226 /* Old Frequency (backward compat - moved lower ) */
227 __u16 old_num_channels;
228 __u8 old_num_frequency;
230 /* Scan capabilities */
233 static int rtl8180_wx_get_range(struct net_device *dev,
234 struct iw_request_info *info,
235 union iwreq_data *wrqu, char *extra)
237 struct iw_range *range = (struct iw_range *)extra;
238 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
239 struct r8192_priv *priv = ieee80211_priv(dev);
243 wrqu->data.length = sizeof(*range);
244 memset(range, 0, sizeof(*range));
246 /* Let's try to keep this struct in the same order as in
247 * linux/include/wireless.h
250 /* TODO: See what values we can set, and remove the ones we can't
251 * set, or fill them with some default data.
254 /* ~5 Mb/s real (802.11b) */
255 range->throughput = 5 * 1000 * 1000;
257 /* TODO: Not used in 802.11b? */
258 /* range->min_nwid; */ /* Minimal NWID we are able to set */
259 /* TODO: Not used in 802.11b? */
260 /* range->max_nwid; */ /* Maximal NWID we are able to set */
262 /* Old Frequency (backward compat - moved lower ) */
263 /* range->old_num_channels; */
264 /* range->old_num_frequency; */
265 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
266 if (priv->rf_set_sens != NULL)
267 range->sensitivity = priv->max_sens; /* signal level threshold range */
269 range->max_qual.qual = 100;
270 /* TODO: Find real max RSSI and stick here */
271 range->max_qual.level = 0;
272 range->max_qual.noise = -98;
273 range->max_qual.updated = 7; /* Updated all three */
275 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
276 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
277 range->avg_qual.level = 20 + -98;
278 range->avg_qual.noise = 0;
279 range->avg_qual.updated = 7; /* Updated all three */
281 range->num_bitrates = RATE_COUNT;
283 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
284 range->bitrate[i] = rtl8180_rates[i];
286 range->min_frag = MIN_FRAG_THRESHOLD;
287 range->max_frag = MAX_FRAG_THRESHOLD;
290 range->max_pmp = 5000000;
292 range->max_pmt = 65535*1000;
293 range->pmp_flags = IW_POWER_PERIOD;
294 range->pmt_flags = IW_POWER_TIMEOUT;
295 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
297 range->we_version_compiled = WIRELESS_EXT;
298 range->we_version_source = 16;
300 /* range->retry_capa; */ /* What retry options are supported */
301 /* range->retry_flags; */ /* How to decode max/min retry limit */
302 /* range->r_time_flags; */ /* How to decode max/min retry life */
303 /* range->min_retry; */ /* Minimal number of retries */
304 /* range->max_retry; */ /* Maximal number of retries */
305 /* range->min_r_time; */ /* Minimal retry lifetime */
306 /* range->max_r_time; */ /* Maximal retry lifetime */
309 for (i = 0, val = 0; i < 14; i++) {
311 /* Include only legal frequencies for some countries */
312 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
313 range->freq[val].i = i + 1;
314 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
315 range->freq[val].e = 1;
318 /* FIXME: do we need to set anything for channels */
322 if (val == IW_MAX_FREQUENCIES)
325 range->num_frequency = val;
326 range->num_channels = val;
327 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
328 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
329 tmp->scan_capa = 0x01;
334 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
335 union iwreq_data *wrqu, char *b)
337 struct r8192_priv *priv = ieee80211_priv(dev);
338 struct ieee80211_device *ieee = priv->ieee80211;
344 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
346 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
347 struct iw_scan_req *req = (struct iw_scan_req *)b;
349 if (req->essid_len) {
350 ieee->current_network.ssid_len = req->essid_len;
351 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
356 if (priv->ieee80211->state != IEEE80211_LINKED) {
357 priv->ieee80211->scanning = 0;
358 ieee80211_softmac_scan_syncro(priv->ieee80211);
361 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
368 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
369 union iwreq_data *wrqu, char *b)
373 struct r8192_priv *priv = ieee80211_priv(dev);
380 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
387 static int r8192_wx_set_essid(struct net_device *dev,
388 struct iw_request_info *a,
389 union iwreq_data *wrqu, char *b)
391 struct r8192_priv *priv = ieee80211_priv(dev);
396 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
406 static int r8192_wx_get_essid(struct net_device *dev,
407 struct iw_request_info *a,
408 union iwreq_data *wrqu, char *b)
411 struct r8192_priv *priv = ieee80211_priv(dev);
415 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
423 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
424 union iwreq_data *wrqu, char *b)
427 struct r8192_priv *priv = ieee80211_priv(dev);
431 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
437 static int r8192_wx_get_name(struct net_device *dev,
438 struct iw_request_info *info,
439 union iwreq_data *wrqu, char *extra)
441 struct r8192_priv *priv = ieee80211_priv(dev);
443 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
447 static int r8192_wx_set_frag(struct net_device *dev,
448 struct iw_request_info *info,
449 union iwreq_data *wrqu, char *extra)
451 struct r8192_priv *priv = ieee80211_priv(dev);
453 if (wrqu->frag.disabled)
454 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
456 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
457 wrqu->frag.value > MAX_FRAG_THRESHOLD)
460 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
467 static int r8192_wx_get_frag(struct net_device *dev,
468 struct iw_request_info *info,
469 union iwreq_data *wrqu, char *extra)
471 struct r8192_priv *priv = ieee80211_priv(dev);
473 wrqu->frag.value = priv->ieee80211->fts;
474 wrqu->frag.fixed = 0; /* no auto select */
475 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
481 static int r8192_wx_set_wap(struct net_device *dev,
482 struct iw_request_info *info,
483 union iwreq_data *awrq,
488 struct r8192_priv *priv = ieee80211_priv(dev);
489 /* struct sockaddr *temp = (struct sockaddr *)awrq; */
492 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
501 static int r8192_wx_get_wap(struct net_device *dev,
502 struct iw_request_info *info,
503 union iwreq_data *wrqu, char *extra)
505 struct r8192_priv *priv = ieee80211_priv(dev);
507 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
511 static int r8192_wx_get_enc(struct net_device *dev,
512 struct iw_request_info *info,
513 union iwreq_data *wrqu, char *key)
515 struct r8192_priv *priv = ieee80211_priv(dev);
517 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
520 static int r8192_wx_set_enc(struct net_device *dev,
521 struct iw_request_info *info,
522 union iwreq_data *wrqu, char *key)
524 struct r8192_priv *priv = ieee80211_priv(dev);
525 struct ieee80211_device *ieee = priv->ieee80211;
527 u32 hwkey[4] = {0, 0, 0, 0};
530 u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
531 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
532 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
533 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
541 RT_TRACE(COMP_SEC, "Setting SW wep key");
542 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
548 /* sometimes, the length is zero while we do not type key value */
549 if (wrqu->encoding.length != 0) {
551 for (i = 0; i < 4; i++) {
552 hwkey[i] |= key[4*i+0]&mask;
553 if (i == 1 && (4*i+1) == wrqu->encoding.length)
555 if (i == 3 && (4*i+1) == wrqu->encoding.length)
557 hwkey[i] |= (key[4*i+1]&mask)<<8;
558 hwkey[i] |= (key[4*i+2]&mask)<<16;
559 hwkey[i] |= (key[4*i+3]&mask)<<24;
562 #define CONF_WEP40 0x4
563 #define CONF_WEP104 0x14
565 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
567 key_idx = ieee->tx_keyidx;
585 if (wrqu->encoding.length == 0x5) {
586 ieee->pairwise_key_type = KEY_TYPE_WEP40;
587 EnableHWSecurityConfig8192(dev);
590 key_idx, /* EntryNo */
591 key_idx, /* KeyIndex */
592 KEY_TYPE_WEP40, /* KeyType */
595 hwkey); /* KeyContent */
599 else if (wrqu->encoding.length == 0xd) {
600 ieee->pairwise_key_type = KEY_TYPE_WEP104;
601 EnableHWSecurityConfig8192(dev);
604 key_idx, /* EntryNo */
605 key_idx, /* KeyIndex */
606 KEY_TYPE_WEP104, /* KeyType */
609 hwkey); /* KeyContent */
612 printk("wrong type in WEP, not WEP40 and WEP104\n");
621 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
622 union iwreq_data *wrqu, char *p)
625 struct r8192_priv *priv = ieee80211_priv(dev);
626 int *parms = (int *)p;
629 priv->ieee80211->active_scan = mode;
636 static int r8192_wx_set_retry(struct net_device *dev,
637 struct iw_request_info *info,
638 union iwreq_data *wrqu, char *extra)
640 struct r8192_priv *priv = ieee80211_priv(dev);
645 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
646 wrqu->retry.disabled){
650 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
655 if (wrqu->retry.value > R8180_MAX_RETRY) {
659 if (wrqu->retry.flags & IW_RETRY_MAX) {
660 priv->retry_rts = wrqu->retry.value;
661 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
664 priv->retry_data = wrqu->retry.value;
665 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
669 * We might try to write directly the TX config register
670 * or to restart just the (R)TX process.
671 * I'm unsure if whole reset is really needed
681 static int r8192_wx_get_retry(struct net_device *dev,
682 struct iw_request_info *info,
683 union iwreq_data *wrqu, char *extra)
685 struct r8192_priv *priv = ieee80211_priv(dev);
688 wrqu->retry.disabled = 0; /* can't be disabled */
690 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
694 if (wrqu->retry.flags & IW_RETRY_MAX) {
695 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
696 wrqu->retry.value = priv->retry_rts;
698 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
699 wrqu->retry.value = priv->retry_data;
706 static int r8192_wx_get_sens(struct net_device *dev,
707 struct iw_request_info *info,
708 union iwreq_data *wrqu, char *extra)
710 struct r8192_priv *priv = ieee80211_priv(dev);
712 if (priv->rf_set_sens == NULL)
713 return -1; /* we have not this support for this radio */
714 wrqu->sens.value = priv->sens;
719 static int r8192_wx_set_sens(struct net_device *dev,
720 struct iw_request_info *info,
721 union iwreq_data *wrqu, char *extra)
724 struct r8192_priv *priv = ieee80211_priv(dev);
728 if (priv->rf_set_sens == NULL) {
729 err = -1; /* we have not this support for this radio */
732 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
733 priv->sens = wrqu->sens.value;
743 /* hw security need to reorganized. */
744 static int r8192_wx_set_enc_ext(struct net_device *dev,
745 struct iw_request_info *info,
746 union iwreq_data *wrqu, char *extra)
749 struct r8192_priv *priv = ieee80211_priv(dev);
750 struct ieee80211_device *ieee = priv->ieee80211;
754 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
757 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
760 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
761 struct iw_point *encoding = &wrqu->encoding;
762 u8 idx = 0, alg = 0, group = 0;
764 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
765 /* none is not allowed to use hwsec WB 2008.07.01 */
768 /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
769 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
770 idx = encoding->flags & IW_ENCODE_INDEX;
773 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
775 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) {
776 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
777 alg = KEY_TYPE_WEP104;
778 ieee->pairwise_key_type = alg;
779 EnableHWSecurityConfig8192(dev);
781 memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
783 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
791 key); /* KeyContent */
793 ieee->group_key_type = alg;
798 broadcast_addr, /* MacAddr */
800 key); /* KeyContent */
801 } else { /* pairwise key */
806 (u8 *)ieee->ap_mac_addr,/* MacAddr */
808 key); /* KeyContent */
820 static int r8192_wx_set_auth(struct net_device *dev,
821 struct iw_request_info *info,
822 union iwreq_data *data, char *extra)
825 struct r8192_priv *priv = ieee80211_priv(dev);
828 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
833 static int r8192_wx_set_mlme(struct net_device *dev,
834 struct iw_request_info *info,
835 union iwreq_data *wrqu, char *extra)
839 struct r8192_priv *priv = ieee80211_priv(dev);
842 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
848 static int r8192_wx_set_gen_ie(struct net_device *dev,
849 struct iw_request_info *info,
850 union iwreq_data *data, char *extra)
853 struct r8192_priv *priv = ieee80211_priv(dev);
856 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
863 static int dummy(struct net_device *dev, struct iw_request_info *a,
864 union iwreq_data *wrqu, char *b)
870 static iw_handler r8192_wx_handlers[] = {
871 NULL, /* SIOCSIWCOMMIT */
872 r8192_wx_get_name, /* SIOCGIWNAME */
873 dummy, /* SIOCSIWNWID */
874 dummy, /* SIOCGIWNWID */
875 r8192_wx_set_freq, /* SIOCSIWFREQ */
876 r8192_wx_get_freq, /* SIOCGIWFREQ */
877 r8192_wx_set_mode, /* SIOCSIWMODE */
878 r8192_wx_get_mode, /* SIOCGIWMODE */
879 r8192_wx_set_sens, /* SIOCSIWSENS */
880 r8192_wx_get_sens, /* SIOCGIWSENS */
881 NULL, /* SIOCSIWRANGE */
882 rtl8180_wx_get_range, /* SIOCGIWRANGE */
883 NULL, /* SIOCSIWPRIV */
884 NULL, /* SIOCGIWPRIV */
885 NULL, /* SIOCSIWSTATS */
886 NULL, /* SIOCGIWSTATS */
887 dummy, /* SIOCSIWSPY */
888 dummy, /* SIOCGIWSPY */
889 NULL, /* SIOCGIWTHRSPY */
890 NULL, /* SIOCWIWTHRSPY */
891 r8192_wx_set_wap, /* SIOCSIWAP */
892 r8192_wx_get_wap, /* SIOCGIWAP */
893 r8192_wx_set_mlme, /* MLME-- */
894 dummy, /* SIOCGIWAPLIST -- deprecated */
895 r8192_wx_set_scan, /* SIOCSIWSCAN */
896 r8192_wx_get_scan, /* SIOCGIWSCAN */
897 r8192_wx_set_essid, /* SIOCSIWESSID */
898 r8192_wx_get_essid, /* SIOCGIWESSID */
899 dummy, /* SIOCSIWNICKN */
900 dummy, /* SIOCGIWNICKN */
901 NULL, /* -- hole -- */
902 NULL, /* -- hole -- */
903 r8192_wx_set_rate, /* SIOCSIWRATE */
904 r8192_wx_get_rate, /* SIOCGIWRATE */
905 r8192_wx_set_rts, /* SIOCSIWRTS */
906 r8192_wx_get_rts, /* SIOCGIWRTS */
907 r8192_wx_set_frag, /* SIOCSIWFRAG */
908 r8192_wx_get_frag, /* SIOCGIWFRAG */
909 dummy, /* SIOCSIWTXPOW */
910 dummy, /* SIOCGIWTXPOW */
911 r8192_wx_set_retry, /* SIOCSIWRETRY */
912 r8192_wx_get_retry, /* SIOCGIWRETRY */
913 r8192_wx_set_enc, /* SIOCSIWENCODE */
914 r8192_wx_get_enc, /* SIOCGIWENCODE */
915 r8192_wx_set_power, /* SIOCSIWPOWER */
916 r8192_wx_get_power, /* SIOCGIWPOWER */
919 r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */
920 NULL, /* SIOCSIWGENIE */
922 r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */
923 NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */
924 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
925 NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */
926 NULL, /* SIOCSIWPMKSA */
932 static const struct iw_priv_args r8192_private_args[] = {
935 SIOCIWFIRSTPRIV + 0x0,
936 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
940 SIOCIWFIRSTPRIV + 0x1,
941 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
945 SIOCIWFIRSTPRIV + 0x2,
946 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
949 SIOCIWFIRSTPRIV + 0x3,
950 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
957 static iw_handler r8192_private_handler[] = {
959 r8192_wx_set_scan_type,
961 r8192_wx_force_reset,
964 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
966 struct r8192_priv *priv = ieee80211_priv(dev);
967 struct ieee80211_device *ieee = priv->ieee80211;
968 struct iw_statistics *wstats = &priv->wstats;
973 if (ieee->state < IEEE80211_LINKED) {
974 wstats->qual.qual = 0;
975 wstats->qual.level = 0;
976 wstats->qual.noise = 0;
977 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
981 tmp_level = (&ieee->current_network)->stats.rssi;
982 tmp_qual = (&ieee->current_network)->stats.signal;
983 tmp_noise = (&ieee->current_network)->stats.noise;
985 wstats->qual.level = tmp_level;
986 wstats->qual.qual = tmp_qual;
987 wstats->qual.noise = tmp_noise;
988 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
993 struct iw_handler_def r8192_wx_handlers_def = {
994 .standard = r8192_wx_handlers,
995 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
996 .private = r8192_private_handler,
997 .num_private = ARRAY_SIZE(r8192_private_handler),
998 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
999 .get_wireless_stats = r8192_get_wireless_stats,
1000 .private_args = (struct iw_priv_args *)r8192_private_args,