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 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
== true)
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
== true)
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
== true)
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
);
141 u16
read_rtl8225(struct net_device
*dev
, u8 addr
);
142 void write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
143 u32
john_read_rtl8225(struct net_device
*dev
, u8 adr
);
144 void _write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
146 static int r8192_wx_read_regs(struct net_device
*dev
,
147 struct iw_request_info
*info
,
148 union iwreq_data
*wrqu
, char *extra
)
150 struct r8192_priv
*priv
= ieee80211_priv(dev
);
157 get_user(addr
,(u8
*)wrqu
->data
.pointer
);
158 data1
= read_rtl8225(dev
, addr
);
159 wrqu
->data
.length
= data1
;
166 static int r8192_wx_write_regs(struct net_device
*dev
,
167 struct iw_request_info
*info
,
168 union iwreq_data
*wrqu
, char *extra
)
170 struct r8192_priv
*priv
= ieee80211_priv(dev
);
175 get_user(addr
, (u8
*)wrqu
->data
.pointer
);
176 write_rtl8225(dev
, addr
, wrqu
->data
.length
);
183 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
184 u8
rtl8187_read_phy(struct net_device
*dev
,u8 adr
, u32 data
);
186 static int r8192_wx_read_bb(struct net_device
*dev
,
187 struct iw_request_info
*info
,
188 union iwreq_data
*wrqu
, char *extra
)
190 struct r8192_priv
*priv
= ieee80211_priv(dev
);
194 for(i
=0;i
<12;i
++) printk("%8x\n", read_cam(dev
, i
) );
199 databb
= rtl8187_read_phy(dev
, (u8
)wrqu
->data
.length
, 0x00000000);
200 wrqu
->data
.length
= databb
;
206 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
207 static int r8192_wx_write_bb(struct net_device
*dev
,
208 struct iw_request_info
*info
,
209 union iwreq_data
*wrqu
, char *extra
)
211 struct r8192_priv
*priv
= ieee80211_priv(dev
);
216 get_user(databb
, (u8
*)wrqu
->data
.pointer
);
217 rtl8187_write_phy(dev
, wrqu
->data
.length
, databb
);
225 static int r8192_wx_write_nicb(struct net_device
*dev
,
226 struct iw_request_info
*info
,
227 union iwreq_data
*wrqu
, char *extra
)
229 struct r8192_priv
*priv
= ieee80211_priv(dev
);
234 get_user(addr
, (u32
*)wrqu
->data
.pointer
);
235 write_nic_byte(dev
, addr
, wrqu
->data
.length
);
241 static int r8192_wx_read_nicb(struct net_device
*dev
,
242 struct iw_request_info
*info
,
243 union iwreq_data
*wrqu
, char *extra
)
245 struct r8192_priv
*priv
= ieee80211_priv(dev
);
251 get_user(addr
,(u32
*)wrqu
->data
.pointer
);
252 data1
= read_nic_byte(dev
, addr
);
253 wrqu
->data
.length
= data1
;
259 static int r8192_wx_get_ap_status(struct net_device
*dev
,
260 struct iw_request_info
*info
,
261 union iwreq_data
*wrqu
, char *extra
)
263 struct r8192_priv
*priv
= ieee80211_priv(dev
);
264 struct ieee80211_device
*ieee
= priv
->ieee80211
;
265 struct ieee80211_network
*target
;
270 //count the length of input ssid
271 for(name_len
=0 ; ((char*)wrqu
->data
.pointer
)[name_len
]!='\0' ; name_len
++);
273 //search for the correspoding info which is received
274 list_for_each_entry(target
, &ieee
->network_list
, list
) {
275 if ( (target
->ssid_len
== name_len
) &&
276 (strncmp(target
->ssid
, (char*)wrqu
->data
.pointer
, name_len
)==0)){
277 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0 )
278 //set flags=1 to indicate this ap is WPA
279 wrqu
->data
.flags
= 1;
280 else wrqu
->data
.flags
= 0;
295 static int r8192_wx_set_rawtx(struct net_device
*dev
,
296 struct iw_request_info
*info
,
297 union iwreq_data
*wrqu
, char *extra
)
299 struct r8192_priv
*priv
= ieee80211_priv(dev
);
302 if(priv
->bHwRadioOff
== true)
307 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
315 static int r8192_wx_force_reset(struct net_device
*dev
,
316 struct iw_request_info
*info
,
317 union iwreq_data
*wrqu
, char *extra
)
319 struct r8192_priv
*priv
= ieee80211_priv(dev
);
323 printk("%s(): force reset ! extra is %d\n",__FUNCTION__
, *extra
);
324 priv
->force_reset
= *extra
;
331 static int r8192_wx_set_crcmon(struct net_device
*dev
,
332 struct iw_request_info
*info
,
333 union iwreq_data
*wrqu
, char *extra
)
335 struct r8192_priv
*priv
= ieee80211_priv(dev
);
336 int *parms
= (int *)extra
;
337 int enable
= (parms
[0] > 0);
338 short prev
= priv
->crcmon
;
340 if(priv
->bHwRadioOff
== true)
350 DMESG("bad CRC in monitor mode are %s",
351 priv
->crcmon
? "accepted" : "rejected");
353 if(prev
!= priv
->crcmon
&& priv
->up
){
363 static int r8192_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
364 union iwreq_data
*wrqu
, char *b
)
366 struct r8192_priv
*priv
= ieee80211_priv(dev
);
367 RT_RF_POWER_STATE rtState
;
370 if(priv
->bHwRadioOff
== true)
373 rtState
= priv
->ieee80211
->eRFPowerState
;
376 if(wrqu
->mode
== IW_MODE_ADHOC
){
378 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
379 if(rtState
== eRfOff
){
380 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
382 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
387 RT_TRACE(COMP_ERR
, "%s(): IPSLeave\n",__FUNCTION__
);
388 down(&priv
->ieee80211
->ips_sem
);
390 up(&priv
->ieee80211
->ips_sem
);
396 ret
= ieee80211_wx_set_mode(priv
->ieee80211
,a
,wrqu
,b
);
398 //rtl8187_set_rxconf(dev);
404 struct iw_range_with_scan_capa
406 /* Informative stuff (to choose between different interface) */
407 __u32 throughput
; /* To give an idea... */
408 /* In theory this value should be the maximum benchmarked
409 * TCP/IP throughput, because with most of these devices the
410 * bit rate is meaningless (overhead an co) to estimate how
411 * fast the connection will go and pick the fastest one.
412 * I suggest people to play with Netperf or any benchmark...
415 /* NWID (or domain id) */
416 __u32 min_nwid
; /* Minimal NWID we are able to set */
417 __u32 max_nwid
; /* Maximal NWID we are able to set */
419 /* Old Frequency (backward compat - moved lower ) */
420 __u16 old_num_channels
;
421 __u8 old_num_frequency
;
423 /* Scan capabilities */
426 static int rtl8180_wx_get_range(struct net_device
*dev
,
427 struct iw_request_info
*info
,
428 union iwreq_data
*wrqu
, char *extra
)
430 struct iw_range
*range
= (struct iw_range
*)extra
;
431 struct iw_range_with_scan_capa
* tmp
= (struct iw_range_with_scan_capa
*)range
;
432 struct r8192_priv
*priv
= ieee80211_priv(dev
);
436 wrqu
->data
.length
= sizeof(*range
);
437 memset(range
, 0, sizeof(*range
));
439 /* Let's try to keep this struct in the same order as in
440 * linux/include/wireless.h
443 /* TODO: See what values we can set, and remove the ones we can't
444 * set, or fill them with some default data.
447 /* ~5 Mb/s real (802.11b) */
448 range
->throughput
= 130 * 1000 * 1000;
450 // TODO: Not used in 802.11b?
451 // range->min_nwid; /* Minimal NWID we are able to set */
452 // TODO: Not used in 802.11b?
453 // range->max_nwid; /* Maximal NWID we are able to set */
455 /* Old Frequency (backward compat - moved lower ) */
456 // range->old_num_channels;
457 // range->old_num_frequency;
458 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
459 if(priv
->rf_set_sens
!= NULL
)
460 range
->sensitivity
= priv
->max_sens
; /* signal level threshold range */
462 range
->max_qual
.qual
= 100;
463 /* TODO: Find real max RSSI and stick here */
464 range
->max_qual
.level
= 0;
465 range
->max_qual
.noise
= -98;
466 range
->max_qual
.updated
= 7; /* Updated all three */
468 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
469 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
470 range
->avg_qual
.level
= 20 + -98;
471 range
->avg_qual
.noise
= 0;
472 range
->avg_qual
.updated
= 7; /* Updated all three */
474 range
->num_bitrates
= RATE_COUNT
;
476 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++) {
477 range
->bitrate
[i
] = rtl8180_rates
[i
];
480 range
->min_frag
= MIN_FRAG_THRESHOLD
;
481 range
->max_frag
= MAX_FRAG_THRESHOLD
;
484 range
->max_pmp
= 5000000;
486 range
->max_pmt
= 65535*1000;
487 range
->pmp_flags
= IW_POWER_PERIOD
;
488 range
->pmt_flags
= IW_POWER_TIMEOUT
;
489 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
490 range
->we_version_compiled
= WIRELESS_EXT
;
491 range
->we_version_source
= 18;
493 // range->retry_capa; /* What retry options are supported */
494 // range->retry_flags; /* How to decode max/min retry limit */
495 // range->r_time_flags; /* How to decode max/min retry life */
496 // range->min_retry; /* Minimal number of retries */
497 // range->max_retry; /* Maximal number of retries */
498 // range->min_r_time; /* Minimal retry lifetime */
499 // range->max_r_time; /* Maximal retry lifetime */
502 for (i
= 0, val
= 0; i
< 14; i
++) {
504 // Include only legal frequencies for some countries
506 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
508 if ((priv
->ieee80211
->channel_map
)[i
+1]) {
510 range
->freq
[val
].i
= i
+ 1;
511 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
512 range
->freq
[val
].e
= 1;
515 // FIXME: do we need to set anything for channels
519 if (val
== IW_MAX_FREQUENCIES
)
522 range
->num_frequency
= val
;
523 range
->num_channels
= val
;
524 #if WIRELESS_EXT > 17
525 range
->enc_capa
= IW_ENC_CAPA_WPA
|IW_ENC_CAPA_WPA2
|
526 IW_ENC_CAPA_CIPHER_TKIP
|IW_ENC_CAPA_CIPHER_CCMP
;
528 tmp
->scan_capa
= 0x01;
533 static int r8192_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
534 union iwreq_data
*wrqu
, char *b
)
536 struct r8192_priv
*priv
= ieee80211_priv(dev
);
537 struct ieee80211_device
* ieee
= priv
->ieee80211
;
538 RT_RF_POWER_STATE rtState
;
541 if(priv
->bHwRadioOff
== true)
544 rtState
= priv
->ieee80211
->eRFPowerState
;
546 if(!priv
->up
) return -ENETDOWN
;
547 if (priv
->ieee80211
->LinkDetectInfo
.bBusyTraffic
== true)
550 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
)
552 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
555 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
556 ieee
->current_network
.ssid_len
= req
->essid_len
;
557 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
558 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
564 priv
->ieee80211
->actscanning
= true;
565 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
566 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
567 if(rtState
== eRfOff
){
568 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
570 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
575 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
576 down(&priv
->ieee80211
->ips_sem
);
578 up(&priv
->ieee80211
->ips_sem
);
582 priv
->ieee80211
->scanning
= 0;
583 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
589 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
590 priv
->ieee80211
->scanning
= 0;
591 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
596 ret
= ieee80211_wx_set_scan(priv
->ieee80211
,a
,wrqu
,b
);
603 static int r8192_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
604 union iwreq_data
*wrqu
, char *b
)
608 struct r8192_priv
*priv
= ieee80211_priv(dev
);
610 if(priv
->bHwRadioOff
== true)
613 if(!priv
->up
) return -ENETDOWN
;
617 ret
= ieee80211_wx_get_scan(priv
->ieee80211
,a
,wrqu
,b
);
624 static int r8192_wx_set_essid(struct net_device
*dev
,
625 struct iw_request_info
*a
,
626 union iwreq_data
*wrqu
, char *b
)
628 struct r8192_priv
*priv
= ieee80211_priv(dev
);
629 RT_RF_POWER_STATE rtState
;
632 if(priv
->bHwRadioOff
== true)
635 rtState
= priv
->ieee80211
->eRFPowerState
;
639 down(&priv
->ieee80211
->ips_sem
);
641 up(&priv
->ieee80211
->ips_sem
);
643 ret
= ieee80211_wx_set_essid(priv
->ieee80211
,a
,wrqu
,b
);
653 static int r8192_wx_get_essid(struct net_device
*dev
,
654 struct iw_request_info
*a
,
655 union iwreq_data
*wrqu
, char *b
)
658 struct r8192_priv
*priv
= ieee80211_priv(dev
);
662 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
670 static int r8192_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
671 union iwreq_data
*wrqu
, char *b
)
674 struct r8192_priv
*priv
= ieee80211_priv(dev
);
676 if(priv
->bHwRadioOff
== true)
681 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
687 static int r8192_wx_get_name(struct net_device
*dev
,
688 struct iw_request_info
*info
,
689 union iwreq_data
*wrqu
, char *extra
)
691 struct r8192_priv
*priv
= ieee80211_priv(dev
);
692 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
696 static int r8192_wx_set_frag(struct net_device
*dev
,
697 struct iw_request_info
*info
,
698 union iwreq_data
*wrqu
, char *extra
)
700 struct r8192_priv
*priv
= ieee80211_priv(dev
);
702 if(priv
->bHwRadioOff
== true)
705 if (wrqu
->frag
.disabled
)
706 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
708 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
709 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
712 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
719 static int r8192_wx_get_frag(struct net_device
*dev
,
720 struct iw_request_info
*info
,
721 union iwreq_data
*wrqu
, char *extra
)
723 struct r8192_priv
*priv
= ieee80211_priv(dev
);
725 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
726 wrqu
->frag
.fixed
= 0; /* no auto select */
727 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
733 static int r8192_wx_set_wap(struct net_device
*dev
,
734 struct iw_request_info
*info
,
735 union iwreq_data
*awrq
,
740 struct r8192_priv
*priv
= ieee80211_priv(dev
);
741 // struct sockaddr *temp = (struct sockaddr *)awrq;
743 if(priv
->bHwRadioOff
== true)
749 down(&priv
->ieee80211
->ips_sem
);
751 up(&priv
->ieee80211
->ips_sem
);
753 ret
= ieee80211_wx_set_wap(priv
->ieee80211
,info
,awrq
,extra
);
762 static int r8192_wx_get_wap(struct net_device
*dev
,
763 struct iw_request_info
*info
,
764 union iwreq_data
*wrqu
, char *extra
)
766 struct r8192_priv
*priv
= ieee80211_priv(dev
);
768 return ieee80211_wx_get_wap(priv
->ieee80211
,info
,wrqu
,extra
);
772 static int r8192_wx_get_enc(struct net_device
*dev
,
773 struct iw_request_info
*info
,
774 union iwreq_data
*wrqu
, char *key
)
776 struct r8192_priv
*priv
= ieee80211_priv(dev
);
778 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
781 static int r8192_wx_set_enc(struct net_device
*dev
,
782 struct iw_request_info
*info
,
783 union iwreq_data
*wrqu
, char *key
)
785 struct r8192_priv
*priv
= ieee80211_priv(dev
);
788 struct ieee80211_device
*ieee
= priv
->ieee80211
;
790 u32 hwkey
[4]={0,0,0,0};
793 u8 zero_addr
[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
794 {0x00,0x00,0x00,0x00,0x00,0x01},
795 {0x00,0x00,0x00,0x00,0x00,0x02},
796 {0x00,0x00,0x00,0x00,0x00,0x03} };
799 if(priv
->bHwRadioOff
== true)
802 if(!priv
->up
) return -ENETDOWN
;
804 priv
->ieee80211
->wx_set_enc
= 1;
806 down(&priv
->ieee80211
->ips_sem
);
808 up(&priv
->ieee80211
->ips_sem
);
813 RT_TRACE(COMP_SEC
, "Setting SW wep key");
814 ret
= ieee80211_wx_set_encode(priv
->ieee80211
,info
,wrqu
,key
);
818 //sometimes, the length is zero while we do not type key value
819 if(wrqu
->encoding
.length
!=0){
821 for(i
=0 ; i
<4 ; i
++){
822 hwkey
[i
] |= key
[4*i
+0]&mask
;
823 if(i
==1&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
824 if(i
==3&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
825 hwkey
[i
] |= (key
[4*i
+1]&mask
)<<8;
826 hwkey
[i
] |= (key
[4*i
+2]&mask
)<<16;
827 hwkey
[i
] |= (key
[4*i
+3]&mask
)<<24;
830 #define CONF_WEP40 0x4
831 #define CONF_WEP104 0x14
833 switch(wrqu
->encoding
.flags
& IW_ENCODE_INDEX
){
834 case 0: key_idx
= ieee
->tx_keyidx
; break;
835 case 1: key_idx
= 0; break;
836 case 2: key_idx
= 1; break;
837 case 3: key_idx
= 2; break;
838 case 4: key_idx
= 3; break;
842 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
843 if(wrqu
->encoding
.length
==0x5){
844 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
845 EnableHWSecurityConfig8192(dev
);
849 KEY_TYPE_WEP40
, //KeyType
857 //write_nic_byte(dev, SECR, 7);
861 KEY_TYPE_WEP40
, //KeyType
862 broadcast_addr
, //addr
869 else if(wrqu
->encoding
.length
==0xd){
870 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
871 EnableHWSecurityConfig8192(dev
);
875 KEY_TYPE_WEP104
, //KeyType
882 //write_nic_byte(dev, SECR, 7);
886 KEY_TYPE_WEP104
, //KeyType
887 broadcast_addr
, //addr
893 else printk("wrong type in WEP, not WEP40 and WEP104\n");
899 //consider the setting different key index situation
900 //wrqu->encoding.flags = 801 means that we set key with index "1"
901 if(wrqu
->encoding
.length
==0 && (wrqu
->encoding
.flags
>>8) == 0x8 ){
903 //write_nic_byte(dev, SECR, 7);
904 EnableHWSecurityConfig8192(dev
);
905 //copy wpa config from default key(key0~key3) to broadcast key(key5)
907 key_idx
= (wrqu
->encoding
.flags
& 0xf)-1 ;
908 write_cam(dev
, (4*6), 0xffff0000|read_cam(dev
, key_idx
*6) );
909 write_cam(dev
, (4*6)+1, 0xffffffff);
910 write_cam(dev
, (4*6)+2, read_cam(dev
, (key_idx
*6)+2) );
911 write_cam(dev
, (4*6)+3, read_cam(dev
, (key_idx
*6)+3) );
912 write_cam(dev
, (4*6)+4, read_cam(dev
, (key_idx
*6)+4) );
913 write_cam(dev
, (4*6)+5, read_cam(dev
, (key_idx
*6)+5) );
917 priv
->ieee80211
->wx_set_enc
= 0;
923 static int r8192_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
924 iwreq_data
*wrqu
, char *p
){
926 struct r8192_priv
*priv
= ieee80211_priv(dev
);
930 priv
->ieee80211
->active_scan
= mode
;
937 static int r8192_wx_set_retry(struct net_device
*dev
,
938 struct iw_request_info
*info
,
939 union iwreq_data
*wrqu
, char *extra
)
941 struct r8192_priv
*priv
= ieee80211_priv(dev
);
944 if(priv
->bHwRadioOff
== true)
949 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
950 wrqu
->retry
.disabled
){
954 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)){
959 if(wrqu
->retry
.value
> R8180_MAX_RETRY
){
963 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
964 priv
->retry_rts
= wrqu
->retry
.value
;
965 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
968 priv
->retry_data
= wrqu
->retry
.value
;
969 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
973 * We might try to write directly the TX config register
974 * or to restart just the (R)TX process.
975 * I'm unsure if whole reset is really needed
981 rtl8180_rtx_disable(dev);
982 rtl8180_rx_enable(dev);
983 rtl8180_tx_enable(dev);
993 static int r8192_wx_get_retry(struct net_device
*dev
,
994 struct iw_request_info
*info
,
995 union iwreq_data
*wrqu
, char *extra
)
997 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1000 wrqu
->retry
.disabled
= 0; /* can't be disabled */
1002 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
1006 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
1007 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MAX
;
1008 wrqu
->retry
.value
= priv
->retry_rts
;
1010 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MIN
;
1011 wrqu
->retry
.value
= priv
->retry_data
;
1013 //DMESG("returning %d",wrqu->retry.value);
1019 static int r8192_wx_get_sens(struct net_device
*dev
,
1020 struct iw_request_info
*info
,
1021 union iwreq_data
*wrqu
, char *extra
)
1023 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1024 if(priv
->rf_set_sens
== NULL
)
1025 return -1; /* we have not this support for this radio */
1026 wrqu
->sens
.value
= priv
->sens
;
1031 static int r8192_wx_set_sens(struct net_device
*dev
,
1032 struct iw_request_info
*info
,
1033 union iwreq_data
*wrqu
, char *extra
)
1036 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1040 if(priv
->bHwRadioOff
== true)
1043 down(&priv
->wx_sem
);
1044 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
1045 if(priv
->rf_set_sens
== NULL
) {
1046 err
= -1; /* we have not this support for this radio */
1049 if(priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
1050 priv
->sens
= wrqu
->sens
.value
;
1060 #if (WIRELESS_EXT >= 18)
1061 static int r8192_wx_set_enc_ext(struct net_device
*dev
,
1062 struct iw_request_info
*info
,
1063 union iwreq_data
*wrqu
, char *extra
)
1066 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1067 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1069 if(priv
->bHwRadioOff
== true)
1072 down(&priv
->wx_sem
);
1074 priv
->ieee80211
->wx_set_enc
= 1;
1077 down(&priv
->ieee80211
->ips_sem
);
1079 up(&priv
->ieee80211
->ips_sem
);
1082 ret
= ieee80211_wx_set_encode_ext(ieee
, info
, wrqu
, extra
);
1085 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1088 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1089 struct iw_point
*encoding
= &wrqu
->encoding
;
1091 static u8 CAM_CONST_ADDR
[4][6] = {
1092 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1093 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1094 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1095 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1097 u8 idx
= 0, alg
= 0, group
= 0;
1098 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
1099 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
1101 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
1102 CamResetAllEntry(dev
);
1105 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;
1106 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1109 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
1111 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
1113 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
1114 alg
= KEY_TYPE_WEP104
;
1115 ieee
->pairwise_key_type
= alg
;
1116 EnableHWSecurityConfig8192(dev
);
1118 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
1120 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
1122 if (ext
->key_len
== 13)
1123 ieee
->pairwise_key_type
= alg
= KEY_TYPE_WEP104
;
1134 ieee
->group_key_type
= alg
;
1139 broadcast_addr
, //MacAddr
1145 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
1146 write_nic_byte(dev
, 0x173, 1); //fix aes bug
1152 (u8
*)ieee
->ap_mac_addr
, //MacAddr
1161 priv
->ieee80211
->wx_set_enc
= 0;
1166 static int r8192_wx_set_auth(struct net_device
*dev
,
1167 struct iw_request_info
*info
,
1168 union iwreq_data
*data
, char *extra
)
1171 //printk("====>%s()\n", __FUNCTION__);
1172 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1174 if(priv
->bHwRadioOff
== true)
1177 down(&priv
->wx_sem
);
1178 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
1183 static int r8192_wx_set_mlme(struct net_device
*dev
,
1184 struct iw_request_info
*info
,
1185 union iwreq_data
*wrqu
, char *extra
)
1187 //printk("====>%s()\n", __FUNCTION__);
1190 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1192 if(priv
->bHwRadioOff
== true)
1195 down(&priv
->wx_sem
);
1196 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1201 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
1202 struct iw_request_info
*info
,
1203 union iwreq_data
*data
, char *extra
)
1205 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1207 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1209 if(priv
->bHwRadioOff
== true)
1212 down(&priv
->wx_sem
);
1213 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1215 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1219 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1220 union iwreq_data
*wrqu
,char *b
)
1225 // check ac/dc status with the help of user space application */
1226 static int r8192_wx_adapter_power_status(struct net_device
*dev
,
1227 struct iw_request_info
*info
,
1228 union iwreq_data
*wrqu
, char *extra
)
1230 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1232 PRT_POWER_SAVE_CONTROL pPSC
= (PRT_POWER_SAVE_CONTROL
)(&(priv
->ieee80211
->PowerSaveControl
));
1233 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1235 down(&priv
->wx_sem
);
1238 RT_TRACE(COMP_POWER
, "%s(): %s\n",__FUNCTION__
, (*extra
== 6)?"DC power":"AC power");
1239 // ieee->ps shall not be set under DC mode, otherwise it conflict
1240 // with Leisure power save mode setting.
1242 if(*extra
|| priv
->force_lps
) {
1243 priv
->ps_force
= false;
1244 pPSC
->bLeisurePs
= true;
1246 //LZM for PS-Poll AID issue. 090429
1247 if(priv
->ieee80211
->state
== IEEE80211_LINKED
)
1248 LeisurePSLeave(dev
);
1250 priv
->ps_force
= true;
1251 pPSC
->bLeisurePs
= false;
1262 static iw_handler r8192_wx_handlers
[] =
1264 NULL
, /* SIOCSIWCOMMIT */
1265 r8192_wx_get_name
, /* SIOCGIWNAME */
1266 dummy
, /* SIOCSIWNWID */
1267 dummy
, /* SIOCGIWNWID */
1268 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1269 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1270 r8192_wx_set_mode
, /* SIOCSIWMODE */
1271 r8192_wx_get_mode
, /* SIOCGIWMODE */
1272 r8192_wx_set_sens
, /* SIOCSIWSENS */
1273 r8192_wx_get_sens
, /* SIOCGIWSENS */
1274 NULL
, /* SIOCSIWRANGE */
1275 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1276 NULL
, /* SIOCSIWPRIV */
1277 NULL
, /* SIOCGIWPRIV */
1278 NULL
, /* SIOCSIWSTATS */
1279 NULL
, /* SIOCGIWSTATS */
1280 dummy
, /* SIOCSIWSPY */
1281 dummy
, /* SIOCGIWSPY */
1282 NULL
, /* SIOCGIWTHRSPY */
1283 NULL
, /* SIOCWIWTHRSPY */
1284 r8192_wx_set_wap
, /* SIOCSIWAP */
1285 r8192_wx_get_wap
, /* SIOCGIWAP */
1286 #if (WIRELESS_EXT >= 18)
1287 r8192_wx_set_mlme
, /* MLME-- */
1291 dummy
, /* SIOCGIWAPLIST -- depricated */
1292 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1293 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1294 r8192_wx_set_essid
, /* SIOCSIWESSID */
1295 r8192_wx_get_essid
, /* SIOCGIWESSID */
1296 dummy
, /* SIOCSIWNICKN */
1297 dummy
, /* SIOCGIWNICKN */
1298 NULL
, /* -- hole -- */
1299 NULL
, /* -- hole -- */
1300 r8192_wx_set_rate
, /* SIOCSIWRATE */
1301 r8192_wx_get_rate
, /* SIOCGIWRATE */
1302 r8192_wx_set_rts
, /* SIOCSIWRTS */
1303 r8192_wx_get_rts
, /* SIOCGIWRTS */
1304 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1305 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1306 dummy
, /* SIOCSIWTXPOW */
1307 dummy
, /* SIOCGIWTXPOW */
1308 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1309 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1310 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1311 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1312 r8192_wx_set_power
, /* SIOCSIWPOWER */
1313 r8192_wx_get_power
, /* SIOCGIWPOWER */
1314 NULL
, /*---hole---*/
1315 NULL
, /*---hole---*/
1316 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1317 NULL
, /* SIOCSIWGENIE */
1318 #if (WIRELESS_EXT >= 18)
1319 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1320 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1321 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1327 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1328 NULL
, /* SIOCSIWPMKSA */
1329 NULL
, /*---hole---*/
1334 static const struct iw_priv_args r8192_private_args
[] = {
1337 SIOCIWFIRSTPRIV
+ 0x0,
1338 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1342 SIOCIWFIRSTPRIV
+ 0x1,
1343 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1347 SIOCIWFIRSTPRIV
+ 0x2,
1348 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1352 SIOCIWFIRSTPRIV
+ 0x3,
1353 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1358 SIOCIWFIRSTPRIV
+ 0x4,
1359 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
|1, IW_PRIV_TYPE_NONE
,
1366 static iw_handler r8192_private_handler
[] = {
1367 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1368 r8192_wx_set_scan_type
,
1370 r8192_wx_force_reset
,
1371 r8192_wx_adapter_power_status
,
1374 //#if WIRELESS_EXT >= 17
1375 struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1377 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1378 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1379 struct iw_statistics
* wstats
= &priv
->wstats
;
1383 if(ieee
->state
< IEEE80211_LINKED
)
1385 wstats
->qual
.qual
= 0;
1386 wstats
->qual
.level
= 0;
1387 wstats
->qual
.noise
= 0;
1388 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1392 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1393 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1394 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1395 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1397 wstats
->qual
.level
= tmp_level
;
1398 wstats
->qual
.qual
= tmp_qual
;
1399 wstats
->qual
.noise
= tmp_noise
;
1400 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1406 struct iw_handler_def r8192_wx_handlers_def
={
1407 .standard
= r8192_wx_handlers
,
1408 .num_standard
= sizeof(r8192_wx_handlers
) / sizeof(iw_handler
),
1409 .private = r8192_private_handler
,
1410 .num_private
= sizeof(r8192_private_handler
) / sizeof(iw_handler
),
1411 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1412 #if WIRELESS_EXT >= 17
1413 .get_wireless_stats
= r8192_get_wireless_stats
,
1415 .private_args
= (struct iw_priv_args
*)r8192_private_args
,