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"
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
);
75 ret
= ieee80211_wx_set_rate(priv
->ieee80211
,info
,wrqu
,extra
);
83 static int r8192_wx_set_rts(struct net_device
*dev
,
84 struct iw_request_info
*info
,
85 union iwreq_data
*wrqu
, char *extra
)
88 struct r8192_priv
*priv
= ieee80211_priv(dev
);
92 ret
= ieee80211_wx_set_rts(priv
->ieee80211
,info
,wrqu
,extra
);
99 static int r8192_wx_get_rts(struct net_device
*dev
,
100 struct iw_request_info
*info
,
101 union iwreq_data
*wrqu
, char *extra
)
103 struct r8192_priv
*priv
= ieee80211_priv(dev
);
104 return ieee80211_wx_get_rts(priv
->ieee80211
,info
,wrqu
,extra
);
107 static int r8192_wx_set_power(struct net_device
*dev
,
108 struct iw_request_info
*info
,
109 union iwreq_data
*wrqu
, char *extra
)
112 struct r8192_priv
*priv
= ieee80211_priv(dev
);
116 ret
= ieee80211_wx_set_power(priv
->ieee80211
,info
,wrqu
,extra
);
123 static int r8192_wx_get_power(struct net_device
*dev
,
124 struct iw_request_info
*info
,
125 union iwreq_data
*wrqu
, char *extra
)
127 struct r8192_priv
*priv
= ieee80211_priv(dev
);
128 return ieee80211_wx_get_power(priv
->ieee80211
,info
,wrqu
,extra
);
132 u16
read_rtl8225(struct net_device
*dev
, u8 addr
);
133 void write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
134 u32
john_read_rtl8225(struct net_device
*dev
, u8 adr
);
135 void _write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
137 static int r8192_wx_read_regs(struct net_device
*dev
,
138 struct iw_request_info
*info
,
139 union iwreq_data
*wrqu
, char *extra
)
141 struct r8192_priv
*priv
= ieee80211_priv(dev
);
148 get_user(addr
,(u8
*)wrqu
->data
.pointer
);
149 data1
= read_rtl8225(dev
, addr
);
150 wrqu
->data
.length
= data1
;
157 static int r8192_wx_write_regs(struct net_device
*dev
,
158 struct iw_request_info
*info
,
159 union iwreq_data
*wrqu
, char *extra
)
161 struct r8192_priv
*priv
= ieee80211_priv(dev
);
166 get_user(addr
, (u8
*)wrqu
->data
.pointer
);
167 write_rtl8225(dev
, addr
, wrqu
->data
.length
);
174 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
175 u8
rtl8187_read_phy(struct net_device
*dev
,u8 adr
, u32 data
);
177 static int r8192_wx_read_bb(struct net_device
*dev
,
178 struct iw_request_info
*info
,
179 union iwreq_data
*wrqu
, char *extra
)
181 struct r8192_priv
*priv
= ieee80211_priv(dev
);
185 for(i
=0;i
<12;i
++) printk("%8x\n", read_cam(dev
, i
) );
190 databb
= rtl8187_read_phy(dev
, (u8
)wrqu
->data
.length
, 0x00000000);
191 wrqu
->data
.length
= databb
;
197 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
198 static int r8192_wx_write_bb(struct net_device
*dev
,
199 struct iw_request_info
*info
,
200 union iwreq_data
*wrqu
, char *extra
)
202 struct r8192_priv
*priv
= ieee80211_priv(dev
);
207 get_user(databb
, (u8
*)wrqu
->data
.pointer
);
208 rtl8187_write_phy(dev
, wrqu
->data
.length
, databb
);
216 static int r8192_wx_write_nicb(struct net_device
*dev
,
217 struct iw_request_info
*info
,
218 union iwreq_data
*wrqu
, char *extra
)
220 struct r8192_priv
*priv
= ieee80211_priv(dev
);
225 get_user(addr
, (u32
*)wrqu
->data
.pointer
);
226 write_nic_byte(dev
, addr
, wrqu
->data
.length
);
232 static int r8192_wx_read_nicb(struct net_device
*dev
,
233 struct iw_request_info
*info
,
234 union iwreq_data
*wrqu
, char *extra
)
236 struct r8192_priv
*priv
= ieee80211_priv(dev
);
242 get_user(addr
,(u32
*)wrqu
->data
.pointer
);
243 data1
= read_nic_byte(dev
, addr
);
244 wrqu
->data
.length
= data1
;
250 static int r8192_wx_get_ap_status(struct net_device
*dev
,
251 struct iw_request_info
*info
,
252 union iwreq_data
*wrqu
, char *extra
)
254 struct r8192_priv
*priv
= ieee80211_priv(dev
);
255 struct ieee80211_device
*ieee
= priv
->ieee80211
;
256 struct ieee80211_network
*target
;
261 //count the length of input ssid
262 for(name_len
=0 ; ((char*)wrqu
->data
.pointer
)[name_len
]!='\0' ; name_len
++);
264 //search for the correspoding info which is received
265 list_for_each_entry(target
, &ieee
->network_list
, list
) {
266 if ( (target
->ssid_len
== name_len
) &&
267 (strncmp(target
->ssid
, (char*)wrqu
->data
.pointer
, name_len
)==0)){
268 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0 )
269 //set flags=1 to indicate this ap is WPA
270 wrqu
->data
.flags
= 1;
271 else wrqu
->data
.flags
= 0;
286 static int r8192_wx_set_rawtx(struct net_device
*dev
,
287 struct iw_request_info
*info
,
288 union iwreq_data
*wrqu
, char *extra
)
290 struct r8192_priv
*priv
= ieee80211_priv(dev
);
295 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
303 static int r8192_wx_force_reset(struct net_device
*dev
,
304 struct iw_request_info
*info
,
305 union iwreq_data
*wrqu
, char *extra
)
307 struct r8192_priv
*priv
= ieee80211_priv(dev
);
311 printk("%s(): force reset ! extra is %d\n",__FUNCTION__
, *extra
);
312 priv
->force_reset
= *extra
;
319 static int r8192_wx_set_crcmon(struct net_device
*dev
,
320 struct iw_request_info
*info
,
321 union iwreq_data
*wrqu
, char *extra
)
323 struct r8192_priv
*priv
= ieee80211_priv(dev
);
324 int *parms
= (int *)extra
;
325 int enable
= (parms
[0] > 0);
326 short prev
= priv
->crcmon
;
335 DMESG("bad CRC in monitor mode are %s",
336 priv
->crcmon
? "accepted" : "rejected");
338 if(prev
!= priv
->crcmon
&& priv
->up
){
348 static int r8192_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
349 union iwreq_data
*wrqu
, char *b
)
351 struct r8192_priv
*priv
= ieee80211_priv(dev
);
352 RT_RF_POWER_STATE rtState
;
355 rtState
= priv
->ieee80211
->eRFPowerState
;
358 if(wrqu
->mode
== IW_MODE_ADHOC
){
360 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
361 if(rtState
== eRfOff
){
362 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
364 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
369 printk("=========>%s(): IPSLeave\n",__FUNCTION__
);
376 ret
= ieee80211_wx_set_mode(priv
->ieee80211
,a
,wrqu
,b
);
378 //rtl8187_set_rxconf(dev);
384 struct iw_range_with_scan_capa
386 /* Informative stuff (to choose between different interface) */
387 __u32 throughput
; /* To give an idea... */
388 /* In theory this value should be the maximum benchmarked
389 * TCP/IP throughput, because with most of these devices the
390 * bit rate is meaningless (overhead an co) to estimate how
391 * fast the connection will go and pick the fastest one.
392 * I suggest people to play with Netperf or any benchmark...
395 /* NWID (or domain id) */
396 __u32 min_nwid
; /* Minimal NWID we are able to set */
397 __u32 max_nwid
; /* Maximal NWID we are able to set */
399 /* Old Frequency (backward compat - moved lower ) */
400 __u16 old_num_channels
;
401 __u8 old_num_frequency
;
403 /* Scan capabilities */
406 static int rtl8180_wx_get_range(struct net_device
*dev
,
407 struct iw_request_info
*info
,
408 union iwreq_data
*wrqu
, char *extra
)
410 struct iw_range
*range
= (struct iw_range
*)extra
;
411 struct iw_range_with_scan_capa
* tmp
= (struct iw_range_with_scan_capa
*)range
;
412 struct r8192_priv
*priv
= ieee80211_priv(dev
);
416 wrqu
->data
.length
= sizeof(*range
);
417 memset(range
, 0, sizeof(*range
));
419 /* Let's try to keep this struct in the same order as in
420 * linux/include/wireless.h
423 /* TODO: See what values we can set, and remove the ones we can't
424 * set, or fill them with some default data.
427 /* ~5 Mb/s real (802.11b) */
428 range
->throughput
= 5 * 1000 * 1000;
430 // TODO: Not used in 802.11b?
431 // range->min_nwid; /* Minimal NWID we are able to set */
432 // TODO: Not used in 802.11b?
433 // range->max_nwid; /* Maximal NWID we are able to set */
435 /* Old Frequency (backward compat - moved lower ) */
436 // range->old_num_channels;
437 // range->old_num_frequency;
438 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
439 if(priv
->rf_set_sens
!= NULL
)
440 range
->sensitivity
= priv
->max_sens
; /* signal level threshold range */
442 range
->max_qual
.qual
= 100;
443 /* TODO: Find real max RSSI and stick here */
444 range
->max_qual
.level
= 0;
445 range
->max_qual
.noise
= -98;
446 range
->max_qual
.updated
= 7; /* Updated all three */
448 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
449 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
450 range
->avg_qual
.level
= 20 + -98;
451 range
->avg_qual
.noise
= 0;
452 range
->avg_qual
.updated
= 7; /* Updated all three */
454 range
->num_bitrates
= RATE_COUNT
;
456 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++) {
457 range
->bitrate
[i
] = rtl8180_rates
[i
];
460 range
->min_frag
= MIN_FRAG_THRESHOLD
;
461 range
->max_frag
= MAX_FRAG_THRESHOLD
;
464 range
->max_pmp
= 5000000;
466 range
->max_pmt
= 65535*1000;
467 range
->pmp_flags
= IW_POWER_PERIOD
;
468 range
->pmt_flags
= IW_POWER_TIMEOUT
;
469 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
470 range
->we_version_compiled
= WIRELESS_EXT
;
471 range
->we_version_source
= 16;
473 // range->retry_capa; /* What retry options are supported */
474 // range->retry_flags; /* How to decode max/min retry limit */
475 // range->r_time_flags; /* How to decode max/min retry life */
476 // range->min_retry; /* Minimal number of retries */
477 // range->max_retry; /* Maximal number of retries */
478 // range->min_r_time; /* Minimal retry lifetime */
479 // range->max_r_time; /* Maximal retry lifetime */
482 for (i
= 0, val
= 0; i
< 14; i
++) {
484 // Include only legal frequencies for some countries
486 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
488 if ((priv
->ieee80211
->channel_map
)[i
+1]) {
490 range
->freq
[val
].i
= i
+ 1;
491 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
492 range
->freq
[val
].e
= 1;
495 // FIXME: do we need to set anything for channels
499 if (val
== IW_MAX_FREQUENCIES
)
502 range
->num_frequency
= val
;
503 range
->num_channels
= val
;
504 #if WIRELESS_EXT > 17
505 range
->enc_capa
= IW_ENC_CAPA_WPA
|IW_ENC_CAPA_WPA2
|
506 IW_ENC_CAPA_CIPHER_TKIP
|IW_ENC_CAPA_CIPHER_CCMP
;
508 tmp
->scan_capa
= 0x01;
513 static int r8192_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
514 union iwreq_data
*wrqu
, char *b
)
516 struct r8192_priv
*priv
= ieee80211_priv(dev
);
517 struct ieee80211_device
* ieee
= priv
->ieee80211
;
518 RT_RF_POWER_STATE rtState
;
520 rtState
= priv
->ieee80211
->eRFPowerState
;
521 if(!priv
->up
) return -ENETDOWN
;
522 if (priv
->ieee80211
->LinkDetectInfo
.bBusyTraffic
== true)
525 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
)
527 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
530 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
531 ieee
->current_network
.ssid_len
= req
->essid_len
;
532 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
533 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
539 priv
->ieee80211
->actscanning
= true;
540 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
541 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
542 if(rtState
== eRfOff
){
543 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
545 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
550 printk("=========>%s(): IPSLeave\n",__FUNCTION__
);
555 priv
->ieee80211
->scanning
= 0;
556 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
562 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
563 priv
->ieee80211
->scanning
= 0;
564 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
569 ret
= ieee80211_wx_set_scan(priv
->ieee80211
,a
,wrqu
,b
);
576 static int r8192_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
577 union iwreq_data
*wrqu
, char *b
)
581 struct r8192_priv
*priv
= ieee80211_priv(dev
);
583 if(!priv
->up
) return -ENETDOWN
;
587 ret
= ieee80211_wx_get_scan(priv
->ieee80211
,a
,wrqu
,b
);
594 static int r8192_wx_set_essid(struct net_device
*dev
,
595 struct iw_request_info
*a
,
596 union iwreq_data
*wrqu
, char *b
)
598 struct r8192_priv
*priv
= ieee80211_priv(dev
);
599 RT_RF_POWER_STATE rtState
;
602 rtState
= priv
->ieee80211
->eRFPowerState
;
605 if(priv
->ieee80211
->PowerSaveControl
.bInactivePs
){
606 if(rtState
== eRfOff
){
607 if(priv
->ieee80211
->RfOffReason
> RF_CHANGE_BY_IPS
)
609 RT_TRACE(COMP_ERR
, "%s(): RF is OFF.\n",__FUNCTION__
);
614 printk("=========>%s(): IPSLeave\n",__FUNCTION__
);
620 ret
= ieee80211_wx_set_essid(priv
->ieee80211
,a
,wrqu
,b
);
630 static int r8192_wx_get_essid(struct net_device
*dev
,
631 struct iw_request_info
*a
,
632 union iwreq_data
*wrqu
, char *b
)
635 struct r8192_priv
*priv
= ieee80211_priv(dev
);
639 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
647 static int r8192_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
648 union iwreq_data
*wrqu
, char *b
)
651 struct r8192_priv
*priv
= ieee80211_priv(dev
);
655 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
661 static int r8192_wx_get_name(struct net_device
*dev
,
662 struct iw_request_info
*info
,
663 union iwreq_data
*wrqu
, char *extra
)
665 struct r8192_priv
*priv
= ieee80211_priv(dev
);
666 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
670 static int r8192_wx_set_frag(struct net_device
*dev
,
671 struct iw_request_info
*info
,
672 union iwreq_data
*wrqu
, char *extra
)
674 struct r8192_priv
*priv
= ieee80211_priv(dev
);
676 if (wrqu
->frag
.disabled
)
677 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
679 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
680 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
683 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
690 static int r8192_wx_get_frag(struct net_device
*dev
,
691 struct iw_request_info
*info
,
692 union iwreq_data
*wrqu
, char *extra
)
694 struct r8192_priv
*priv
= ieee80211_priv(dev
);
696 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
697 wrqu
->frag
.fixed
= 0; /* no auto select */
698 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
704 static int r8192_wx_set_wap(struct net_device
*dev
,
705 struct iw_request_info
*info
,
706 union iwreq_data
*awrq
,
711 struct r8192_priv
*priv
= ieee80211_priv(dev
);
712 // struct sockaddr *temp = (struct sockaddr *)awrq;
716 ret
= ieee80211_wx_set_wap(priv
->ieee80211
,info
,awrq
,extra
);
725 static int r8192_wx_get_wap(struct net_device
*dev
,
726 struct iw_request_info
*info
,
727 union iwreq_data
*wrqu
, char *extra
)
729 struct r8192_priv
*priv
= ieee80211_priv(dev
);
731 return ieee80211_wx_get_wap(priv
->ieee80211
,info
,wrqu
,extra
);
735 static int r8192_wx_get_enc(struct net_device
*dev
,
736 struct iw_request_info
*info
,
737 union iwreq_data
*wrqu
, char *key
)
739 struct r8192_priv
*priv
= ieee80211_priv(dev
);
741 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
744 static int r8192_wx_set_enc(struct net_device
*dev
,
745 struct iw_request_info
*info
,
746 union iwreq_data
*wrqu
, char *key
)
748 struct r8192_priv
*priv
= ieee80211_priv(dev
);
751 struct ieee80211_device
*ieee
= priv
->ieee80211
;
753 u32 hwkey
[4]={0,0,0,0};
756 u8 zero_addr
[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
757 {0x00,0x00,0x00,0x00,0x00,0x01},
758 {0x00,0x00,0x00,0x00,0x00,0x02},
759 {0x00,0x00,0x00,0x00,0x00,0x03} };
762 if(!priv
->up
) return -ENETDOWN
;
766 RT_TRACE(COMP_SEC
, "Setting SW wep key");
767 ret
= ieee80211_wx_set_encode(priv
->ieee80211
,info
,wrqu
,key
);
772 //sometimes, the length is zero while we do not type key value
773 if(wrqu
->encoding
.length
!=0){
775 for(i
=0 ; i
<4 ; i
++){
776 hwkey
[i
] |= key
[4*i
+0]&mask
;
777 if(i
==1&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
778 if(i
==3&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
779 hwkey
[i
] |= (key
[4*i
+1]&mask
)<<8;
780 hwkey
[i
] |= (key
[4*i
+2]&mask
)<<16;
781 hwkey
[i
] |= (key
[4*i
+3]&mask
)<<24;
784 #define CONF_WEP40 0x4
785 #define CONF_WEP104 0x14
787 switch(wrqu
->encoding
.flags
& IW_ENCODE_INDEX
){
788 case 0: key_idx
= ieee
->tx_keyidx
; break;
789 case 1: key_idx
= 0; break;
790 case 2: key_idx
= 1; break;
791 case 3: key_idx
= 2; break;
792 case 4: key_idx
= 3; break;
796 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
797 if(wrqu
->encoding
.length
==0x5){
798 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
799 EnableHWSecurityConfig8192(dev
);
803 KEY_TYPE_WEP40
, //KeyType
811 //write_nic_byte(dev, SECR, 7);
815 KEY_TYPE_WEP40
, //KeyType
816 broadcast_addr
, //addr
823 else if(wrqu
->encoding
.length
==0xd){
824 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
825 EnableHWSecurityConfig8192(dev
);
829 KEY_TYPE_WEP104
, //KeyType
836 //write_nic_byte(dev, SECR, 7);
840 KEY_TYPE_WEP104
, //KeyType
841 broadcast_addr
, //addr
847 else printk("wrong type in WEP, not WEP40 and WEP104\n");
853 //consider the setting different key index situation
854 //wrqu->encoding.flags = 801 means that we set key with index "1"
855 if(wrqu
->encoding
.length
==0 && (wrqu
->encoding
.flags
>>8) == 0x8 ){
857 //write_nic_byte(dev, SECR, 7);
858 EnableHWSecurityConfig8192(dev
);
859 //copy wpa config from default key(key0~key3) to broadcast key(key5)
861 key_idx
= (wrqu
->encoding
.flags
& 0xf)-1 ;
862 write_cam(dev
, (4*6), 0xffff0000|read_cam(dev
, key_idx
*6) );
863 write_cam(dev
, (4*6)+1, 0xffffffff);
864 write_cam(dev
, (4*6)+2, read_cam(dev
, (key_idx
*6)+2) );
865 write_cam(dev
, (4*6)+3, read_cam(dev
, (key_idx
*6)+3) );
866 write_cam(dev
, (4*6)+4, read_cam(dev
, (key_idx
*6)+4) );
867 write_cam(dev
, (4*6)+5, read_cam(dev
, (key_idx
*6)+5) );
875 static int r8192_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
876 iwreq_data
*wrqu
, char *p
){
878 struct r8192_priv
*priv
= ieee80211_priv(dev
);
882 priv
->ieee80211
->active_scan
= mode
;
889 static int r8192_wx_set_retry(struct net_device
*dev
,
890 struct iw_request_info
*info
,
891 union iwreq_data
*wrqu
, char *extra
)
893 struct r8192_priv
*priv
= ieee80211_priv(dev
);
898 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
899 wrqu
->retry
.disabled
){
903 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)){
908 if(wrqu
->retry
.value
> R8180_MAX_RETRY
){
912 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
913 priv
->retry_rts
= wrqu
->retry
.value
;
914 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
917 priv
->retry_data
= wrqu
->retry
.value
;
918 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
922 * We might try to write directly the TX config register
923 * or to restart just the (R)TX process.
924 * I'm unsure if whole reset is really needed
930 rtl8180_rtx_disable(dev);
931 rtl8180_rx_enable(dev);
932 rtl8180_tx_enable(dev);
942 static int r8192_wx_get_retry(struct net_device
*dev
,
943 struct iw_request_info
*info
,
944 union iwreq_data
*wrqu
, char *extra
)
946 struct r8192_priv
*priv
= ieee80211_priv(dev
);
949 wrqu
->retry
.disabled
= 0; /* can't be disabled */
951 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
955 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
956 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MAX
;
957 wrqu
->retry
.value
= priv
->retry_rts
;
959 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MIN
;
960 wrqu
->retry
.value
= priv
->retry_data
;
962 //DMESG("returning %d",wrqu->retry.value);
968 static int r8192_wx_get_sens(struct net_device
*dev
,
969 struct iw_request_info
*info
,
970 union iwreq_data
*wrqu
, char *extra
)
972 struct r8192_priv
*priv
= ieee80211_priv(dev
);
973 if(priv
->rf_set_sens
== NULL
)
974 return -1; /* we have not this support for this radio */
975 wrqu
->sens
.value
= priv
->sens
;
980 static int r8192_wx_set_sens(struct net_device
*dev
,
981 struct iw_request_info
*info
,
982 union iwreq_data
*wrqu
, char *extra
)
985 struct r8192_priv
*priv
= ieee80211_priv(dev
);
989 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
990 if(priv
->rf_set_sens
== NULL
) {
991 err
= -1; /* we have not this support for this radio */
994 if(priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
995 priv
->sens
= wrqu
->sens
.value
;
1005 #if (WIRELESS_EXT >= 18)
1006 static int r8192_wx_set_enc_ext(struct net_device
*dev
,
1007 struct iw_request_info
*info
,
1008 union iwreq_data
*wrqu
, char *extra
)
1011 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1012 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1013 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1015 down(&priv
->wx_sem
);
1016 ret
= ieee80211_wx_set_encode_ext(ieee
, info
, wrqu
, extra
);
1019 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1022 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1023 struct iw_point
*encoding
= &wrqu
->encoding
;
1025 static u8 CAM_CONST_ADDR
[4][6] = {
1026 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1027 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1028 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1029 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1031 u8 idx
= 0, alg
= 0, group
= 0;
1032 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
1033 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
1035 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
1036 CamResetAllEntry(dev
);
1039 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;
1040 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1043 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
1045 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
1047 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
1048 alg
= KEY_TYPE_WEP104
;
1049 ieee
->pairwise_key_type
= alg
;
1050 EnableHWSecurityConfig8192(dev
);
1052 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
1054 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
1056 if (ext
->key_len
== 13)
1057 ieee
->pairwise_key_type
= alg
= KEY_TYPE_WEP104
;
1068 ieee
->group_key_type
= alg
;
1073 broadcast_addr
, //MacAddr
1079 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
1080 write_nic_byte(dev
, 0x173, 1); //fix aes bug
1086 (u8
*)ieee
->ap_mac_addr
, //MacAddr
1100 static int r8192_wx_set_auth(struct net_device
*dev
,
1101 struct iw_request_info
*info
,
1102 union iwreq_data
*data
, char *extra
)
1105 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1106 //printk("====>%s()\n", __FUNCTION__);
1107 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1108 down(&priv
->wx_sem
);
1109 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
1115 static int r8192_wx_set_mlme(struct net_device
*dev
,
1116 struct iw_request_info
*info
,
1117 union iwreq_data
*wrqu
, char *extra
)
1119 //printk("====>%s()\n", __FUNCTION__);
1122 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1123 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1124 down(&priv
->wx_sem
);
1125 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1131 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
1132 struct iw_request_info
*info
,
1133 union iwreq_data
*data
, char *extra
)
1135 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1137 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1138 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1139 down(&priv
->wx_sem
);
1141 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1144 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1151 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1152 union iwreq_data
*wrqu
,char *b
)
1158 static iw_handler r8192_wx_handlers
[] =
1160 NULL
, /* SIOCSIWCOMMIT */
1161 r8192_wx_get_name
, /* SIOCGIWNAME */
1162 dummy
, /* SIOCSIWNWID */
1163 dummy
, /* SIOCGIWNWID */
1164 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1165 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1166 r8192_wx_set_mode
, /* SIOCSIWMODE */
1167 r8192_wx_get_mode
, /* SIOCGIWMODE */
1168 r8192_wx_set_sens
, /* SIOCSIWSENS */
1169 r8192_wx_get_sens
, /* SIOCGIWSENS */
1170 NULL
, /* SIOCSIWRANGE */
1171 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1172 NULL
, /* SIOCSIWPRIV */
1173 NULL
, /* SIOCGIWPRIV */
1174 NULL
, /* SIOCSIWSTATS */
1175 NULL
, /* SIOCGIWSTATS */
1176 dummy
, /* SIOCSIWSPY */
1177 dummy
, /* SIOCGIWSPY */
1178 NULL
, /* SIOCGIWTHRSPY */
1179 NULL
, /* SIOCWIWTHRSPY */
1180 r8192_wx_set_wap
, /* SIOCSIWAP */
1181 r8192_wx_get_wap
, /* SIOCGIWAP */
1182 #if (WIRELESS_EXT >= 18)
1183 r8192_wx_set_mlme
, /* MLME-- */
1187 dummy
, /* SIOCGIWAPLIST -- depricated */
1188 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1189 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1190 r8192_wx_set_essid
, /* SIOCSIWESSID */
1191 r8192_wx_get_essid
, /* SIOCGIWESSID */
1192 dummy
, /* SIOCSIWNICKN */
1193 dummy
, /* SIOCGIWNICKN */
1194 NULL
, /* -- hole -- */
1195 NULL
, /* -- hole -- */
1196 r8192_wx_set_rate
, /* SIOCSIWRATE */
1197 r8192_wx_get_rate
, /* SIOCGIWRATE */
1198 r8192_wx_set_rts
, /* SIOCSIWRTS */
1199 r8192_wx_get_rts
, /* SIOCGIWRTS */
1200 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1201 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1202 dummy
, /* SIOCSIWTXPOW */
1203 dummy
, /* SIOCGIWTXPOW */
1204 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1205 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1206 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1207 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1208 r8192_wx_set_power
, /* SIOCSIWPOWER */
1209 r8192_wx_get_power
, /* SIOCGIWPOWER */
1210 NULL
, /*---hole---*/
1211 NULL
, /*---hole---*/
1212 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1213 NULL
, /* SIOCSIWGENIE */
1214 #if (WIRELESS_EXT >= 18)
1215 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1216 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1217 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1223 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1224 NULL
, /* SIOCSIWPMKSA */
1225 NULL
, /*---hole---*/
1230 static const struct iw_priv_args r8192_private_args
[] = {
1233 SIOCIWFIRSTPRIV
+ 0x0,
1234 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1238 SIOCIWFIRSTPRIV
+ 0x1,
1239 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1243 SIOCIWFIRSTPRIV
+ 0x2,
1244 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1249 SIOCIWFIRSTPRIV
+ 0x3,
1250 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readRF"
1254 SIOCIWFIRSTPRIV
+ 0x4,
1255 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeRF"
1259 SIOCIWFIRSTPRIV
+ 0x5,
1260 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readBB"
1264 SIOCIWFIRSTPRIV
+ 0x6,
1265 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeBB"
1269 SIOCIWFIRSTPRIV
+ 0x7,
1270 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readnicb"
1274 SIOCIWFIRSTPRIV
+ 0x8,
1275 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writenicb"
1279 SIOCIWFIRSTPRIV
+ 0x9,
1280 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "apinfo"
1286 SIOCIWFIRSTPRIV
+ 0x3,
1287 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1294 static iw_handler r8192_private_handler
[] = {
1295 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1296 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1297 // r8192_wx_set_forceassociate,
1298 // r8192_wx_set_beaconinterval,
1299 // r8192_wx_set_monitor_type,
1300 r8192_wx_set_scan_type
,
1304 r8192_wx_write_regs
,
1308 r8192_wx_write_nicb
,
1309 r8192_wx_get_ap_status
1311 r8192_wx_force_reset
,
1314 //#if WIRELESS_EXT >= 17
1315 struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1317 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1318 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1319 struct iw_statistics
* wstats
= &priv
->wstats
;
1323 if(ieee
->state
< IEEE80211_LINKED
)
1325 wstats
->qual
.qual
= 0;
1326 wstats
->qual
.level
= 0;
1327 wstats
->qual
.noise
= 0;
1328 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1329 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1331 wstats
->qual
.updated
= 0x0f;
1336 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1337 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1338 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1339 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1341 wstats
->qual
.level
= tmp_level
;
1342 wstats
->qual
.qual
= tmp_qual
;
1343 wstats
->qual
.noise
= tmp_noise
;
1344 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1345 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1347 wstats
->qual
.updated
= 0x0f;
1354 struct iw_handler_def r8192_wx_handlers_def
={
1355 .standard
= r8192_wx_handlers
,
1356 .num_standard
= sizeof(r8192_wx_handlers
) / sizeof(iw_handler
),
1357 .private = r8192_private_handler
,
1358 .num_private
= sizeof(r8192_private_handler
) / sizeof(iw_handler
),
1359 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1360 #if WIRELESS_EXT >= 17
1361 .get_wireless_stats
= r8192_get_wireless_stats
,
1363 .private_args
= (struct iw_priv_args
*)r8192_private_args
,