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 "r8192S_hw.h"
24 #include "ieee80211/dot11d.h"
27 u32 rtl8180_rates
[] = {1000000,2000000,5500000,11000000,
28 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
35 static int r8192_wx_get_freq(struct net_device
*dev
,
36 struct iw_request_info
*a
,
37 union iwreq_data
*wrqu
, char *b
)
39 struct r8192_priv
*priv
= ieee80211_priv(dev
);
41 return ieee80211_wx_get_freq(priv
->ieee80211
,a
,wrqu
,b
);
44 static int r8192_wx_get_mode(struct net_device
*dev
, 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_mode(priv
->ieee80211
,a
,wrqu
,b
);
54 static int r8192_wx_get_rate(struct net_device
*dev
,
55 struct iw_request_info
*info
,
56 union iwreq_data
*wrqu
, char *extra
)
58 struct r8192_priv
*priv
= ieee80211_priv(dev
);
59 return ieee80211_wx_get_rate(priv
->ieee80211
,info
,wrqu
,extra
);
64 static int r8192_wx_set_rate(struct net_device
*dev
,
65 struct iw_request_info
*info
,
66 union iwreq_data
*wrqu
, char *extra
)
69 struct r8192_priv
*priv
= ieee80211_priv(dev
);
73 ret
= ieee80211_wx_set_rate(priv
->ieee80211
,info
,wrqu
,extra
);
81 static int r8192_wx_set_rts(struct net_device
*dev
,
82 struct iw_request_info
*info
,
83 union iwreq_data
*wrqu
, char *extra
)
86 struct r8192_priv
*priv
= ieee80211_priv(dev
);
90 ret
= ieee80211_wx_set_rts(priv
->ieee80211
,info
,wrqu
,extra
);
97 static int r8192_wx_get_rts(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_rts(priv
->ieee80211
,info
,wrqu
,extra
);
105 static int r8192_wx_set_power(struct net_device
*dev
,
106 struct iw_request_info
*info
,
107 union iwreq_data
*wrqu
, char *extra
)
110 struct r8192_priv
*priv
= ieee80211_priv(dev
);
114 ret
= ieee80211_wx_set_power(priv
->ieee80211
,info
,wrqu
,extra
);
121 static int r8192_wx_get_power(struct net_device
*dev
,
122 struct iw_request_info
*info
,
123 union iwreq_data
*wrqu
, char *extra
)
125 struct r8192_priv
*priv
= ieee80211_priv(dev
);
126 return ieee80211_wx_get_power(priv
->ieee80211
,info
,wrqu
,extra
);
130 u16
read_rtl8225(struct net_device
*dev
, u8 addr
);
131 void write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
132 u32
john_read_rtl8225(struct net_device
*dev
, u8 adr
);
133 void _write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
135 static int r8192_wx_read_regs(struct net_device
*dev
,
136 struct iw_request_info
*info
,
137 union iwreq_data
*wrqu
, char *extra
)
139 struct r8192_priv
*priv
= ieee80211_priv(dev
);
146 get_user(addr
,(u8
*)wrqu
->data
.pointer
);
147 data1
= read_rtl8225(dev
, addr
);
148 wrqu
->data
.length
= data1
;
155 static int r8192_wx_write_regs(struct net_device
*dev
,
156 struct iw_request_info
*info
,
157 union iwreq_data
*wrqu
, char *extra
)
159 struct r8192_priv
*priv
= ieee80211_priv(dev
);
164 get_user(addr
, (u8
*)wrqu
->data
.pointer
);
165 write_rtl8225(dev
, addr
, wrqu
->data
.length
);
172 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
173 u8
rtl8187_read_phy(struct net_device
*dev
,u8 adr
, u32 data
);
175 static int r8192_wx_read_bb(struct net_device
*dev
,
176 struct iw_request_info
*info
,
177 union iwreq_data
*wrqu
, char *extra
)
179 struct r8192_priv
*priv
= ieee80211_priv(dev
);
184 databb
= rtl8187_read_phy(dev
, (u8
)wrqu
->data
.length
, 0x00000000);
185 wrqu
->data
.length
= databb
;
191 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
192 static int r8192_wx_write_bb(struct net_device
*dev
,
193 struct iw_request_info
*info
,
194 union iwreq_data
*wrqu
, char *extra
)
196 struct r8192_priv
*priv
= ieee80211_priv(dev
);
201 get_user(databb
, (u8
*)wrqu
->data
.pointer
);
202 rtl8187_write_phy(dev
, wrqu
->data
.length
, databb
);
210 static int r8192_wx_write_nicb(struct net_device
*dev
,
211 struct iw_request_info
*info
,
212 union iwreq_data
*wrqu
, char *extra
)
214 struct r8192_priv
*priv
= ieee80211_priv(dev
);
219 get_user(addr
, (u32
*)wrqu
->data
.pointer
);
220 write_nic_byte(dev
, addr
, wrqu
->data
.length
);
226 static int r8192_wx_read_nicb(struct net_device
*dev
,
227 struct iw_request_info
*info
,
228 union iwreq_data
*wrqu
, char *extra
)
230 struct r8192_priv
*priv
= ieee80211_priv(dev
);
236 get_user(addr
,(u32
*)wrqu
->data
.pointer
);
237 data1
= read_nic_byte(dev
, addr
);
238 wrqu
->data
.length
= data1
;
244 static int r8192_wx_get_ap_status(struct net_device
*dev
,
245 struct iw_request_info
*info
,
246 union iwreq_data
*wrqu
, char *extra
)
248 struct r8192_priv
*priv
= ieee80211_priv(dev
);
249 struct ieee80211_device
*ieee
= priv
->ieee80211
;
250 struct ieee80211_network
*target
;
255 //count the length of input ssid
256 for(name_len
=0 ; ((char*)wrqu
->data
.pointer
)[name_len
]!='\0' ; name_len
++);
258 //search for the correspoding info which is received
259 list_for_each_entry(target
, &ieee
->network_list
, list
) {
260 if ( (target
->ssid_len
== name_len
) &&
261 (strncmp(target
->ssid
, (char*)wrqu
->data
.pointer
, name_len
)==0)){
262 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0 )
263 //set flags=1 to indicate this ap is WPA
264 wrqu
->data
.flags
= 1;
265 else wrqu
->data
.flags
= 0;
279 static int r8192_wx_force_reset(struct net_device
*dev
,
280 struct iw_request_info
*info
,
281 union iwreq_data
*wrqu
, char *extra
)
283 struct r8192_priv
*priv
= ieee80211_priv(dev
);
287 printk("%s(): force reset ! extra is %d\n",__FUNCTION__
, *extra
);
288 priv
->force_reset
= *extra
;
294 static int r8191su_wx_get_firm_version(struct net_device
*dev
,
295 struct iw_request_info
*info
,
296 struct iw_param
*wrqu
, char *extra
)
298 struct r8192_priv
*priv
= ieee80211_priv(dev
);
299 u16 firmware_version
;
302 firmware_version
= priv
->pFirmware
->FirmwareVersion
;
303 wrqu
->value
= firmware_version
;
312 static int r8192_wx_set_rawtx(struct net_device
*dev
,
313 struct iw_request_info
*info
,
314 union iwreq_data
*wrqu
, char *extra
)
316 struct r8192_priv
*priv
= ieee80211_priv(dev
);
321 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
329 static int r8192_wx_set_crcmon(struct net_device
*dev
,
330 struct iw_request_info
*info
,
331 union iwreq_data
*wrqu
, char *extra
)
333 struct r8192_priv
*priv
= ieee80211_priv(dev
);
334 int *parms
= (int *)extra
;
335 int enable
= (parms
[0] > 0);
336 short prev
= priv
->crcmon
;
345 DMESG("bad CRC in monitor mode are %s",
346 priv
->crcmon
? "accepted" : "rejected");
348 if(prev
!= priv
->crcmon
&& priv
->up
){
358 static int r8192_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
359 union iwreq_data
*wrqu
, char *b
)
361 struct r8192_priv
*priv
= ieee80211_priv(dev
);
365 ret
= ieee80211_wx_set_mode(priv
->ieee80211
,a
,wrqu
,b
);
367 rtl8192_set_rxconf(dev
);
373 struct iw_range_with_scan_capa
375 /* Informative stuff (to choose between different interface) */
376 __u32 throughput
; /* To give an idea... */
377 /* In theory this value should be the maximum benchmarked
378 * TCP/IP throughput, because with most of these devices the
379 * bit rate is meaningless (overhead an co) to estimate how
380 * fast the connection will go and pick the fastest one.
381 * I suggest people to play with Netperf or any benchmark...
384 /* NWID (or domain id) */
385 __u32 min_nwid
; /* Minimal NWID we are able to set */
386 __u32 max_nwid
; /* Maximal NWID we are able to set */
388 /* Old Frequency (backward compat - moved lower ) */
389 __u16 old_num_channels
;
390 __u8 old_num_frequency
;
392 /* Scan capabilities */
395 static int rtl8180_wx_get_range(struct net_device
*dev
,
396 struct iw_request_info
*info
,
397 union iwreq_data
*wrqu
, char *extra
)
399 struct iw_range
*range
= (struct iw_range
*)extra
;
400 struct iw_range_with_scan_capa
* tmp
= (struct iw_range_with_scan_capa
*)range
;
401 struct r8192_priv
*priv
= ieee80211_priv(dev
);
405 wrqu
->data
.length
= sizeof(*range
);
406 memset(range
, 0, sizeof(*range
));
408 /* Let's try to keep this struct in the same order as in
409 * linux/include/wireless.h
412 /* TODO: See what values we can set, and remove the ones we can't
413 * set, or fill them with some default data.
416 /* ~5 Mb/s real (802.11b) */
417 range
->throughput
= 5 * 1000 * 1000;
419 // TODO: Not used in 802.11b?
420 // range->min_nwid; /* Minimal NWID we are able to set */
421 // TODO: Not used in 802.11b?
422 // range->max_nwid; /* Maximal NWID we are able to set */
424 /* Old Frequency (backward compat - moved lower ) */
425 // range->old_num_channels;
426 // range->old_num_frequency;
427 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
428 if(priv
->rf_set_sens
!= NULL
)
429 range
->sensitivity
= priv
->max_sens
; /* signal level threshold range */
431 range
->max_qual
.qual
= 100;
432 /* TODO: Find real max RSSI and stick here */
433 range
->max_qual
.level
= 0;
434 range
->max_qual
.noise
= -98;
435 range
->max_qual
.updated
= 7; /* Updated all three */
437 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
438 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
439 range
->avg_qual
.level
= 20 + -98;
440 range
->avg_qual
.noise
= 0;
441 range
->avg_qual
.updated
= 7; /* Updated all three */
443 range
->num_bitrates
= RATE_COUNT
;
445 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++) {
446 range
->bitrate
[i
] = rtl8180_rates
[i
];
449 range
->min_frag
= MIN_FRAG_THRESHOLD
;
450 range
->max_frag
= MAX_FRAG_THRESHOLD
;
453 range
->max_pmp
= 5000000;
455 range
->max_pmt
= 65535*1000;
456 range
->pmp_flags
= IW_POWER_PERIOD
;
457 range
->pmt_flags
= IW_POWER_TIMEOUT
;
458 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
460 range
->we_version_compiled
= WIRELESS_EXT
;
461 range
->we_version_source
= 16;
463 // range->retry_capa; /* What retry options are supported */
464 // range->retry_flags; /* How to decode max/min retry limit */
465 // range->r_time_flags; /* How to decode max/min retry life */
466 // range->min_retry; /* Minimal number of retries */
467 // range->max_retry; /* Maximal number of retries */
468 // range->min_r_time; /* Minimal retry lifetime */
469 // range->max_r_time; /* Maximal retry lifetime */
472 for (i
= 0, val
= 0; i
< 14; i
++) {
474 // Include only legal frequencies for some countries
475 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
476 range
->freq
[val
].i
= i
+ 1;
477 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
478 range
->freq
[val
].e
= 1;
481 // FIXME: do we need to set anything for channels
485 if (val
== IW_MAX_FREQUENCIES
)
488 range
->num_frequency
= val
;
489 range
->num_channels
= val
;
490 range
->enc_capa
= IW_ENC_CAPA_WPA
|IW_ENC_CAPA_WPA2
|
491 IW_ENC_CAPA_CIPHER_TKIP
|IW_ENC_CAPA_CIPHER_CCMP
;
492 tmp
->scan_capa
= 0x01;
497 static int r8192_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
498 union iwreq_data
*wrqu
, char *b
)
500 struct r8192_priv
*priv
= ieee80211_priv(dev
);
501 struct ieee80211_device
* ieee
= priv
->ieee80211
;
504 if(!priv
->up
) return -ENETDOWN
;
506 if (priv
->ieee80211
->LinkDetectInfo
.bBusyTraffic
== true)
509 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
)
511 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
514 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
515 ieee
->current_network
.ssid_len
= req
->essid_len
;
516 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
517 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
522 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
523 priv
->ieee80211
->scanning
= 0;
524 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
528 ret
= ieee80211_wx_set_scan(priv
->ieee80211
,a
,wrqu
,b
);
534 static int r8192_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
535 union iwreq_data
*wrqu
, char *b
)
539 struct r8192_priv
*priv
= ieee80211_priv(dev
);
541 if(!priv
->up
) return -ENETDOWN
;
545 ret
= ieee80211_wx_get_scan(priv
->ieee80211
,a
,wrqu
,b
);
552 static int r8192_wx_set_essid(struct net_device
*dev
,
553 struct iw_request_info
*a
,
554 union iwreq_data
*wrqu
, char *b
)
556 struct r8192_priv
*priv
= ieee80211_priv(dev
);
560 ret
= ieee80211_wx_set_essid(priv
->ieee80211
,a
,wrqu
,b
);
570 static int r8192_wx_get_essid(struct net_device
*dev
,
571 struct iw_request_info
*a
,
572 union iwreq_data
*wrqu
, char *b
)
575 struct r8192_priv
*priv
= ieee80211_priv(dev
);
579 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
587 static int r8192_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
588 union iwreq_data
*wrqu
, char *b
)
591 struct r8192_priv
*priv
= ieee80211_priv(dev
);
595 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
601 static int r8192_wx_get_name(struct net_device
*dev
,
602 struct iw_request_info
*info
,
603 union iwreq_data
*wrqu
, char *extra
)
605 struct r8192_priv
*priv
= ieee80211_priv(dev
);
606 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
610 static int r8192_wx_set_frag(struct net_device
*dev
,
611 struct iw_request_info
*info
,
612 union iwreq_data
*wrqu
, char *extra
)
614 struct r8192_priv
*priv
= ieee80211_priv(dev
);
616 if (wrqu
->frag
.disabled
)
617 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
619 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
620 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
623 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
630 static int r8192_wx_get_frag(struct net_device
*dev
,
631 struct iw_request_info
*info
,
632 union iwreq_data
*wrqu
, char *extra
)
634 struct r8192_priv
*priv
= ieee80211_priv(dev
);
636 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
637 wrqu
->frag
.fixed
= 0; /* no auto select */
638 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
644 static int r8192_wx_set_wap(struct net_device
*dev
,
645 struct iw_request_info
*info
,
646 union iwreq_data
*awrq
,
651 struct r8192_priv
*priv
= ieee80211_priv(dev
);
652 // struct sockaddr *temp = (struct sockaddr *)awrq;
655 ret
= ieee80211_wx_set_wap(priv
->ieee80211
,info
,awrq
,extra
);
664 static int r8192_wx_get_wap(struct net_device
*dev
,
665 struct iw_request_info
*info
,
666 union iwreq_data
*wrqu
, char *extra
)
668 struct r8192_priv
*priv
= ieee80211_priv(dev
);
670 return ieee80211_wx_get_wap(priv
->ieee80211
,info
,wrqu
,extra
);
674 static int r8192_wx_get_enc(struct net_device
*dev
,
675 struct iw_request_info
*info
,
676 union iwreq_data
*wrqu
, char *key
)
678 struct r8192_priv
*priv
= ieee80211_priv(dev
);
680 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
683 static int r8192_wx_set_enc(struct net_device
*dev
,
684 struct iw_request_info
*info
,
685 union iwreq_data
*wrqu
, char *key
)
687 struct r8192_priv
*priv
= ieee80211_priv(dev
);
688 struct ieee80211_device
*ieee
= priv
->ieee80211
;
692 u32 hwkey
[4]={0,0,0,0};
695 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
696 u8 zero_addr
[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
697 {0x00,0x00,0x00,0x00,0x00,0x01},
698 {0x00,0x00,0x00,0x00,0x00,0x02},
699 {0x00,0x00,0x00,0x00,0x00,0x03} };
702 if(!priv
->up
) return -ENETDOWN
;
706 RT_TRACE(COMP_SEC
, "Setting SW wep key");
707 ret
= ieee80211_wx_set_encode(priv
->ieee80211
,info
,wrqu
,key
);
713 //sometimes, the length is zero while we do not type key value
714 if(wrqu
->encoding
.length
!=0){
716 for(i
=0 ; i
<4 ; i
++){
717 hwkey
[i
] |= key
[4*i
+0]&mask
;
718 if(i
==1&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
719 if(i
==3&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
720 hwkey
[i
] |= (key
[4*i
+1]&mask
)<<8;
721 hwkey
[i
] |= (key
[4*i
+2]&mask
)<<16;
722 hwkey
[i
] |= (key
[4*i
+3]&mask
)<<24;
725 #define CONF_WEP40 0x4
726 #define CONF_WEP104 0x14
728 switch(wrqu
->encoding
.flags
& IW_ENCODE_INDEX
){
729 case 0: key_idx
= ieee
->tx_keyidx
; break;
730 case 1: key_idx
= 0; break;
731 case 2: key_idx
= 1; break;
732 case 3: key_idx
= 2; break;
733 case 4: key_idx
= 3; break;
737 if(wrqu
->encoding
.length
==0x5){
738 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
739 EnableHWSecurityConfig8192(dev
);
744 KEY_TYPE_WEP40
, //KeyType
751 else if(wrqu
->encoding
.length
==0xd){
752 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
753 EnableHWSecurityConfig8192(dev
);
758 KEY_TYPE_WEP104
, //KeyType
764 else printk("wrong type in WEP, not WEP40 and WEP104\n");
772 static int r8192_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
773 iwreq_data
*wrqu
, char *p
){
775 struct r8192_priv
*priv
= ieee80211_priv(dev
);
779 priv
->ieee80211
->active_scan
= mode
;
786 static int r8192_wx_set_retry(struct net_device
*dev
,
787 struct iw_request_info
*info
,
788 union iwreq_data
*wrqu
, char *extra
)
790 struct r8192_priv
*priv
= ieee80211_priv(dev
);
795 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
796 wrqu
->retry
.disabled
){
800 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)){
805 if(wrqu
->retry
.value
> R8180_MAX_RETRY
){
809 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
810 priv
->retry_rts
= wrqu
->retry
.value
;
811 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
814 priv
->retry_data
= wrqu
->retry
.value
;
815 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
819 * We might try to write directly the TX config register
820 * or to restart just the (R)TX process.
821 * I'm unsure if whole reset is really needed
827 rtl8180_rtx_disable(dev);
828 rtl8180_rx_enable(dev);
829 rtl8180_tx_enable(dev);
839 static int r8192_wx_get_retry(struct net_device
*dev
,
840 struct iw_request_info
*info
,
841 union iwreq_data
*wrqu
, char *extra
)
843 struct r8192_priv
*priv
= ieee80211_priv(dev
);
846 wrqu
->retry
.disabled
= 0; /* can't be disabled */
848 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
852 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
853 wrqu
->retry
.flags
= IW_RETRY_LIMIT
| IW_RETRY_MAX
;
854 wrqu
->retry
.value
= priv
->retry_rts
;
856 wrqu
->retry
.flags
= IW_RETRY_LIMIT
| IW_RETRY_MIN
;
857 wrqu
->retry
.value
= priv
->retry_data
;
859 //printk("returning %d",wrqu->retry.value);
865 static int r8192_wx_get_sens(struct net_device
*dev
,
866 struct iw_request_info
*info
,
867 union iwreq_data
*wrqu
, char *extra
)
869 struct r8192_priv
*priv
= ieee80211_priv(dev
);
870 if(priv
->rf_set_sens
== NULL
)
871 return -1; /* we have not this support for this radio */
872 wrqu
->sens
.value
= priv
->sens
;
877 static int r8192_wx_set_sens(struct net_device
*dev
,
878 struct iw_request_info
*info
,
879 union iwreq_data
*wrqu
, char *extra
)
882 struct r8192_priv
*priv
= ieee80211_priv(dev
);
886 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
887 if(priv
->rf_set_sens
== NULL
) {
888 err
= -1; /* we have not this support for this radio */
891 if(priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
892 priv
->sens
= wrqu
->sens
.value
;
902 //hw security need to reorganized.
903 static int r8192_wx_set_enc_ext(struct net_device
*dev
,
904 struct iw_request_info
*info
,
905 union iwreq_data
*wrqu
, char *extra
)
908 struct r8192_priv
*priv
= ieee80211_priv(dev
);
909 struct ieee80211_device
* ieee
= priv
->ieee80211
;
910 //printk("===>%s()\n", __FUNCTION__);
914 ret
= ieee80211_wx_set_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
917 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
920 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
921 struct iw_point
*encoding
= &wrqu
->encoding
;
922 u8 idx
= 0, alg
= 0, group
= 0;
923 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
924 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
926 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
927 CamResetAllEntry(dev
);
930 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;
931 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
934 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
936 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
938 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
939 alg
= KEY_TYPE_WEP104
;
940 ieee
->pairwise_key_type
= alg
;
941 EnableHWSecurityConfig8192(dev
);
943 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
945 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
958 ieee
->group_key_type
= alg
;
963 broadcast_addr
, //MacAddr
973 (u8
*)ieee
->ap_mac_addr
, //MacAddr
986 static int r8192_wx_set_auth(struct net_device
*dev
,
987 struct iw_request_info
*info
,
988 union iwreq_data
*data
, char *extra
)
992 //printk("====>%s()\n", __FUNCTION__);
993 struct r8192_priv
*priv
= ieee80211_priv(dev
);
995 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
1000 static int r8192_wx_set_mlme(struct net_device
*dev
,
1001 struct iw_request_info
*info
,
1002 union iwreq_data
*wrqu
, char *extra
)
1004 //printk("====>%s()\n", __FUNCTION__);
1007 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1008 down(&priv
->wx_sem
);
1009 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1014 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
1015 struct iw_request_info
*info
,
1016 union iwreq_data
*data
, char *extra
)
1018 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1020 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1021 down(&priv
->wx_sem
);
1023 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1026 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1032 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1033 union iwreq_data
*wrqu
,char *b
)
1039 static iw_handler r8192_wx_handlers
[] =
1041 NULL
, /* SIOCSIWCOMMIT */
1042 r8192_wx_get_name
, /* SIOCGIWNAME */
1043 dummy
, /* SIOCSIWNWID */
1044 dummy
, /* SIOCGIWNWID */
1045 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1046 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1047 r8192_wx_set_mode
, /* SIOCSIWMODE */
1048 r8192_wx_get_mode
, /* SIOCGIWMODE */
1049 r8192_wx_set_sens
, /* SIOCSIWSENS */
1050 r8192_wx_get_sens
, /* SIOCGIWSENS */
1051 NULL
, /* SIOCSIWRANGE */
1052 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1053 NULL
, /* SIOCSIWPRIV */
1054 NULL
, /* SIOCGIWPRIV */
1055 NULL
, /* SIOCSIWSTATS */
1056 NULL
, /* SIOCGIWSTATS */
1057 dummy
, /* SIOCSIWSPY */
1058 dummy
, /* SIOCGIWSPY */
1059 NULL
, /* SIOCGIWTHRSPY */
1060 NULL
, /* SIOCWIWTHRSPY */
1061 r8192_wx_set_wap
, /* SIOCSIWAP */
1062 r8192_wx_get_wap
, /* SIOCGIWAP */
1063 r8192_wx_set_mlme
, /* MLME-- */
1064 dummy
, /* SIOCGIWAPLIST -- depricated */
1065 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1066 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1067 r8192_wx_set_essid
, /* SIOCSIWESSID */
1068 r8192_wx_get_essid
, /* SIOCGIWESSID */
1069 dummy
, /* SIOCSIWNICKN */
1070 dummy
, /* SIOCGIWNICKN */
1071 NULL
, /* -- hole -- */
1072 NULL
, /* -- hole -- */
1073 r8192_wx_set_rate
, /* SIOCSIWRATE */
1074 r8192_wx_get_rate
, /* SIOCGIWRATE */
1075 r8192_wx_set_rts
, /* SIOCSIWRTS */
1076 r8192_wx_get_rts
, /* SIOCGIWRTS */
1077 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1078 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1079 dummy
, /* SIOCSIWTXPOW */
1080 dummy
, /* SIOCGIWTXPOW */
1081 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1082 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1083 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1084 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1085 r8192_wx_set_power
, /* SIOCSIWPOWER */
1086 r8192_wx_get_power
, /* SIOCGIWPOWER */
1087 NULL
, /*---hole---*/
1088 NULL
, /*---hole---*/
1089 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1090 NULL
, /* SIOCSIWGENIE */
1092 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1093 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1094 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1095 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1096 NULL
, /* SIOCSIWPMKSA */
1097 NULL
, /*---hole---*/
1102 static const struct iw_priv_args r8192_private_args
[] = {
1105 SIOCIWFIRSTPRIV
+ 0x0,
1106 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1110 SIOCIWFIRSTPRIV
+ 0x1,
1111 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1115 SIOCIWFIRSTPRIV
+ 0x2,
1116 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1121 SIOCIWFIRSTPRIV
+ 0x3,
1122 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readRF"
1126 SIOCIWFIRSTPRIV
+ 0x4,
1127 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeRF"
1131 SIOCIWFIRSTPRIV
+ 0x5,
1132 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readBB"
1136 SIOCIWFIRSTPRIV
+ 0x6,
1137 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeBB"
1141 SIOCIWFIRSTPRIV
+ 0x7,
1142 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readnicb"
1146 SIOCIWFIRSTPRIV
+ 0x8,
1147 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writenicb"
1151 SIOCIWFIRSTPRIV
+ 0x9,
1152 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "apinfo"
1158 SIOCIWFIRSTPRIV
+ 0x3,
1159 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1164 SIOCIWFIRSTPRIV
+ 0x5,
1165 IW_PRIV_TYPE_NONE
, IW_PRIV_TYPE_INT
|IW_PRIV_SIZE_FIXED
|1,
1171 static iw_handler r8192_private_handler
[] = {
1172 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1173 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1174 // r8192_wx_set_forceassociate,
1175 // r8192_wx_set_beaconinterval,
1176 // r8192_wx_set_monitor_type,
1177 r8192_wx_set_scan_type
,
1181 r8192_wx_write_regs
,
1185 r8192_wx_write_nicb
,
1186 r8192_wx_get_ap_status
,
1188 r8192_wx_force_reset
,
1190 (iw_handler
)r8191su_wx_get_firm_version
,
1193 struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1195 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1196 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1197 struct iw_statistics
* wstats
= &priv
->wstats
;
1201 if(ieee
->state
< IEEE80211_LINKED
)
1203 wstats
->qual
.qual
= 0;
1204 wstats
->qual
.level
= 0;
1205 wstats
->qual
.noise
= 0;
1206 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1210 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1211 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1212 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1213 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1215 wstats
->qual
.level
= tmp_level
;
1216 wstats
->qual
.qual
= tmp_qual
;
1217 wstats
->qual
.noise
= tmp_noise
;
1218 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1222 struct iw_handler_def r8192_wx_handlers_def
={
1223 .standard
= r8192_wx_handlers
,
1224 .num_standard
= ARRAY_SIZE(r8192_wx_handlers
),
1225 .private = r8192_private_handler
,
1226 .num_private
= ARRAY_SIZE(r8192_private_handler
),
1227 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1228 .get_wireless_stats
= r8192_get_wireless_stats
,
1229 .private_args
= (struct iw_priv_args
*)r8192_private_args
,