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
,