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 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1012 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1014 down(&priv
->wx_sem
);
1015 ret
= ieee80211_wx_set_encode_ext(ieee
, info
, wrqu
, extra
);
1018 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1021 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1022 struct iw_point
*encoding
= &wrqu
->encoding
;
1024 static u8 CAM_CONST_ADDR
[4][6] = {
1025 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1026 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1027 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1028 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1030 u8 idx
= 0, alg
= 0, group
= 0;
1031 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
1032 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
1034 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
1035 CamResetAllEntry(dev
);
1038 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;
1039 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1042 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
1044 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
1046 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
1047 alg
= KEY_TYPE_WEP104
;
1048 ieee
->pairwise_key_type
= alg
;
1049 EnableHWSecurityConfig8192(dev
);
1051 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
1053 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
1055 if (ext
->key_len
== 13)
1056 ieee
->pairwise_key_type
= alg
= KEY_TYPE_WEP104
;
1067 ieee
->group_key_type
= alg
;
1072 broadcast_addr
, //MacAddr
1078 if ((ieee
->pairwise_key_type
== KEY_TYPE_CCMP
) && ieee
->pHTInfo
->bCurrentHTSupport
){
1079 write_nic_byte(dev
, 0x173, 1); //fix aes bug
1085 (u8
*)ieee
->ap_mac_addr
, //MacAddr
1098 static int r8192_wx_set_auth(struct net_device
*dev
,
1099 struct iw_request_info
*info
,
1100 union iwreq_data
*data
, char *extra
)
1103 //printk("====>%s()\n", __FUNCTION__);
1104 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1105 down(&priv
->wx_sem
);
1106 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
1111 static int r8192_wx_set_mlme(struct net_device
*dev
,
1112 struct iw_request_info
*info
,
1113 union iwreq_data
*wrqu
, char *extra
)
1115 //printk("====>%s()\n", __FUNCTION__);
1118 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1119 down(&priv
->wx_sem
);
1120 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1125 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
1126 struct iw_request_info
*info
,
1127 union iwreq_data
*data
, char *extra
)
1129 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1131 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1132 down(&priv
->wx_sem
);
1133 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1135 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1139 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1140 union iwreq_data
*wrqu
,char *b
)
1146 static iw_handler r8192_wx_handlers
[] =
1148 NULL
, /* SIOCSIWCOMMIT */
1149 r8192_wx_get_name
, /* SIOCGIWNAME */
1150 dummy
, /* SIOCSIWNWID */
1151 dummy
, /* SIOCGIWNWID */
1152 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1153 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1154 r8192_wx_set_mode
, /* SIOCSIWMODE */
1155 r8192_wx_get_mode
, /* SIOCGIWMODE */
1156 r8192_wx_set_sens
, /* SIOCSIWSENS */
1157 r8192_wx_get_sens
, /* SIOCGIWSENS */
1158 NULL
, /* SIOCSIWRANGE */
1159 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1160 NULL
, /* SIOCSIWPRIV */
1161 NULL
, /* SIOCGIWPRIV */
1162 NULL
, /* SIOCSIWSTATS */
1163 NULL
, /* SIOCGIWSTATS */
1164 dummy
, /* SIOCSIWSPY */
1165 dummy
, /* SIOCGIWSPY */
1166 NULL
, /* SIOCGIWTHRSPY */
1167 NULL
, /* SIOCWIWTHRSPY */
1168 r8192_wx_set_wap
, /* SIOCSIWAP */
1169 r8192_wx_get_wap
, /* SIOCGIWAP */
1170 #if (WIRELESS_EXT >= 18)
1171 r8192_wx_set_mlme
, /* MLME-- */
1175 dummy
, /* SIOCGIWAPLIST -- depricated */
1176 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1177 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1178 r8192_wx_set_essid
, /* SIOCSIWESSID */
1179 r8192_wx_get_essid
, /* SIOCGIWESSID */
1180 dummy
, /* SIOCSIWNICKN */
1181 dummy
, /* SIOCGIWNICKN */
1182 NULL
, /* -- hole -- */
1183 NULL
, /* -- hole -- */
1184 r8192_wx_set_rate
, /* SIOCSIWRATE */
1185 r8192_wx_get_rate
, /* SIOCGIWRATE */
1186 r8192_wx_set_rts
, /* SIOCSIWRTS */
1187 r8192_wx_get_rts
, /* SIOCGIWRTS */
1188 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1189 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1190 dummy
, /* SIOCSIWTXPOW */
1191 dummy
, /* SIOCGIWTXPOW */
1192 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1193 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1194 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1195 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1196 r8192_wx_set_power
, /* SIOCSIWPOWER */
1197 r8192_wx_get_power
, /* SIOCGIWPOWER */
1198 NULL
, /*---hole---*/
1199 NULL
, /*---hole---*/
1200 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1201 NULL
, /* SIOCSIWGENIE */
1202 #if (WIRELESS_EXT >= 18)
1203 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1204 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1205 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1211 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1212 NULL
, /* SIOCSIWPMKSA */
1213 NULL
, /*---hole---*/
1218 static const struct iw_priv_args r8192_private_args
[] = {
1221 SIOCIWFIRSTPRIV
+ 0x0,
1222 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1226 SIOCIWFIRSTPRIV
+ 0x1,
1227 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1231 SIOCIWFIRSTPRIV
+ 0x2,
1232 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1237 SIOCIWFIRSTPRIV
+ 0x3,
1238 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readRF"
1242 SIOCIWFIRSTPRIV
+ 0x4,
1243 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeRF"
1247 SIOCIWFIRSTPRIV
+ 0x5,
1248 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readBB"
1252 SIOCIWFIRSTPRIV
+ 0x6,
1253 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeBB"
1257 SIOCIWFIRSTPRIV
+ 0x7,
1258 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readnicb"
1262 SIOCIWFIRSTPRIV
+ 0x8,
1263 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writenicb"
1267 SIOCIWFIRSTPRIV
+ 0x9,
1268 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "apinfo"
1274 SIOCIWFIRSTPRIV
+ 0x3,
1275 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1282 static iw_handler r8192_private_handler
[] = {
1283 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1284 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1285 // r8192_wx_set_forceassociate,
1286 // r8192_wx_set_beaconinterval,
1287 // r8192_wx_set_monitor_type,
1288 r8192_wx_set_scan_type
,
1292 r8192_wx_write_regs
,
1296 r8192_wx_write_nicb
,
1297 r8192_wx_get_ap_status
1299 r8192_wx_force_reset
,
1302 //#if WIRELESS_EXT >= 17
1303 struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1305 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1306 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1307 struct iw_statistics
* wstats
= &priv
->wstats
;
1311 if(ieee
->state
< IEEE80211_LINKED
)
1313 wstats
->qual
.qual
= 0;
1314 wstats
->qual
.level
= 0;
1315 wstats
->qual
.noise
= 0;
1316 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1320 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1321 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1322 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1323 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1325 wstats
->qual
.level
= tmp_level
;
1326 wstats
->qual
.qual
= tmp_qual
;
1327 wstats
->qual
.noise
= tmp_noise
;
1328 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1334 struct iw_handler_def r8192_wx_handlers_def
={
1335 .standard
= r8192_wx_handlers
,
1336 .num_standard
= sizeof(r8192_wx_handlers
) / sizeof(iw_handler
),
1337 .private = r8192_private_handler
,
1338 .num_private
= sizeof(r8192_private_handler
) / sizeof(iw_handler
),
1339 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1340 #if WIRELESS_EXT >= 17
1341 .get_wireless_stats
= r8192_get_wireless_stats
,
1343 .private_args
= (struct iw_priv_args
*)r8192_private_args
,