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
21 #include <linux/string.h>
23 #include "r8192S_hw.h"
25 #include <linux/string.h>
27 #include "r8192U_hw.h"
35 u32 rtl8180_rates
[] = {1000000,2000000,5500000,11000000,
36 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
43 static int r8192_wx_get_freq(struct net_device
*dev
,
44 struct iw_request_info
*a
,
45 union iwreq_data
*wrqu
, char *b
)
47 struct r8192_priv
*priv
= ieee80211_priv(dev
);
49 return ieee80211_wx_get_freq(priv
->ieee80211
,a
,wrqu
,b
);
55 static int r8192_wx_set_beaconinterval(struct net_device
*dev
, struct iw_request_info
*aa
,
56 union iwreq_data
*wrqu
, char *b
)
58 int *parms
= (int *)b
;
61 struct r8192_priv
*priv
= ieee80211_priv(dev
);
64 DMESG("setting beacon interval to %x",bi
);
66 priv
->ieee80211
->beacon_interval
=bi
;
74 static int r8192_wx_set_forceassociate(struct net_device
*dev
, struct iw_request_info
*aa
,
75 union iwreq_data
*wrqu
, char *extra
)
77 struct r8192_priv
*priv
=ieee80211_priv(dev
);
78 int *parms
= (int *)extra
;
80 priv
->ieee80211
->force_associate
= (parms
[0] > 0);
87 static int r8192_wx_get_mode(struct net_device
*dev
, struct iw_request_info
*a
,
88 union iwreq_data
*wrqu
, char *b
)
90 struct r8192_priv
*priv
=ieee80211_priv(dev
);
92 return ieee80211_wx_get_mode(priv
->ieee80211
,a
,wrqu
,b
);
97 static int r8192_wx_get_rate(struct net_device
*dev
,
98 struct iw_request_info
*info
,
99 union iwreq_data
*wrqu
, char *extra
)
101 struct r8192_priv
*priv
= ieee80211_priv(dev
);
102 return ieee80211_wx_get_rate(priv
->ieee80211
,info
,wrqu
,extra
);
107 static int r8192_wx_set_rate(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_rate(priv
->ieee80211
,info
,wrqu
,extra
);
124 static int r8192_wx_set_rts(struct net_device
*dev
,
125 struct iw_request_info
*info
,
126 union iwreq_data
*wrqu
, char *extra
)
129 struct r8192_priv
*priv
= ieee80211_priv(dev
);
133 ret
= ieee80211_wx_set_rts(priv
->ieee80211
,info
,wrqu
,extra
);
140 static int r8192_wx_get_rts(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
);
145 return ieee80211_wx_get_rts(priv
->ieee80211
,info
,wrqu
,extra
);
148 static int r8192_wx_set_power(struct net_device
*dev
,
149 struct iw_request_info
*info
,
150 union iwreq_data
*wrqu
, char *extra
)
153 struct r8192_priv
*priv
= ieee80211_priv(dev
);
157 ret
= ieee80211_wx_set_power(priv
->ieee80211
,info
,wrqu
,extra
);
164 static int r8192_wx_get_power(struct net_device
*dev
,
165 struct iw_request_info
*info
,
166 union iwreq_data
*wrqu
, char *extra
)
168 struct r8192_priv
*priv
= ieee80211_priv(dev
);
169 return ieee80211_wx_get_power(priv
->ieee80211
,info
,wrqu
,extra
);
173 u16
read_rtl8225(struct net_device
*dev
, u8 addr
);
174 void write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
175 u32
john_read_rtl8225(struct net_device
*dev
, u8 adr
);
176 void _write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
178 static int r8192_wx_read_regs(struct net_device
*dev
,
179 struct iw_request_info
*info
,
180 union iwreq_data
*wrqu
, char *extra
)
182 struct r8192_priv
*priv
= ieee80211_priv(dev
);
189 get_user(addr
,(u8
*)wrqu
->data
.pointer
);
190 data1
= read_rtl8225(dev
, addr
);
191 wrqu
->data
.length
= data1
;
198 static int r8192_wx_write_regs(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(addr
, (u8
*)wrqu
->data
.pointer
);
208 write_rtl8225(dev
, addr
, wrqu
->data
.length
);
215 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
216 u8
rtl8187_read_phy(struct net_device
*dev
,u8 adr
, u32 data
);
218 static int r8192_wx_read_bb(struct net_device
*dev
,
219 struct iw_request_info
*info
,
220 union iwreq_data
*wrqu
, char *extra
)
222 struct r8192_priv
*priv
= ieee80211_priv(dev
);
226 for(i
=0;i
<12;i
++) printk("%8x\n", read_cam(dev
, i
) );
231 databb
= rtl8187_read_phy(dev
, (u8
)wrqu
->data
.length
, 0x00000000);
232 wrqu
->data
.length
= databb
;
238 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
239 static int r8192_wx_write_bb(struct net_device
*dev
,
240 struct iw_request_info
*info
,
241 union iwreq_data
*wrqu
, char *extra
)
243 struct r8192_priv
*priv
= ieee80211_priv(dev
);
248 get_user(databb
, (u8
*)wrqu
->data
.pointer
);
249 rtl8187_write_phy(dev
, wrqu
->data
.length
, databb
);
257 static int r8192_wx_write_nicb(struct net_device
*dev
,
258 struct iw_request_info
*info
,
259 union iwreq_data
*wrqu
, char *extra
)
261 struct r8192_priv
*priv
= ieee80211_priv(dev
);
266 get_user(addr
, (u32
*)wrqu
->data
.pointer
);
267 write_nic_byte(dev
, addr
, wrqu
->data
.length
);
273 static int r8192_wx_read_nicb(struct net_device
*dev
,
274 struct iw_request_info
*info
,
275 union iwreq_data
*wrqu
, char *extra
)
277 struct r8192_priv
*priv
= ieee80211_priv(dev
);
283 get_user(addr
,(u32
*)wrqu
->data
.pointer
);
284 data1
= read_nic_byte(dev
, addr
);
285 wrqu
->data
.length
= data1
;
291 static int r8192_wx_get_ap_status(struct net_device
*dev
,
292 struct iw_request_info
*info
,
293 union iwreq_data
*wrqu
, char *extra
)
295 struct r8192_priv
*priv
= ieee80211_priv(dev
);
296 struct ieee80211_device
*ieee
= priv
->ieee80211
;
297 struct ieee80211_network
*target
;
302 //count the length of input ssid
303 for(name_len
=0 ; ((char*)wrqu
->data
.pointer
)[name_len
]!='\0' ; name_len
++);
305 //search for the correspoding info which is received
306 list_for_each_entry(target
, &ieee
->network_list
, list
) {
307 if ( (target
->ssid_len
== name_len
) &&
308 (strncmp(target
->ssid
, (char*)wrqu
->data
.pointer
, name_len
)==0)){
309 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0 )
310 //set flags=1 to indicate this ap is WPA
311 wrqu
->data
.flags
= 1;
312 else wrqu
->data
.flags
= 0;
327 static int r8192_wx_null(struct net_device
*dev
,
328 struct iw_request_info
*info
,
329 union iwreq_data
*wrqu
, char *extra
)
334 static int r8192_wx_force_reset(struct net_device
*dev
,
335 struct iw_request_info
*info
,
336 union iwreq_data
*wrqu
, char *extra
)
338 struct r8192_priv
*priv
= ieee80211_priv(dev
);
342 printk("%s(): force reset ! extra is %d\n",__FUNCTION__
, *extra
);
343 priv
->force_reset
= *extra
;
350 static int r8191su_wx_get_firm_version(struct net_device
*dev
,
351 struct iw_request_info
*info
,
352 struct iw_param
*wrqu
, char *extra
)
354 struct r8192_priv
*priv
= ieee80211_priv(dev
);
355 u16 firmware_version
;
358 firmware_version
= priv
->pFirmware
->FirmwareVersion
;
359 wrqu
->value
= firmware_version
;
369 static int r8192_wx_set_rawtx(struct net_device
*dev
,
370 struct iw_request_info
*info
,
371 union iwreq_data
*wrqu
, char *extra
)
373 struct r8192_priv
*priv
= ieee80211_priv(dev
);
378 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
386 static int r8192_wx_set_crcmon(struct net_device
*dev
,
387 struct iw_request_info
*info
,
388 union iwreq_data
*wrqu
, char *extra
)
390 struct r8192_priv
*priv
= ieee80211_priv(dev
);
391 int *parms
= (int *)extra
;
392 int enable
= (parms
[0] > 0);
393 short prev
= priv
->crcmon
;
402 DMESG("bad CRC in monitor mode are %s",
403 priv
->crcmon
? "accepted" : "rejected");
405 if(prev
!= priv
->crcmon
&& priv
->up
){
415 static int r8192_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
416 union iwreq_data
*wrqu
, char *b
)
418 struct r8192_priv
*priv
= ieee80211_priv(dev
);
422 ret
= ieee80211_wx_set_mode(priv
->ieee80211
,a
,wrqu
,b
);
424 rtl8192_set_rxconf(dev
);
430 struct iw_range_with_scan_capa
432 /* Informative stuff (to choose between different interface) */
433 __u32 throughput
; /* To give an idea... */
434 /* In theory this value should be the maximum benchmarked
435 * TCP/IP throughput, because with most of these devices the
436 * bit rate is meaningless (overhead an co) to estimate how
437 * fast the connection will go and pick the fastest one.
438 * I suggest people to play with Netperf or any benchmark...
441 /* NWID (or domain id) */
442 __u32 min_nwid
; /* Minimal NWID we are able to set */
443 __u32 max_nwid
; /* Maximal NWID we are able to set */
445 /* Old Frequency (backward compat - moved lower ) */
446 __u16 old_num_channels
;
447 __u8 old_num_frequency
;
449 /* Scan capabilities */
452 static int rtl8180_wx_get_range(struct net_device
*dev
,
453 struct iw_request_info
*info
,
454 union iwreq_data
*wrqu
, char *extra
)
456 struct iw_range
*range
= (struct iw_range
*)extra
;
457 struct iw_range_with_scan_capa
* tmp
= (struct iw_range_with_scan_capa
*)range
;
458 struct r8192_priv
*priv
= ieee80211_priv(dev
);
462 wrqu
->data
.length
= sizeof(*range
);
463 memset(range
, 0, sizeof(*range
));
465 /* Let's try to keep this struct in the same order as in
466 * linux/include/wireless.h
469 /* TODO: See what values we can set, and remove the ones we can't
470 * set, or fill them with some default data.
473 /* ~5 Mb/s real (802.11b) */
474 range
->throughput
= 5 * 1000 * 1000;
476 // TODO: Not used in 802.11b?
477 // range->min_nwid; /* Minimal NWID we are able to set */
478 // TODO: Not used in 802.11b?
479 // range->max_nwid; /* Maximal NWID we are able to set */
481 /* Old Frequency (backward compat - moved lower ) */
482 // range->old_num_channels;
483 // range->old_num_frequency;
484 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
485 if(priv
->rf_set_sens
!= NULL
)
486 range
->sensitivity
= priv
->max_sens
; /* signal level threshold range */
488 range
->max_qual
.qual
= 100;
489 /* TODO: Find real max RSSI and stick here */
490 range
->max_qual
.level
= 0;
491 range
->max_qual
.noise
= -98;
492 range
->max_qual
.updated
= 7; /* Updated all three */
494 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
495 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
496 range
->avg_qual
.level
= 20 + -98;
497 range
->avg_qual
.noise
= 0;
498 range
->avg_qual
.updated
= 7; /* Updated all three */
500 range
->num_bitrates
= RATE_COUNT
;
502 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++) {
503 range
->bitrate
[i
] = rtl8180_rates
[i
];
506 range
->min_frag
= MIN_FRAG_THRESHOLD
;
507 range
->max_frag
= MAX_FRAG_THRESHOLD
;
510 range
->max_pmp
= 5000000;
512 range
->max_pmt
= 65535*1000;
513 range
->pmp_flags
= IW_POWER_PERIOD
;
514 range
->pmt_flags
= IW_POWER_TIMEOUT
;
515 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
517 range
->we_version_compiled
= WIRELESS_EXT
;
518 range
->we_version_source
= 16;
520 // range->retry_capa; /* What retry options are supported */
521 // range->retry_flags; /* How to decode max/min retry limit */
522 // range->r_time_flags; /* How to decode max/min retry life */
523 // range->min_retry; /* Minimal number of retries */
524 // range->max_retry; /* Maximal number of retries */
525 // range->min_r_time; /* Minimal retry lifetime */
526 // range->max_r_time; /* Maximal retry lifetime */
529 for (i
= 0, val
= 0; i
< 14; i
++) {
531 // Include only legal frequencies for some countries
533 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
535 if ((priv
->ieee80211
->channel_map
)[i
+1]) {
537 range
->freq
[val
].i
= i
+ 1;
538 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
539 range
->freq
[val
].e
= 1;
542 // FIXME: do we need to set anything for channels
546 if (val
== IW_MAX_FREQUENCIES
)
549 range
->num_frequency
= val
;
550 range
->num_channels
= val
;
551 #if WIRELESS_EXT > 17
552 range
->enc_capa
= IW_ENC_CAPA_WPA
|IW_ENC_CAPA_WPA2
|
553 IW_ENC_CAPA_CIPHER_TKIP
|IW_ENC_CAPA_CIPHER_CCMP
;
555 tmp
->scan_capa
= 0x01;
560 static int r8192_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
561 union iwreq_data
*wrqu
, char *b
)
563 struct r8192_priv
*priv
= ieee80211_priv(dev
);
564 struct ieee80211_device
* ieee
= priv
->ieee80211
;
567 if(!priv
->up
) return -ENETDOWN
;
569 if (priv
->ieee80211
->LinkDetectInfo
.bBusyTraffic
== true)
571 #if WIRELESS_EXT > 17
572 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
)
574 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
577 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
578 ieee
->current_network
.ssid_len
= req
->essid_len
;
579 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
580 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
586 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
587 priv
->ieee80211
->scanning
= 0;
588 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
592 ret
= ieee80211_wx_set_scan(priv
->ieee80211
,a
,wrqu
,b
);
598 static int r8192_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
599 union iwreq_data
*wrqu
, char *b
)
603 struct r8192_priv
*priv
= ieee80211_priv(dev
);
605 if(!priv
->up
) return -ENETDOWN
;
609 ret
= ieee80211_wx_get_scan(priv
->ieee80211
,a
,wrqu
,b
);
616 static int r8192_wx_set_essid(struct net_device
*dev
,
617 struct iw_request_info
*a
,
618 union iwreq_data
*wrqu
, char *b
)
620 struct r8192_priv
*priv
= ieee80211_priv(dev
);
624 ret
= ieee80211_wx_set_essid(priv
->ieee80211
,a
,wrqu
,b
);
634 static int r8192_wx_get_essid(struct net_device
*dev
,
635 struct iw_request_info
*a
,
636 union iwreq_data
*wrqu
, char *b
)
639 struct r8192_priv
*priv
= ieee80211_priv(dev
);
643 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
651 static int r8192_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
652 union iwreq_data
*wrqu
, char *b
)
655 struct r8192_priv
*priv
= ieee80211_priv(dev
);
659 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
665 static int r8192_wx_get_name(struct net_device
*dev
,
666 struct iw_request_info
*info
,
667 union iwreq_data
*wrqu
, char *extra
)
669 struct r8192_priv
*priv
= ieee80211_priv(dev
);
670 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
674 static int r8192_wx_set_frag(struct net_device
*dev
,
675 struct iw_request_info
*info
,
676 union iwreq_data
*wrqu
, char *extra
)
678 struct r8192_priv
*priv
= ieee80211_priv(dev
);
680 if (wrqu
->frag
.disabled
)
681 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
683 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
684 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
687 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
694 static int r8192_wx_get_frag(struct net_device
*dev
,
695 struct iw_request_info
*info
,
696 union iwreq_data
*wrqu
, char *extra
)
698 struct r8192_priv
*priv
= ieee80211_priv(dev
);
700 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
701 wrqu
->frag
.fixed
= 0; /* no auto select */
702 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
708 static int r8192_wx_set_wap(struct net_device
*dev
,
709 struct iw_request_info
*info
,
710 union iwreq_data
*awrq
,
715 struct r8192_priv
*priv
= ieee80211_priv(dev
);
716 // struct sockaddr *temp = (struct sockaddr *)awrq;
719 ret
= ieee80211_wx_set_wap(priv
->ieee80211
,info
,awrq
,extra
);
728 static int r8192_wx_get_wap(struct net_device
*dev
,
729 struct iw_request_info
*info
,
730 union iwreq_data
*wrqu
, char *extra
)
732 struct r8192_priv
*priv
= ieee80211_priv(dev
);
734 return ieee80211_wx_get_wap(priv
->ieee80211
,info
,wrqu
,extra
);
738 static int r8192_wx_get_enc(struct net_device
*dev
,
739 struct iw_request_info
*info
,
740 union iwreq_data
*wrqu
, char *key
)
742 struct r8192_priv
*priv
= ieee80211_priv(dev
);
744 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
747 static int r8192_wx_set_enc(struct net_device
*dev
,
748 struct iw_request_info
*info
,
749 union iwreq_data
*wrqu
, char *key
)
751 struct r8192_priv
*priv
= ieee80211_priv(dev
);
752 struct ieee80211_device
*ieee
= priv
->ieee80211
;
756 u32 hwkey
[4]={0,0,0,0};
759 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
760 u8 zero_addr
[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
761 {0x00,0x00,0x00,0x00,0x00,0x01},
762 {0x00,0x00,0x00,0x00,0x00,0x02},
763 {0x00,0x00,0x00,0x00,0x00,0x03} };
766 if(!priv
->up
) return -ENETDOWN
;
770 RT_TRACE(COMP_SEC
, "Setting SW wep key");
771 ret
= ieee80211_wx_set_encode(priv
->ieee80211
,info
,wrqu
,key
);
777 //sometimes, the length is zero while we do not type key value
778 if(wrqu
->encoding
.length
!=0){
780 for(i
=0 ; i
<4 ; i
++){
781 hwkey
[i
] |= key
[4*i
+0]&mask
;
782 if(i
==1&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
783 if(i
==3&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
784 hwkey
[i
] |= (key
[4*i
+1]&mask
)<<8;
785 hwkey
[i
] |= (key
[4*i
+2]&mask
)<<16;
786 hwkey
[i
] |= (key
[4*i
+3]&mask
)<<24;
789 #define CONF_WEP40 0x4
790 #define CONF_WEP104 0x14
792 switch(wrqu
->encoding
.flags
& IW_ENCODE_INDEX
){
793 case 0: key_idx
= ieee
->tx_keyidx
; break;
794 case 1: key_idx
= 0; break;
795 case 2: key_idx
= 1; break;
796 case 3: key_idx
= 2; break;
797 case 4: key_idx
= 3; break;
801 if(wrqu
->encoding
.length
==0x5){
802 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
803 EnableHWSecurityConfig8192(dev
);
808 KEY_TYPE_WEP40
, //KeyType
815 else if(wrqu
->encoding
.length
==0xd){
816 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
817 EnableHWSecurityConfig8192(dev
);
822 KEY_TYPE_WEP104
, //KeyType
828 else printk("wrong type in WEP, not WEP40 and WEP104\n");
836 static int r8192_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
837 iwreq_data
*wrqu
, char *p
){
839 struct r8192_priv
*priv
= ieee80211_priv(dev
);
843 priv
->ieee80211
->active_scan
= mode
;
850 static int r8192_wx_set_retry(struct net_device
*dev
,
851 struct iw_request_info
*info
,
852 union iwreq_data
*wrqu
, char *extra
)
854 struct r8192_priv
*priv
= ieee80211_priv(dev
);
859 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
860 wrqu
->retry
.disabled
){
864 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)){
869 if(wrqu
->retry
.value
> R8180_MAX_RETRY
){
873 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
874 priv
->retry_rts
= wrqu
->retry
.value
;
875 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
878 priv
->retry_data
= wrqu
->retry
.value
;
879 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
883 * We might try to write directly the TX config register
884 * or to restart just the (R)TX process.
885 * I'm unsure if whole reset is really needed
891 rtl8180_rtx_disable(dev);
892 rtl8180_rx_enable(dev);
893 rtl8180_tx_enable(dev);
903 static int r8192_wx_get_retry(struct net_device
*dev
,
904 struct iw_request_info
*info
,
905 union iwreq_data
*wrqu
, char *extra
)
907 struct r8192_priv
*priv
= ieee80211_priv(dev
);
910 wrqu
->retry
.disabled
= 0; /* can't be disabled */
912 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
916 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
917 wrqu
->retry
.flags
= IW_RETRY_LIMIT
| IW_RETRY_MAX
;
918 wrqu
->retry
.value
= priv
->retry_rts
;
920 wrqu
->retry
.flags
= IW_RETRY_LIMIT
| IW_RETRY_MIN
;
921 wrqu
->retry
.value
= priv
->retry_data
;
923 //printk("returning %d",wrqu->retry.value);
929 static int r8192_wx_get_sens(struct net_device
*dev
,
930 struct iw_request_info
*info
,
931 union iwreq_data
*wrqu
, char *extra
)
933 struct r8192_priv
*priv
= ieee80211_priv(dev
);
934 if(priv
->rf_set_sens
== NULL
)
935 return -1; /* we have not this support for this radio */
936 wrqu
->sens
.value
= priv
->sens
;
941 static int r8192_wx_set_sens(struct net_device
*dev
,
942 struct iw_request_info
*info
,
943 union iwreq_data
*wrqu
, char *extra
)
946 struct r8192_priv
*priv
= ieee80211_priv(dev
);
950 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
951 if(priv
->rf_set_sens
== NULL
) {
952 err
= -1; /* we have not this support for this radio */
955 if(priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
956 priv
->sens
= wrqu
->sens
.value
;
966 #if (WIRELESS_EXT >= 18)
968 static int r8192_wx_get_enc_ext(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
);
974 ret
= ieee80211_wx_get_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
978 //hw security need to reorganized.
979 static int r8192_wx_set_enc_ext(struct net_device
*dev
,
980 struct iw_request_info
*info
,
981 union iwreq_data
*wrqu
, char *extra
)
984 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
985 struct r8192_priv
*priv
= ieee80211_priv(dev
);
986 struct ieee80211_device
* ieee
= priv
->ieee80211
;
987 //printk("===>%s()\n", __FUNCTION__);
991 ret
= ieee80211_wx_set_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
994 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
997 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
998 struct iw_point
*encoding
= &wrqu
->encoding
;
1000 static u8 CAM_CONST_ADDR
[4][6] = {
1001 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1002 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1003 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1004 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1006 u8 idx
= 0, alg
= 0, group
= 0;
1007 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
1008 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
1010 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
1011 CamResetAllEntry(dev
);
1014 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;
1015 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1018 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
1020 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
1022 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
1023 alg
= KEY_TYPE_WEP104
;
1024 ieee
->pairwise_key_type
= alg
;
1025 EnableHWSecurityConfig8192(dev
);
1027 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
1029 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
1042 ieee
->group_key_type
= alg
;
1047 broadcast_addr
, //MacAddr
1057 (u8
*)ieee
->ap_mac_addr
, //MacAddr
1072 static int r8192_wx_set_auth(struct net_device
*dev
,
1073 struct iw_request_info
*info
,
1074 union iwreq_data
*data
, char *extra
)
1077 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1078 //printk("====>%s()\n", __FUNCTION__);
1079 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1080 down(&priv
->wx_sem
);
1081 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
1087 static int r8192_wx_set_mlme(struct net_device
*dev
,
1088 struct iw_request_info
*info
,
1089 union iwreq_data
*wrqu
, char *extra
)
1091 //printk("====>%s()\n", __FUNCTION__);
1094 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1095 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1096 down(&priv
->wx_sem
);
1097 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1104 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
1105 struct iw_request_info
*info
,
1106 union iwreq_data
*data
, char *extra
)
1108 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1110 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1111 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1112 down(&priv
->wx_sem
);
1114 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1117 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1124 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1125 union iwreq_data
*wrqu
,char *b
)
1131 static iw_handler r8192_wx_handlers
[] =
1133 NULL
, /* SIOCSIWCOMMIT */
1134 r8192_wx_get_name
, /* SIOCGIWNAME */
1135 dummy
, /* SIOCSIWNWID */
1136 dummy
, /* SIOCGIWNWID */
1137 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1138 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1139 r8192_wx_set_mode
, /* SIOCSIWMODE */
1140 r8192_wx_get_mode
, /* SIOCGIWMODE */
1141 r8192_wx_set_sens
, /* SIOCSIWSENS */
1142 r8192_wx_get_sens
, /* SIOCGIWSENS */
1143 NULL
, /* SIOCSIWRANGE */
1144 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1145 NULL
, /* SIOCSIWPRIV */
1146 NULL
, /* SIOCGIWPRIV */
1147 NULL
, /* SIOCSIWSTATS */
1148 NULL
, /* SIOCGIWSTATS */
1149 dummy
, /* SIOCSIWSPY */
1150 dummy
, /* SIOCGIWSPY */
1151 NULL
, /* SIOCGIWTHRSPY */
1152 NULL
, /* SIOCWIWTHRSPY */
1153 r8192_wx_set_wap
, /* SIOCSIWAP */
1154 r8192_wx_get_wap
, /* SIOCGIWAP */
1155 #if (WIRELESS_EXT >= 18)
1156 r8192_wx_set_mlme
, /* MLME-- */
1160 dummy
, /* SIOCGIWAPLIST -- depricated */
1161 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1162 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1163 r8192_wx_set_essid
, /* SIOCSIWESSID */
1164 r8192_wx_get_essid
, /* SIOCGIWESSID */
1165 dummy
, /* SIOCSIWNICKN */
1166 dummy
, /* SIOCGIWNICKN */
1167 NULL
, /* -- hole -- */
1168 NULL
, /* -- hole -- */
1169 r8192_wx_set_rate
, /* SIOCSIWRATE */
1170 r8192_wx_get_rate
, /* SIOCGIWRATE */
1171 r8192_wx_set_rts
, /* SIOCSIWRTS */
1172 r8192_wx_get_rts
, /* SIOCGIWRTS */
1173 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1174 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1175 dummy
, /* SIOCSIWTXPOW */
1176 dummy
, /* SIOCGIWTXPOW */
1177 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1178 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1179 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1180 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1181 r8192_wx_set_power
, /* SIOCSIWPOWER */
1182 r8192_wx_get_power
, /* SIOCGIWPOWER */
1183 NULL
, /*---hole---*/
1184 NULL
, /*---hole---*/
1185 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1186 NULL
, /* SIOCSIWGENIE */
1188 #if (WIRELESS_EXT >= 18)
1189 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1190 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1191 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1192 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1199 NULL
, /* SIOCSIWPMKSA */
1200 NULL
, /*---hole---*/
1205 static const struct iw_priv_args r8192_private_args
[] = {
1208 SIOCIWFIRSTPRIV
+ 0x0,
1209 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1213 SIOCIWFIRSTPRIV
+ 0x1,
1214 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1218 SIOCIWFIRSTPRIV
+ 0x2,
1219 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1224 SIOCIWFIRSTPRIV
+ 0x3,
1225 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readRF"
1229 SIOCIWFIRSTPRIV
+ 0x4,
1230 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeRF"
1234 SIOCIWFIRSTPRIV
+ 0x5,
1235 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readBB"
1239 SIOCIWFIRSTPRIV
+ 0x6,
1240 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeBB"
1244 SIOCIWFIRSTPRIV
+ 0x7,
1245 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readnicb"
1249 SIOCIWFIRSTPRIV
+ 0x8,
1250 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writenicb"
1254 SIOCIWFIRSTPRIV
+ 0x9,
1255 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "apinfo"
1261 SIOCIWFIRSTPRIV
+ 0x3,
1262 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1268 SIOCIWFIRSTPRIV
+ 0x5,
1269 IW_PRIV_TYPE_NONE
, IW_PRIV_TYPE_INT
|IW_PRIV_SIZE_FIXED
|1,
1276 static iw_handler r8192_private_handler
[] = {
1277 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1278 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1279 // r8192_wx_set_forceassociate,
1280 // r8192_wx_set_beaconinterval,
1281 // r8192_wx_set_monitor_type,
1282 r8192_wx_set_scan_type
,
1286 r8192_wx_write_regs
,
1290 r8192_wx_write_nicb
,
1291 r8192_wx_get_ap_status
,
1293 r8192_wx_force_reset
,
1296 (iw_handler
)r8191su_wx_get_firm_version
,
1300 //#if WIRELESS_EXT >= 17
1301 struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1303 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1304 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1305 struct iw_statistics
* wstats
= &priv
->wstats
;
1309 if(ieee
->state
< IEEE80211_LINKED
)
1311 wstats
->qual
.qual
= 0;
1312 wstats
->qual
.level
= 0;
1313 wstats
->qual
.noise
= 0;
1314 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1315 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1317 wstats
->qual
.updated
= 0x0f;
1322 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1323 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1324 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1325 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1327 wstats
->qual
.level
= tmp_level
;
1328 wstats
->qual
.qual
= tmp_qual
;
1329 wstats
->qual
.noise
= tmp_noise
;
1330 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1331 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1333 wstats
->qual
.updated
= 0x0f;
1340 struct iw_handler_def r8192_wx_handlers_def
={
1341 .standard
= r8192_wx_handlers
,
1342 .num_standard
= sizeof(r8192_wx_handlers
) / sizeof(iw_handler
),
1343 .private = r8192_private_handler
,
1344 .num_private
= sizeof(r8192_private_handler
) / sizeof(iw_handler
),
1345 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1346 #if WIRELESS_EXT >= 17
1347 .get_wireless_stats
= r8192_get_wireless_stats
,
1349 .private_args
= (struct iw_priv_args
*)r8192_private_args
,