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 tanks the Authors of those projects and the Ndiswrapper
20 #include <linux/string.h>
22 #include "r8192E_hw.h"
23 #include "r8192E_wx.h"
25 #include "ieee80211/dot11d.h"
29 static const u32 rtl8180_rates
[] = {1000000,2000000,5500000,11000000,
30 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
);
61 return ieee80211_wx_get_rate(priv
->ieee80211
,info
,wrqu
,extra
);
66 static int r8192_wx_set_rate(struct net_device
*dev
,
67 struct iw_request_info
*info
,
68 union iwreq_data
*wrqu
, char *extra
)
71 struct r8192_priv
*priv
= ieee80211_priv(dev
);
73 if (priv
->bHwRadioOff
)
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
);
93 if (priv
->bHwRadioOff
)
98 ret
= ieee80211_wx_set_rts(priv
->ieee80211
,info
,wrqu
,extra
);
105 static int r8192_wx_get_rts(struct net_device
*dev
,
106 struct iw_request_info
*info
,
107 union iwreq_data
*wrqu
, char *extra
)
109 struct r8192_priv
*priv
= ieee80211_priv(dev
);
110 return ieee80211_wx_get_rts(priv
->ieee80211
,info
,wrqu
,extra
);
113 static int r8192_wx_set_power(struct net_device
*dev
,
114 struct iw_request_info
*info
,
115 union iwreq_data
*wrqu
, char *extra
)
118 struct r8192_priv
*priv
= ieee80211_priv(dev
);
120 if (priv
->bHwRadioOff
)
125 ret
= ieee80211_wx_set_power(priv
->ieee80211
,info
,wrqu
,extra
);
132 static int r8192_wx_get_power(struct net_device
*dev
,
133 struct iw_request_info
*info
,
134 union iwreq_data
*wrqu
, char *extra
)
136 struct r8192_priv
*priv
= ieee80211_priv(dev
);
137 return ieee80211_wx_get_power(priv
->ieee80211
,info
,wrqu
,extra
);
140 static int r8192_wx_set_rawtx(struct net_device
*dev
,
141 struct iw_request_info
*info
,
142 union iwreq_data
*wrqu
, char *extra
)
144 struct r8192_priv
*priv
= ieee80211_priv(dev
);
147 if (priv
->bHwRadioOff
)
152 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
160 static int r8192_wx_force_reset(struct net_device
*dev
,
161 struct iw_request_info
*info
,
162 union iwreq_data
*wrqu
, char *extra
)
164 struct r8192_priv
*priv
= ieee80211_priv(dev
);
168 printk("%s(): force reset ! extra is %d\n",__FUNCTION__
, *extra
);
169 priv
->force_reset
= *extra
;
176 static int r8192_wx_set_crcmon(struct net_device
*dev
,
177 struct iw_request_info
*info
,
178 union iwreq_data
*wrqu
, char *extra
)
180 struct r8192_priv
*priv
= ieee80211_priv(dev
);
181 int *parms
= (int *)extra
;
182 int enable
= (parms
[0] > 0);
183 short prev
= priv
->crcmon
;
185 if (priv
->bHwRadioOff
)
195 DMESG("bad CRC in monitor mode are %s",
196 priv
->crcmon
? "accepted" : "rejected");
198 if(prev
!= priv
->crcmon
&& priv
->up
){
208 static int r8192_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
209 union iwreq_data
*wrqu
, char *b
)
211 struct r8192_priv
*priv
= ieee80211_priv(dev
);
212 RT_RF_POWER_STATE rtState
;
215 if (priv
->bHwRadioOff
)
218 rtState
= priv
->eRFPowerState
;
221 if(wrqu
->mode
== IW_MODE_ADHOC
){
223 if (priv
->PowerSaveControl
.bInactivePs
) {
224 if(rtState
== eRfOff
){
225 if(priv
->RfOffReason
> RF_CHANGE_BY_IPS
)
227 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
232 RT_TRACE(COMP_ERR
, "%s(): IPSLeave\n",__FUNCTION__
);
233 down(&priv
->ieee80211
->ips_sem
);
235 up(&priv
->ieee80211
->ips_sem
);
241 ret
= ieee80211_wx_set_mode(priv
->ieee80211
,a
,wrqu
,b
);
243 //rtl8187_set_rxconf(dev);
249 struct iw_range_with_scan_capa
251 /* Informative stuff (to choose between different interface) */
252 __u32 throughput
; /* To give an idea... */
253 /* In theory this value should be the maximum benchmarked
254 * TCP/IP throughput, because with most of these devices the
255 * bit rate is meaningless (overhead an co) to estimate how
256 * fast the connection will go and pick the fastest one.
257 * I suggest people to play with Netperf or any benchmark...
260 /* NWID (or domain id) */
261 __u32 min_nwid
; /* Minimal NWID we are able to set */
262 __u32 max_nwid
; /* Maximal NWID we are able to set */
264 /* Old Frequency (backward compat - moved lower ) */
265 __u16 old_num_channels
;
266 __u8 old_num_frequency
;
268 /* Scan capabilities */
271 static int rtl8180_wx_get_range(struct net_device
*dev
,
272 struct iw_request_info
*info
,
273 union iwreq_data
*wrqu
, char *extra
)
275 struct iw_range
*range
= (struct iw_range
*)extra
;
276 struct iw_range_with_scan_capa
* tmp
= (struct iw_range_with_scan_capa
*)range
;
277 struct r8192_priv
*priv
= ieee80211_priv(dev
);
281 wrqu
->data
.length
= sizeof(*range
);
282 memset(range
, 0, sizeof(*range
));
284 /* Let's try to keep this struct in the same order as in
285 * linux/include/wireless.h
288 /* TODO: See what values we can set, and remove the ones we can't
289 * set, or fill them with some default data.
292 /* ~5 Mb/s real (802.11b) */
293 range
->throughput
= 130 * 1000 * 1000;
295 // TODO: Not used in 802.11b?
296 // range->min_nwid; /* Minimal NWID we are able to set */
297 // TODO: Not used in 802.11b?
298 // range->max_nwid; /* Maximal NWID we are able to set */
300 /* Old Frequency (backward compat - moved lower ) */
301 // range->old_num_channels;
302 // range->old_num_frequency;
303 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
305 range
->max_qual
.qual
= 100;
306 /* TODO: Find real max RSSI and stick here */
307 range
->max_qual
.level
= 0;
308 range
->max_qual
.noise
= -98;
309 range
->max_qual
.updated
= 7; /* Updated all three */
311 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
312 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
313 range
->avg_qual
.level
= 20 + -98;
314 range
->avg_qual
.noise
= 0;
315 range
->avg_qual
.updated
= 7; /* Updated all three */
317 range
->num_bitrates
= RATE_COUNT
;
319 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++) {
320 range
->bitrate
[i
] = rtl8180_rates
[i
];
323 range
->min_frag
= MIN_FRAG_THRESHOLD
;
324 range
->max_frag
= MAX_FRAG_THRESHOLD
;
327 range
->max_pmp
= 5000000;
329 range
->max_pmt
= 65535*1000;
330 range
->pmp_flags
= IW_POWER_PERIOD
;
331 range
->pmt_flags
= IW_POWER_TIMEOUT
;
332 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
333 range
->we_version_compiled
= WIRELESS_EXT
;
334 range
->we_version_source
= 18;
336 // range->retry_capa; /* What retry options are supported */
337 // range->retry_flags; /* How to decode max/min retry limit */
338 // range->r_time_flags; /* How to decode max/min retry life */
339 // range->min_retry; /* Minimal number of retries */
340 // range->max_retry; /* Maximal number of retries */
341 // range->min_r_time; /* Minimal retry lifetime */
342 // range->max_r_time; /* Maximal retry lifetime */
345 for (i
= 0, val
= 0; i
< 14; i
++) {
347 // Include only legal frequencies for some countries
349 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
351 if ((priv
->ieee80211
->channel_map
)[i
+1]) {
353 range
->freq
[val
].i
= i
+ 1;
354 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
355 range
->freq
[val
].e
= 1;
358 // FIXME: do we need to set anything for channels
362 if (val
== IW_MAX_FREQUENCIES
)
365 range
->num_frequency
= val
;
366 range
->num_channels
= val
;
368 range
->enc_capa
= IW_ENC_CAPA_WPA
|IW_ENC_CAPA_WPA2
|
369 IW_ENC_CAPA_CIPHER_TKIP
|IW_ENC_CAPA_CIPHER_CCMP
;
371 tmp
->scan_capa
= 0x01;
376 static int r8192_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
377 union iwreq_data
*wrqu
, char *b
)
379 struct r8192_priv
*priv
= ieee80211_priv(dev
);
380 struct ieee80211_device
* ieee
= priv
->ieee80211
;
381 RT_RF_POWER_STATE rtState
;
384 if (priv
->bHwRadioOff
)
387 rtState
= priv
->eRFPowerState
;
389 if(!priv
->up
) return -ENETDOWN
;
390 if (priv
->ieee80211
->LinkDetectInfo
.bBusyTraffic
== true)
393 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
)
395 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
398 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
399 ieee
->current_network
.ssid_len
= req
->essid_len
;
400 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
401 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
407 priv
->ieee80211
->actscanning
= true;
408 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
409 if (priv
->PowerSaveControl
.bInactivePs
) {
410 if(rtState
== eRfOff
){
411 if(priv
->RfOffReason
> RF_CHANGE_BY_IPS
)
413 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
418 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
419 down(&priv
->ieee80211
->ips_sem
);
421 up(&priv
->ieee80211
->ips_sem
);
425 priv
->ieee80211
->scanning
= 0;
426 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
432 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
433 priv
->ieee80211
->scanning
= 0;
434 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
439 ret
= ieee80211_wx_set_scan(priv
->ieee80211
,a
,wrqu
,b
);
446 static int r8192_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
447 union iwreq_data
*wrqu
, char *b
)
451 struct r8192_priv
*priv
= ieee80211_priv(dev
);
453 if (priv
->bHwRadioOff
)
456 if(!priv
->up
) return -ENETDOWN
;
460 ret
= ieee80211_wx_get_scan(priv
->ieee80211
,a
,wrqu
,b
);
467 static int r8192_wx_set_essid(struct net_device
*dev
,
468 struct iw_request_info
*a
,
469 union iwreq_data
*wrqu
, char *b
)
471 struct r8192_priv
*priv
= ieee80211_priv(dev
);
472 RT_RF_POWER_STATE rtState
;
475 if (priv
->bHwRadioOff
)
478 rtState
= priv
->eRFPowerState
;
482 down(&priv
->ieee80211
->ips_sem
);
484 up(&priv
->ieee80211
->ips_sem
);
486 ret
= ieee80211_wx_set_essid(priv
->ieee80211
,a
,wrqu
,b
);
496 static int r8192_wx_get_essid(struct net_device
*dev
,
497 struct iw_request_info
*a
,
498 union iwreq_data
*wrqu
, char *b
)
501 struct r8192_priv
*priv
= ieee80211_priv(dev
);
505 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
513 static int r8192_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
514 union iwreq_data
*wrqu
, char *b
)
517 struct r8192_priv
*priv
= ieee80211_priv(dev
);
519 if (priv
->bHwRadioOff
)
524 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
530 static int r8192_wx_get_name(struct net_device
*dev
,
531 struct iw_request_info
*info
,
532 union iwreq_data
*wrqu
, char *extra
)
534 struct r8192_priv
*priv
= ieee80211_priv(dev
);
535 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
539 static int r8192_wx_set_frag(struct net_device
*dev
,
540 struct iw_request_info
*info
,
541 union iwreq_data
*wrqu
, char *extra
)
543 struct r8192_priv
*priv
= ieee80211_priv(dev
);
545 if (priv
->bHwRadioOff
)
548 if (wrqu
->frag
.disabled
)
549 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
551 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
552 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
555 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
562 static int r8192_wx_get_frag(struct net_device
*dev
,
563 struct iw_request_info
*info
,
564 union iwreq_data
*wrqu
, char *extra
)
566 struct r8192_priv
*priv
= ieee80211_priv(dev
);
568 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
569 wrqu
->frag
.fixed
= 0; /* no auto select */
570 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
576 static int r8192_wx_set_wap(struct net_device
*dev
,
577 struct iw_request_info
*info
,
578 union iwreq_data
*awrq
,
583 struct r8192_priv
*priv
= ieee80211_priv(dev
);
584 // struct sockaddr *temp = (struct sockaddr *)awrq;
586 if (priv
->bHwRadioOff
)
592 down(&priv
->ieee80211
->ips_sem
);
594 up(&priv
->ieee80211
->ips_sem
);
596 ret
= ieee80211_wx_set_wap(priv
->ieee80211
,info
,awrq
,extra
);
605 static int r8192_wx_get_wap(struct net_device
*dev
,
606 struct iw_request_info
*info
,
607 union iwreq_data
*wrqu
, char *extra
)
609 struct r8192_priv
*priv
= ieee80211_priv(dev
);
611 return ieee80211_wx_get_wap(priv
->ieee80211
,info
,wrqu
,extra
);
615 static int r8192_wx_get_enc(struct net_device
*dev
,
616 struct iw_request_info
*info
,
617 union iwreq_data
*wrqu
, char *key
)
619 struct r8192_priv
*priv
= ieee80211_priv(dev
);
621 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
624 static int r8192_wx_set_enc(struct net_device
*dev
,
625 struct iw_request_info
*info
,
626 union iwreq_data
*wrqu
, char *key
)
628 struct r8192_priv
*priv
= ieee80211_priv(dev
);
631 struct ieee80211_device
*ieee
= priv
->ieee80211
;
633 u32 hwkey
[4]={0,0,0,0};
636 u8 zero_addr
[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
637 {0x00,0x00,0x00,0x00,0x00,0x01},
638 {0x00,0x00,0x00,0x00,0x00,0x02},
639 {0x00,0x00,0x00,0x00,0x00,0x03} };
642 if (priv
->bHwRadioOff
)
645 if(!priv
->up
) return -ENETDOWN
;
647 priv
->ieee80211
->wx_set_enc
= 1;
649 down(&priv
->ieee80211
->ips_sem
);
651 up(&priv
->ieee80211
->ips_sem
);
656 RT_TRACE(COMP_SEC
, "Setting SW wep key\n");
657 ret
= ieee80211_wx_set_encode(priv
->ieee80211
,info
,wrqu
,key
);
661 //sometimes, the length is zero while we do not type key value
662 if(wrqu
->encoding
.length
!=0){
664 for(i
=0 ; i
<4 ; i
++){
665 hwkey
[i
] |= key
[4*i
+0]&mask
;
666 if(i
==1&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
667 if(i
==3&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
668 hwkey
[i
] |= (key
[4*i
+1]&mask
)<<8;
669 hwkey
[i
] |= (key
[4*i
+2]&mask
)<<16;
670 hwkey
[i
] |= (key
[4*i
+3]&mask
)<<24;
673 #define CONF_WEP40 0x4
674 #define CONF_WEP104 0x14
676 switch(wrqu
->encoding
.flags
& IW_ENCODE_INDEX
){
677 case 0: key_idx
= ieee
->tx_keyidx
; break;
678 case 1: key_idx
= 0; break;
679 case 2: key_idx
= 1; break;
680 case 3: key_idx
= 2; break;
681 case 4: key_idx
= 3; break;
685 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
686 if(wrqu
->encoding
.length
==0x5){
687 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
688 EnableHWSecurityConfig8192(dev
);
692 KEY_TYPE_WEP40
, //KeyType
698 else if(wrqu
->encoding
.length
==0xd){
699 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
700 EnableHWSecurityConfig8192(dev
);
704 KEY_TYPE_WEP104
, //KeyType
709 else printk("wrong type in WEP, not WEP40 and WEP104\n");
712 priv
->ieee80211
->wx_set_enc
= 0;
718 static int r8192_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
719 iwreq_data
*wrqu
, char *p
){
721 struct r8192_priv
*priv
= ieee80211_priv(dev
);
725 priv
->ieee80211
->active_scan
= mode
;
732 static int r8192_wx_set_retry(struct net_device
*dev
,
733 struct iw_request_info
*info
,
734 union iwreq_data
*wrqu
, char *extra
)
736 struct r8192_priv
*priv
= ieee80211_priv(dev
);
739 if (priv
->bHwRadioOff
)
744 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
745 wrqu
->retry
.disabled
){
749 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)){
754 if(wrqu
->retry
.value
> R8180_MAX_RETRY
){
758 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
759 priv
->retry_rts
= wrqu
->retry
.value
;
760 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
763 priv
->retry_data
= wrqu
->retry
.value
;
764 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
768 * We might try to write directly the TX config register
769 * or to restart just the (R)TX process.
770 * I'm unsure if whole reset is really needed
773 rtl8192_commit(priv
);
776 rtl8180_rtx_disable(dev);
777 rtl8180_rx_enable(dev);
778 rtl8180_tx_enable(dev);
788 static int r8192_wx_get_retry(struct net_device
*dev
,
789 struct iw_request_info
*info
,
790 union iwreq_data
*wrqu
, char *extra
)
792 struct r8192_priv
*priv
= ieee80211_priv(dev
);
795 wrqu
->retry
.disabled
= 0; /* can't be disabled */
797 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
801 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
802 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MAX
;
803 wrqu
->retry
.value
= priv
->retry_rts
;
805 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MIN
;
806 wrqu
->retry
.value
= priv
->retry_data
;
808 //DMESG("returning %d",wrqu->retry.value);
814 static int r8192_wx_get_sens(struct net_device
*dev
,
815 struct iw_request_info
*info
,
816 union iwreq_data
*wrqu
, char *extra
)
818 struct r8192_priv
*priv
= ieee80211_priv(dev
);
819 if(priv
->rf_set_sens
== NULL
)
820 return -1; /* we have not this support for this radio */
821 wrqu
->sens
.value
= priv
->sens
;
826 static int r8192_wx_set_sens(struct net_device
*dev
,
827 struct iw_request_info
*info
,
828 union iwreq_data
*wrqu
, char *extra
)
831 struct r8192_priv
*priv
= ieee80211_priv(dev
);
835 if (priv
->bHwRadioOff
)
839 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
840 if(priv
->rf_set_sens
== NULL
) {
841 err
= -1; /* we have not this support for this radio */
844 if(priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
845 priv
->sens
= wrqu
->sens
.value
;
855 static int r8192_wx_set_enc_ext(struct net_device
*dev
,
856 struct iw_request_info
*info
,
857 union iwreq_data
*wrqu
, char *extra
)
860 struct r8192_priv
*priv
= ieee80211_priv(dev
);
861 struct ieee80211_device
* ieee
= priv
->ieee80211
;
863 if (priv
->bHwRadioOff
)
868 priv
->ieee80211
->wx_set_enc
= 1;
871 down(&priv
->ieee80211
->ips_sem
);
873 up(&priv
->ieee80211
->ips_sem
);
876 ret
= ieee80211_wx_set_encode_ext(ieee
, info
, wrqu
, extra
);
879 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
882 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
883 struct iw_point
*encoding
= &wrqu
->encoding
;
884 u8 idx
= 0, alg
= 0, group
= 0;
886 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
887 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
889 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
890 CamResetAllEntry(priv
);
893 alg
= (ext
->alg
== IW_ENCODE_ALG_CCMP
)?KEY_TYPE_CCMP
:ext
->alg
; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
894 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
897 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
899 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
901 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
902 alg
= KEY_TYPE_WEP104
;
903 ieee
->pairwise_key_type
= alg
;
904 EnableHWSecurityConfig8192(dev
);
906 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
908 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
910 if (ext
->key_len
== 13)
911 ieee
->pairwise_key_type
= alg
= KEY_TYPE_WEP104
;
922 ieee
->group_key_type
= alg
;
927 broadcast_addr
, //MacAddr
933 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
934 write_nic_byte(priv
, 0x173, 1); //fix aes bug
940 (u8
*)ieee
->ap_mac_addr
, //MacAddr
949 priv
->ieee80211
->wx_set_enc
= 0;
954 static int r8192_wx_set_auth(struct net_device
*dev
,
955 struct iw_request_info
*info
,
956 union iwreq_data
*data
, char *extra
)
959 //printk("====>%s()\n", __FUNCTION__);
960 struct r8192_priv
*priv
= ieee80211_priv(dev
);
962 if (priv
->bHwRadioOff
)
966 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
971 static int r8192_wx_set_mlme(struct net_device
*dev
,
972 struct iw_request_info
*info
,
973 union iwreq_data
*wrqu
, char *extra
)
975 //printk("====>%s()\n", __FUNCTION__);
978 struct r8192_priv
*priv
= ieee80211_priv(dev
);
980 if (priv
->bHwRadioOff
)
984 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
989 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
990 struct iw_request_info
*info
,
991 union iwreq_data
*data
, char *extra
)
993 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
995 struct r8192_priv
*priv
= ieee80211_priv(dev
);
997 if (priv
->bHwRadioOff
)
1000 down(&priv
->wx_sem
);
1001 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1003 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1007 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1008 union iwreq_data
*wrqu
,char *b
)
1013 // check ac/dc status with the help of user space application */
1014 static int r8192_wx_adapter_power_status(struct net_device
*dev
,
1015 struct iw_request_info
*info
,
1016 union iwreq_data
*wrqu
, char *extra
)
1018 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1020 PRT_POWER_SAVE_CONTROL pPSC
= &priv
->PowerSaveControl
;
1021 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1023 down(&priv
->wx_sem
);
1026 RT_TRACE(COMP_POWER
, "%s(): %s\n",__FUNCTION__
, (*extra
== 6)?"DC power":"AC power");
1027 // ieee->ps shall not be set under DC mode, otherwise it conflict
1028 // with Leisure power save mode setting.
1030 if(*extra
|| priv
->force_lps
) {
1031 priv
->ps_force
= false;
1032 pPSC
->bLeisurePs
= true;
1034 //LZM for PS-Poll AID issue. 090429
1035 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
1036 LeisurePSLeave(dev
);
1038 priv
->ps_force
= true;
1039 pPSC
->bLeisurePs
= false;
1050 static iw_handler r8192_wx_handlers
[] =
1052 NULL
, /* SIOCSIWCOMMIT */
1053 r8192_wx_get_name
, /* SIOCGIWNAME */
1054 dummy
, /* SIOCSIWNWID */
1055 dummy
, /* SIOCGIWNWID */
1056 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1057 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1058 r8192_wx_set_mode
, /* SIOCSIWMODE */
1059 r8192_wx_get_mode
, /* SIOCGIWMODE */
1060 r8192_wx_set_sens
, /* SIOCSIWSENS */
1061 r8192_wx_get_sens
, /* SIOCGIWSENS */
1062 NULL
, /* SIOCSIWRANGE */
1063 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1064 NULL
, /* SIOCSIWPRIV */
1065 NULL
, /* SIOCGIWPRIV */
1066 NULL
, /* SIOCSIWSTATS */
1067 NULL
, /* SIOCGIWSTATS */
1068 dummy
, /* SIOCSIWSPY */
1069 dummy
, /* SIOCGIWSPY */
1070 NULL
, /* SIOCGIWTHRSPY */
1071 NULL
, /* SIOCWIWTHRSPY */
1072 r8192_wx_set_wap
, /* SIOCSIWAP */
1073 r8192_wx_get_wap
, /* SIOCGIWAP */
1074 r8192_wx_set_mlme
, /* MLME-- */
1075 dummy
, /* SIOCGIWAPLIST -- depricated */
1076 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1077 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1078 r8192_wx_set_essid
, /* SIOCSIWESSID */
1079 r8192_wx_get_essid
, /* SIOCGIWESSID */
1080 dummy
, /* SIOCSIWNICKN */
1081 dummy
, /* SIOCGIWNICKN */
1082 NULL
, /* -- hole -- */
1083 NULL
, /* -- hole -- */
1084 r8192_wx_set_rate
, /* SIOCSIWRATE */
1085 r8192_wx_get_rate
, /* SIOCGIWRATE */
1086 r8192_wx_set_rts
, /* SIOCSIWRTS */
1087 r8192_wx_get_rts
, /* SIOCGIWRTS */
1088 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1089 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1090 dummy
, /* SIOCSIWTXPOW */
1091 dummy
, /* SIOCGIWTXPOW */
1092 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1093 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1094 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1095 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1096 r8192_wx_set_power
, /* SIOCSIWPOWER */
1097 r8192_wx_get_power
, /* SIOCGIWPOWER */
1098 NULL
, /*---hole---*/
1099 NULL
, /*---hole---*/
1100 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1101 NULL
, /* SIOCSIWGENIE */
1102 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1103 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1104 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1105 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1106 NULL
, /* SIOCSIWPMKSA */
1107 NULL
, /*---hole---*/
1112 static const struct iw_priv_args r8192_private_args
[] = {
1115 SIOCIWFIRSTPRIV
+ 0x0,
1116 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1120 SIOCIWFIRSTPRIV
+ 0x1,
1121 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1125 SIOCIWFIRSTPRIV
+ 0x2,
1126 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1130 SIOCIWFIRSTPRIV
+ 0x3,
1131 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1136 SIOCIWFIRSTPRIV
+ 0x4,
1137 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
|1, IW_PRIV_TYPE_NONE
,
1144 static iw_handler r8192_private_handler
[] = {
1145 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1146 r8192_wx_set_scan_type
,
1148 r8192_wx_force_reset
,
1149 r8192_wx_adapter_power_status
,
1152 static struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1154 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1155 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1156 struct iw_statistics
* wstats
= &priv
->wstats
;
1160 if(ieee
->state
< IEEE80211_LINKED
)
1162 wstats
->qual
.qual
= 0;
1163 wstats
->qual
.level
= 0;
1164 wstats
->qual
.noise
= 0;
1165 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1169 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1170 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1171 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1172 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1174 wstats
->qual
.level
= tmp_level
;
1175 wstats
->qual
.qual
= tmp_qual
;
1176 wstats
->qual
.noise
= tmp_noise
;
1177 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1182 struct iw_handler_def r8192_wx_handlers_def
={
1183 .standard
= r8192_wx_handlers
,
1184 .num_standard
= sizeof(r8192_wx_handlers
) / sizeof(iw_handler
),
1185 .private = r8192_private_handler
,
1186 .num_private
= sizeof(r8192_private_handler
) / sizeof(iw_handler
),
1187 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1188 .get_wireless_stats
= r8192_get_wireless_stats
,
1189 .private_args
= (struct iw_priv_args
*)r8192_private_args
,