1 /******************************************************************************
3 * This file contains wireless extension handlers.
5 * This is part of rtl8180 OpenSource driver.
6 * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
7 * Released under the terms of GPL (General Public Licence)
9 * Parts of this driver are based on the GPL part
10 * of the official realtek driver.
12 * Parts of this driver are based on the rtl8180 driver skeleton
13 * from Patric Schenke & Andres Salomon.
15 * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
17 * We want to thank the Authors of those projects and the Ndiswrapper
20 *****************************************************************************/
22 #include <linux/string.h>
24 #include "r8192U_hw.h"
27 #include "r8192U_wx.h"
30 static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
31 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
38 static int r8192_wx_get_freq(struct net_device *dev,
39 struct iw_request_info *a,
40 union iwreq_data *wrqu, char *b)
42 struct r8192_priv *priv = ieee80211_priv(dev);
44 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
48 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
49 union iwreq_data *wrqu, char *b)
51 struct r8192_priv *priv = ieee80211_priv(dev);
53 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
58 static int r8192_wx_get_rate(struct net_device *dev,
59 struct iw_request_info *info,
60 union iwreq_data *wrqu, char *extra)
62 struct r8192_priv *priv = ieee80211_priv(dev);
64 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
69 static int r8192_wx_set_rate(struct net_device *dev,
70 struct iw_request_info *info,
71 union iwreq_data *wrqu, char *extra)
74 struct r8192_priv *priv = ieee80211_priv(dev);
78 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
86 static int r8192_wx_set_rts(struct net_device *dev,
87 struct iw_request_info *info,
88 union iwreq_data *wrqu, char *extra)
91 struct r8192_priv *priv = ieee80211_priv(dev);
95 ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
102 static int r8192_wx_get_rts(struct net_device *dev,
103 struct iw_request_info *info,
104 union iwreq_data *wrqu, char *extra)
106 struct r8192_priv *priv = ieee80211_priv(dev);
108 return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
111 static int r8192_wx_set_power(struct net_device *dev,
112 struct iw_request_info *info,
113 union iwreq_data *wrqu, char *extra)
116 struct r8192_priv *priv = ieee80211_priv(dev);
120 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
127 static int r8192_wx_get_power(struct net_device *dev,
128 struct iw_request_info *info,
129 union iwreq_data *wrqu, char *extra)
131 struct r8192_priv *priv = ieee80211_priv(dev);
133 return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
136 static int r8192_wx_force_reset(struct net_device *dev,
137 struct iw_request_info *info,
138 union iwreq_data *wrqu, char *extra)
140 struct r8192_priv *priv = ieee80211_priv(dev);
144 netdev_dbg(dev, "%s(): force reset ! extra is %d\n", __func__, *extra);
145 priv->force_reset = *extra;
152 static int r8192_wx_set_rawtx(struct net_device *dev,
153 struct iw_request_info *info,
154 union iwreq_data *wrqu, char *extra)
156 struct r8192_priv *priv = ieee80211_priv(dev);
161 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
169 static int r8192_wx_set_crcmon(struct net_device *dev,
170 struct iw_request_info *info,
171 union iwreq_data *wrqu, char *extra)
173 struct r8192_priv *priv = ieee80211_priv(dev);
174 int *parms = (int *)extra;
175 int enable = (parms[0] > 0);
184 DMESG("bad CRC in monitor mode are %s",
185 priv->crcmon ? "accepted" : "rejected");
192 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
193 union iwreq_data *wrqu, char *b)
195 struct r8192_priv *priv = ieee80211_priv(dev);
200 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
202 rtl8192_set_rxconf(dev);
208 struct iw_range_with_scan_capa {
209 /* Informative stuff (to choose between different interface) */
210 __u32 throughput; /* To give an idea... */
211 /* In theory this value should be the maximum benchmarked
212 * TCP/IP throughput, because with most of these devices the
213 * bit rate is meaningless (overhead an co) to estimate how
214 * fast the connection will go and pick the fastest one.
215 * I suggest people to play with Netperf or any benchmark...
218 /* NWID (or domain id) */
219 __u32 min_nwid; /* Minimal NWID we are able to set */
220 __u32 max_nwid; /* Maximal NWID we are able to set */
222 /* Old Frequency (backward compat - moved lower ) */
223 __u16 old_num_channels;
224 __u8 old_num_frequency;
226 /* Scan capabilities */
229 static int rtl8180_wx_get_range(struct net_device *dev,
230 struct iw_request_info *info,
231 union iwreq_data *wrqu, char *extra)
233 struct iw_range *range = (struct iw_range *)extra;
234 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
235 struct r8192_priv *priv = ieee80211_priv(dev);
239 wrqu->data.length = sizeof(*range);
240 memset(range, 0, sizeof(*range));
242 /* Let's try to keep this struct in the same order as in
243 * linux/include/wireless.h
246 /* TODO: See what values we can set, and remove the ones we can't
247 * set, or fill them with some default data.
250 /* ~5 Mb/s real (802.11b) */
251 range->throughput = 5 * 1000 * 1000;
253 /* TODO: Not used in 802.11b? */
254 /* range->min_nwid; */ /* Minimal NWID we are able to set */
255 /* TODO: Not used in 802.11b? */
256 /* range->max_nwid; */ /* Maximal NWID we are able to set */
258 /* Old Frequency (backward compat - moved lower ) */
259 /* range->old_num_channels; */
260 /* range->old_num_frequency; */
261 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
262 if (priv->rf_set_sens != NULL)
263 range->sensitivity = priv->max_sens; /* signal level threshold range */
265 range->max_qual.qual = 100;
266 /* TODO: Find real max RSSI and stick here */
267 range->max_qual.level = 0;
268 range->max_qual.noise = 0x100 - 98;
269 range->max_qual.updated = 7; /* Updated all three */
271 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
272 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
273 range->avg_qual.level = 0x100 - 78;
274 range->avg_qual.noise = 0;
275 range->avg_qual.updated = 7; /* Updated all three */
277 range->num_bitrates = RATE_COUNT;
279 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
280 range->bitrate[i] = rtl8180_rates[i];
282 range->min_frag = MIN_FRAG_THRESHOLD;
283 range->max_frag = MAX_FRAG_THRESHOLD;
286 range->max_pmp = 5000000;
288 range->max_pmt = 65535*1000;
289 range->pmp_flags = IW_POWER_PERIOD;
290 range->pmt_flags = IW_POWER_TIMEOUT;
291 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
293 range->we_version_compiled = WIRELESS_EXT;
294 range->we_version_source = 16;
296 /* range->retry_capa; */ /* What retry options are supported */
297 /* range->retry_flags; */ /* How to decode max/min retry limit */
298 /* range->r_time_flags; */ /* How to decode max/min retry life */
299 /* range->min_retry; */ /* Minimal number of retries */
300 /* range->max_retry; */ /* Maximal number of retries */
301 /* range->min_r_time; */ /* Minimal retry lifetime */
302 /* range->max_r_time; */ /* Maximal retry lifetime */
305 for (i = 0, val = 0; i < 14; i++) {
307 /* Include only legal frequencies for some countries */
308 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
309 range->freq[val].i = i + 1;
310 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
311 range->freq[val].e = 1;
314 /* FIXME: do we need to set anything for channels */
318 if (val == IW_MAX_FREQUENCIES)
321 range->num_frequency = val;
322 range->num_channels = val;
323 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
324 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
325 tmp->scan_capa = 0x01;
330 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
331 union iwreq_data *wrqu, char *b)
333 struct r8192_priv *priv = ieee80211_priv(dev);
334 struct ieee80211_device *ieee = priv->ieee80211;
340 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic)
342 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
343 struct iw_scan_req *req = (struct iw_scan_req *)b;
345 if (req->essid_len) {
346 ieee->current_network.ssid_len = req->essid_len;
347 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
352 if (priv->ieee80211->state != IEEE80211_LINKED) {
353 priv->ieee80211->scanning = 0;
354 ieee80211_softmac_scan_syncro(priv->ieee80211);
357 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
364 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
365 union iwreq_data *wrqu, char *b)
369 struct r8192_priv *priv = ieee80211_priv(dev);
376 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
383 static int r8192_wx_set_essid(struct net_device *dev,
384 struct iw_request_info *a,
385 union iwreq_data *wrqu, char *b)
387 struct r8192_priv *priv = ieee80211_priv(dev);
392 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
402 static int r8192_wx_get_essid(struct net_device *dev,
403 struct iw_request_info *a,
404 union iwreq_data *wrqu, char *b)
407 struct r8192_priv *priv = ieee80211_priv(dev);
411 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
419 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
420 union iwreq_data *wrqu, char *b)
423 struct r8192_priv *priv = ieee80211_priv(dev);
427 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
433 static int r8192_wx_get_name(struct net_device *dev,
434 struct iw_request_info *info,
435 union iwreq_data *wrqu, char *extra)
437 struct r8192_priv *priv = ieee80211_priv(dev);
439 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
443 static int r8192_wx_set_frag(struct net_device *dev,
444 struct iw_request_info *info,
445 union iwreq_data *wrqu, char *extra)
447 struct r8192_priv *priv = ieee80211_priv(dev);
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 r8192_wx_get_frag(struct net_device *dev,
464 struct iw_request_info *info,
465 union iwreq_data *wrqu, char *extra)
467 struct r8192_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 r8192_wx_set_wap(struct net_device *dev,
478 struct iw_request_info *info,
479 union iwreq_data *awrq,
484 struct r8192_priv *priv = ieee80211_priv(dev);
485 /* struct sockaddr *temp = (struct sockaddr *)awrq; */
488 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
497 static int r8192_wx_get_wap(struct net_device *dev,
498 struct iw_request_info *info,
499 union iwreq_data *wrqu, char *extra)
501 struct r8192_priv *priv = ieee80211_priv(dev);
503 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
507 static int r8192_wx_get_enc(struct net_device *dev,
508 struct iw_request_info *info,
509 union iwreq_data *wrqu, char *key)
511 struct r8192_priv *priv = ieee80211_priv(dev);
513 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
516 static int r8192_wx_set_enc(struct net_device *dev,
517 struct iw_request_info *info,
518 union iwreq_data *wrqu, char *key)
520 struct r8192_priv *priv = ieee80211_priv(dev);
521 struct ieee80211_device *ieee = priv->ieee80211;
523 u32 hwkey[4] = {0, 0, 0, 0};
526 u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
527 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
528 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
529 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
537 RT_TRACE(COMP_SEC, "Setting SW wep key");
538 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
544 /* sometimes, the length is zero while we do not type key value */
545 if (wrqu->encoding.length != 0) {
547 for (i = 0; i < 4; i++) {
548 hwkey[i] |= key[4*i+0]&mask;
549 if (i == 1 && (4*i+1) == wrqu->encoding.length)
551 if (i == 3 && (4*i+1) == wrqu->encoding.length)
553 hwkey[i] |= (key[4*i+1]&mask)<<8;
554 hwkey[i] |= (key[4*i+2]&mask)<<16;
555 hwkey[i] |= (key[4*i+3]&mask)<<24;
558 #define CONF_WEP40 0x4
559 #define CONF_WEP104 0x14
561 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
563 key_idx = ieee->tx_keyidx;
581 if (wrqu->encoding.length == 0x5) {
582 ieee->pairwise_key_type = KEY_TYPE_WEP40;
583 EnableHWSecurityConfig8192(dev);
586 key_idx, /* EntryNo */
587 key_idx, /* KeyIndex */
588 KEY_TYPE_WEP40, /* KeyType */
591 hwkey); /* KeyContent */
595 else if (wrqu->encoding.length == 0xd) {
596 ieee->pairwise_key_type = KEY_TYPE_WEP104;
597 EnableHWSecurityConfig8192(dev);
600 key_idx, /* EntryNo */
601 key_idx, /* KeyIndex */
602 KEY_TYPE_WEP104, /* KeyType */
605 hwkey); /* KeyContent */
608 printk("wrong type in WEP, not WEP40 and WEP104\n");
617 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
618 union iwreq_data *wrqu, char *p)
621 struct r8192_priv *priv = ieee80211_priv(dev);
622 int *parms = (int *)p;
625 priv->ieee80211->active_scan = mode;
632 static int r8192_wx_set_retry(struct net_device *dev,
633 struct iw_request_info *info,
634 union iwreq_data *wrqu, char *extra)
636 struct r8192_priv *priv = ieee80211_priv(dev);
641 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
642 wrqu->retry.disabled){
646 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
651 if (wrqu->retry.value > R8180_MAX_RETRY) {
655 if (wrqu->retry.flags & IW_RETRY_MAX) {
656 priv->retry_rts = wrqu->retry.value;
657 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
660 priv->retry_data = wrqu->retry.value;
661 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
665 * We might try to write directly the TX config register
666 * or to restart just the (R)TX process.
667 * I'm unsure if whole reset is really needed
677 static int r8192_wx_get_retry(struct net_device *dev,
678 struct iw_request_info *info,
679 union iwreq_data *wrqu, char *extra)
681 struct r8192_priv *priv = ieee80211_priv(dev);
684 wrqu->retry.disabled = 0; /* can't be disabled */
686 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
690 if (wrqu->retry.flags & IW_RETRY_MAX) {
691 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
692 wrqu->retry.value = priv->retry_rts;
694 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
695 wrqu->retry.value = priv->retry_data;
702 static int r8192_wx_get_sens(struct net_device *dev,
703 struct iw_request_info *info,
704 union iwreq_data *wrqu, char *extra)
706 struct r8192_priv *priv = ieee80211_priv(dev);
708 if (priv->rf_set_sens == NULL)
709 return -1; /* we have not this support for this radio */
710 wrqu->sens.value = priv->sens;
715 static int r8192_wx_set_sens(struct net_device *dev,
716 struct iw_request_info *info,
717 union iwreq_data *wrqu, char *extra)
720 struct r8192_priv *priv = ieee80211_priv(dev);
724 if (priv->rf_set_sens == NULL) {
725 err = -1; /* we have not this support for this radio */
728 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
729 priv->sens = wrqu->sens.value;
739 /* hw security need to reorganized. */
740 static int r8192_wx_set_enc_ext(struct net_device *dev,
741 struct iw_request_info *info,
742 union iwreq_data *wrqu, char *extra)
745 struct r8192_priv *priv = ieee80211_priv(dev);
746 struct ieee80211_device *ieee = priv->ieee80211;
750 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
753 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
756 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
757 struct iw_point *encoding = &wrqu->encoding;
758 u8 idx = 0, alg = 0, group = 0;
760 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
761 /* none is not allowed to use hwsec WB 2008.07.01 */
764 /* as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; */
765 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
766 idx = encoding->flags & IW_ENCODE_INDEX;
769 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
771 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) {
772 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
773 alg = KEY_TYPE_WEP104;
774 ieee->pairwise_key_type = alg;
775 EnableHWSecurityConfig8192(dev);
777 memcpy((u8 *)key, ext->key, 16); /* we only get 16 bytes key.why? WB 2008.7.1 */
779 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
787 key); /* KeyContent */
789 ieee->group_key_type = alg;
794 broadcast_addr, /* MacAddr */
796 key); /* KeyContent */
797 } else { /* pairwise key */
802 (u8 *)ieee->ap_mac_addr,/* MacAddr */
804 key); /* KeyContent */
816 static int r8192_wx_set_auth(struct net_device *dev,
817 struct iw_request_info *info,
818 union iwreq_data *data, char *extra)
821 struct r8192_priv *priv = ieee80211_priv(dev);
824 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
829 static int r8192_wx_set_mlme(struct net_device *dev,
830 struct iw_request_info *info,
831 union iwreq_data *wrqu, char *extra)
835 struct r8192_priv *priv = ieee80211_priv(dev);
838 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
844 static int r8192_wx_set_gen_ie(struct net_device *dev,
845 struct iw_request_info *info,
846 union iwreq_data *data, char *extra)
849 struct r8192_priv *priv = ieee80211_priv(dev);
852 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
859 static int dummy(struct net_device *dev, struct iw_request_info *a,
860 union iwreq_data *wrqu, char *b)
866 static iw_handler r8192_wx_handlers[] = {
867 NULL, /* SIOCSIWCOMMIT */
868 r8192_wx_get_name, /* SIOCGIWNAME */
869 dummy, /* SIOCSIWNWID */
870 dummy, /* SIOCGIWNWID */
871 r8192_wx_set_freq, /* SIOCSIWFREQ */
872 r8192_wx_get_freq, /* SIOCGIWFREQ */
873 r8192_wx_set_mode, /* SIOCSIWMODE */
874 r8192_wx_get_mode, /* SIOCGIWMODE */
875 r8192_wx_set_sens, /* SIOCSIWSENS */
876 r8192_wx_get_sens, /* SIOCGIWSENS */
877 NULL, /* SIOCSIWRANGE */
878 rtl8180_wx_get_range, /* SIOCGIWRANGE */
879 NULL, /* SIOCSIWPRIV */
880 NULL, /* SIOCGIWPRIV */
881 NULL, /* SIOCSIWSTATS */
882 NULL, /* SIOCGIWSTATS */
883 dummy, /* SIOCSIWSPY */
884 dummy, /* SIOCGIWSPY */
885 NULL, /* SIOCGIWTHRSPY */
886 NULL, /* SIOCWIWTHRSPY */
887 r8192_wx_set_wap, /* SIOCSIWAP */
888 r8192_wx_get_wap, /* SIOCGIWAP */
889 r8192_wx_set_mlme, /* MLME-- */
890 dummy, /* SIOCGIWAPLIST -- deprecated */
891 r8192_wx_set_scan, /* SIOCSIWSCAN */
892 r8192_wx_get_scan, /* SIOCGIWSCAN */
893 r8192_wx_set_essid, /* SIOCSIWESSID */
894 r8192_wx_get_essid, /* SIOCGIWESSID */
895 dummy, /* SIOCSIWNICKN */
896 dummy, /* SIOCGIWNICKN */
897 NULL, /* -- hole -- */
898 NULL, /* -- hole -- */
899 r8192_wx_set_rate, /* SIOCSIWRATE */
900 r8192_wx_get_rate, /* SIOCGIWRATE */
901 r8192_wx_set_rts, /* SIOCSIWRTS */
902 r8192_wx_get_rts, /* SIOCGIWRTS */
903 r8192_wx_set_frag, /* SIOCSIWFRAG */
904 r8192_wx_get_frag, /* SIOCGIWFRAG */
905 dummy, /* SIOCSIWTXPOW */
906 dummy, /* SIOCGIWTXPOW */
907 r8192_wx_set_retry, /* SIOCSIWRETRY */
908 r8192_wx_get_retry, /* SIOCGIWRETRY */
909 r8192_wx_set_enc, /* SIOCSIWENCODE */
910 r8192_wx_get_enc, /* SIOCGIWENCODE */
911 r8192_wx_set_power, /* SIOCSIWPOWER */
912 r8192_wx_get_power, /* SIOCGIWPOWER */
915 r8192_wx_set_gen_ie, /* NULL, */ /* SIOCSIWGENIE */
916 NULL, /* SIOCSIWGENIE */
918 r8192_wx_set_auth,/* NULL, */ /* SIOCSIWAUTH */
919 NULL,/* r8192_wx_get_auth, */ /* NULL, */ /* SIOCSIWAUTH */
920 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
921 NULL,/* r8192_wx_get_enc_ext, *//* NULL, */ /* SIOCSIWENCODEEXT */
922 NULL, /* SIOCSIWPMKSA */
928 static const struct iw_priv_args r8192_private_args[] = {
931 SIOCIWFIRSTPRIV + 0x0,
932 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
936 SIOCIWFIRSTPRIV + 0x1,
937 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
941 SIOCIWFIRSTPRIV + 0x2,
942 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
945 SIOCIWFIRSTPRIV + 0x3,
946 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
953 static iw_handler r8192_private_handler[] = {
955 r8192_wx_set_scan_type,
957 r8192_wx_force_reset,
960 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
962 struct r8192_priv *priv = ieee80211_priv(dev);
963 struct ieee80211_device *ieee = priv->ieee80211;
964 struct iw_statistics *wstats = &priv->wstats;
969 if (ieee->state < IEEE80211_LINKED) {
970 wstats->qual.qual = 0;
971 wstats->qual.level = 0;
972 wstats->qual.noise = 0;
973 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
977 tmp_level = (&ieee->current_network)->stats.rssi;
978 tmp_qual = (&ieee->current_network)->stats.signal;
979 tmp_noise = (&ieee->current_network)->stats.noise;
981 wstats->qual.level = tmp_level;
982 wstats->qual.qual = tmp_qual;
983 wstats->qual.noise = tmp_noise;
984 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
989 struct iw_handler_def r8192_wx_handlers_def = {
990 .standard = r8192_wx_handlers,
991 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
992 .private = r8192_private_handler,
993 .num_private = ARRAY_SIZE(r8192_private_handler),
994 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
995 .get_wireless_stats = r8192_get_wireless_stats,
996 .private_args = (struct iw_priv_args *)r8192_private_args,