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"
30 #include "ieee80211/dot11d.h"
33 u32 rtl8180_rates
[] = {1000000,2000000,5500000,11000000,
34 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
41 static int r8192_wx_get_freq(struct net_device
*dev
,
42 struct iw_request_info
*a
,
43 union iwreq_data
*wrqu
, char *b
)
45 struct r8192_priv
*priv
= ieee80211_priv(dev
);
47 return ieee80211_wx_get_freq(priv
->ieee80211
,a
,wrqu
,b
);
53 static int r8192_wx_set_beaconinterval(struct net_device
*dev
, struct iw_request_info
*aa
,
54 union iwreq_data
*wrqu
, char *b
)
56 int *parms
= (int *)b
;
59 struct r8192_priv
*priv
= ieee80211_priv(dev
);
62 DMESG("setting beacon interval to %x",bi
);
64 priv
->ieee80211
->beacon_interval
=bi
;
72 static int r8192_wx_set_forceassociate(struct net_device
*dev
, struct iw_request_info
*aa
,
73 union iwreq_data
*wrqu
, char *extra
)
75 struct r8192_priv
*priv
=ieee80211_priv(dev
);
76 int *parms
= (int *)extra
;
78 priv
->ieee80211
->force_associate
= (parms
[0] > 0);
85 static int r8192_wx_get_mode(struct net_device
*dev
, struct iw_request_info
*a
,
86 union iwreq_data
*wrqu
, char *b
)
88 struct r8192_priv
*priv
=ieee80211_priv(dev
);
90 return ieee80211_wx_get_mode(priv
->ieee80211
,a
,wrqu
,b
);
95 static int r8192_wx_get_rate(struct net_device
*dev
,
96 struct iw_request_info
*info
,
97 union iwreq_data
*wrqu
, char *extra
)
99 struct r8192_priv
*priv
= ieee80211_priv(dev
);
100 return ieee80211_wx_get_rate(priv
->ieee80211
,info
,wrqu
,extra
);
105 static int r8192_wx_set_rate(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_rate(priv
->ieee80211
,info
,wrqu
,extra
);
122 static int r8192_wx_set_rts(struct net_device
*dev
,
123 struct iw_request_info
*info
,
124 union iwreq_data
*wrqu
, char *extra
)
127 struct r8192_priv
*priv
= ieee80211_priv(dev
);
131 ret
= ieee80211_wx_set_rts(priv
->ieee80211
,info
,wrqu
,extra
);
138 static int r8192_wx_get_rts(struct net_device
*dev
,
139 struct iw_request_info
*info
,
140 union iwreq_data
*wrqu
, char *extra
)
142 struct r8192_priv
*priv
= ieee80211_priv(dev
);
143 return ieee80211_wx_get_rts(priv
->ieee80211
,info
,wrqu
,extra
);
146 static int r8192_wx_set_power(struct net_device
*dev
,
147 struct iw_request_info
*info
,
148 union iwreq_data
*wrqu
, char *extra
)
151 struct r8192_priv
*priv
= ieee80211_priv(dev
);
155 ret
= ieee80211_wx_set_power(priv
->ieee80211
,info
,wrqu
,extra
);
162 static int r8192_wx_get_power(struct net_device
*dev
,
163 struct iw_request_info
*info
,
164 union iwreq_data
*wrqu
, char *extra
)
166 struct r8192_priv
*priv
= ieee80211_priv(dev
);
167 return ieee80211_wx_get_power(priv
->ieee80211
,info
,wrqu
,extra
);
171 u16
read_rtl8225(struct net_device
*dev
, u8 addr
);
172 void write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
173 u32
john_read_rtl8225(struct net_device
*dev
, u8 adr
);
174 void _write_rtl8225(struct net_device
*dev
, u8 adr
, u16 data
);
176 static int r8192_wx_read_regs(struct net_device
*dev
,
177 struct iw_request_info
*info
,
178 union iwreq_data
*wrqu
, char *extra
)
180 struct r8192_priv
*priv
= ieee80211_priv(dev
);
187 get_user(addr
,(u8
*)wrqu
->data
.pointer
);
188 data1
= read_rtl8225(dev
, addr
);
189 wrqu
->data
.length
= data1
;
196 static int r8192_wx_write_regs(struct net_device
*dev
,
197 struct iw_request_info
*info
,
198 union iwreq_data
*wrqu
, char *extra
)
200 struct r8192_priv
*priv
= ieee80211_priv(dev
);
205 get_user(addr
, (u8
*)wrqu
->data
.pointer
);
206 write_rtl8225(dev
, addr
, wrqu
->data
.length
);
213 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
214 u8
rtl8187_read_phy(struct net_device
*dev
,u8 adr
, u32 data
);
216 static int r8192_wx_read_bb(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
);
224 for(i
=0;i
<12;i
++) printk("%8x\n", read_cam(dev
, i
) );
229 databb
= rtl8187_read_phy(dev
, (u8
)wrqu
->data
.length
, 0x00000000);
230 wrqu
->data
.length
= databb
;
236 void rtl8187_write_phy(struct net_device
*dev
, u8 adr
, u32 data
);
237 static int r8192_wx_write_bb(struct net_device
*dev
,
238 struct iw_request_info
*info
,
239 union iwreq_data
*wrqu
, char *extra
)
241 struct r8192_priv
*priv
= ieee80211_priv(dev
);
246 get_user(databb
, (u8
*)wrqu
->data
.pointer
);
247 rtl8187_write_phy(dev
, wrqu
->data
.length
, databb
);
255 static int r8192_wx_write_nicb(struct net_device
*dev
,
256 struct iw_request_info
*info
,
257 union iwreq_data
*wrqu
, char *extra
)
259 struct r8192_priv
*priv
= ieee80211_priv(dev
);
264 get_user(addr
, (u32
*)wrqu
->data
.pointer
);
265 write_nic_byte(dev
, addr
, wrqu
->data
.length
);
271 static int r8192_wx_read_nicb(struct net_device
*dev
,
272 struct iw_request_info
*info
,
273 union iwreq_data
*wrqu
, char *extra
)
275 struct r8192_priv
*priv
= ieee80211_priv(dev
);
281 get_user(addr
,(u32
*)wrqu
->data
.pointer
);
282 data1
= read_nic_byte(dev
, addr
);
283 wrqu
->data
.length
= data1
;
289 static int r8192_wx_get_ap_status(struct net_device
*dev
,
290 struct iw_request_info
*info
,
291 union iwreq_data
*wrqu
, char *extra
)
293 struct r8192_priv
*priv
= ieee80211_priv(dev
);
294 struct ieee80211_device
*ieee
= priv
->ieee80211
;
295 struct ieee80211_network
*target
;
300 //count the length of input ssid
301 for(name_len
=0 ; ((char*)wrqu
->data
.pointer
)[name_len
]!='\0' ; name_len
++);
303 //search for the correspoding info which is received
304 list_for_each_entry(target
, &ieee
->network_list
, list
) {
305 if ( (target
->ssid_len
== name_len
) &&
306 (strncmp(target
->ssid
, (char*)wrqu
->data
.pointer
, name_len
)==0)){
307 if(target
->wpa_ie_len
>0 || target
->rsn_ie_len
>0 )
308 //set flags=1 to indicate this ap is WPA
309 wrqu
->data
.flags
= 1;
310 else wrqu
->data
.flags
= 0;
325 static int r8192_wx_null(struct net_device
*dev
,
326 struct iw_request_info
*info
,
327 union iwreq_data
*wrqu
, char *extra
)
332 static int r8192_wx_force_reset(struct net_device
*dev
,
333 struct iw_request_info
*info
,
334 union iwreq_data
*wrqu
, char *extra
)
336 struct r8192_priv
*priv
= ieee80211_priv(dev
);
340 printk("%s(): force reset ! extra is %d\n",__FUNCTION__
, *extra
);
341 priv
->force_reset
= *extra
;
348 static int r8191su_wx_get_firm_version(struct net_device
*dev
,
349 struct iw_request_info
*info
,
350 struct iw_param
*wrqu
, char *extra
)
352 struct r8192_priv
*priv
= ieee80211_priv(dev
);
353 u16 firmware_version
;
356 firmware_version
= priv
->pFirmware
->FirmwareVersion
;
357 wrqu
->value
= firmware_version
;
367 static int r8192_wx_set_rawtx(struct net_device
*dev
,
368 struct iw_request_info
*info
,
369 union iwreq_data
*wrqu
, char *extra
)
371 struct r8192_priv
*priv
= ieee80211_priv(dev
);
376 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
384 static int r8192_wx_set_crcmon(struct net_device
*dev
,
385 struct iw_request_info
*info
,
386 union iwreq_data
*wrqu
, char *extra
)
388 struct r8192_priv
*priv
= ieee80211_priv(dev
);
389 int *parms
= (int *)extra
;
390 int enable
= (parms
[0] > 0);
391 short prev
= priv
->crcmon
;
400 DMESG("bad CRC in monitor mode are %s",
401 priv
->crcmon
? "accepted" : "rejected");
403 if(prev
!= priv
->crcmon
&& priv
->up
){
413 static int r8192_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
414 union iwreq_data
*wrqu
, char *b
)
416 struct r8192_priv
*priv
= ieee80211_priv(dev
);
420 ret
= ieee80211_wx_set_mode(priv
->ieee80211
,a
,wrqu
,b
);
422 rtl8192_set_rxconf(dev
);
428 struct iw_range_with_scan_capa
430 /* Informative stuff (to choose between different interface) */
431 __u32 throughput
; /* To give an idea... */
432 /* In theory this value should be the maximum benchmarked
433 * TCP/IP throughput, because with most of these devices the
434 * bit rate is meaningless (overhead an co) to estimate how
435 * fast the connection will go and pick the fastest one.
436 * I suggest people to play with Netperf or any benchmark...
439 /* NWID (or domain id) */
440 __u32 min_nwid
; /* Minimal NWID we are able to set */
441 __u32 max_nwid
; /* Maximal NWID we are able to set */
443 /* Old Frequency (backward compat - moved lower ) */
444 __u16 old_num_channels
;
445 __u8 old_num_frequency
;
447 /* Scan capabilities */
450 static int rtl8180_wx_get_range(struct net_device
*dev
,
451 struct iw_request_info
*info
,
452 union iwreq_data
*wrqu
, char *extra
)
454 struct iw_range
*range
= (struct iw_range
*)extra
;
455 struct iw_range_with_scan_capa
* tmp
= (struct iw_range_with_scan_capa
*)range
;
456 struct r8192_priv
*priv
= ieee80211_priv(dev
);
460 wrqu
->data
.length
= sizeof(*range
);
461 memset(range
, 0, sizeof(*range
));
463 /* Let's try to keep this struct in the same order as in
464 * linux/include/wireless.h
467 /* TODO: See what values we can set, and remove the ones we can't
468 * set, or fill them with some default data.
471 /* ~5 Mb/s real (802.11b) */
472 range
->throughput
= 5 * 1000 * 1000;
474 // TODO: Not used in 802.11b?
475 // range->min_nwid; /* Minimal NWID we are able to set */
476 // TODO: Not used in 802.11b?
477 // range->max_nwid; /* Maximal NWID we are able to set */
479 /* Old Frequency (backward compat - moved lower ) */
480 // range->old_num_channels;
481 // range->old_num_frequency;
482 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
483 if(priv
->rf_set_sens
!= NULL
)
484 range
->sensitivity
= priv
->max_sens
; /* signal level threshold range */
486 range
->max_qual
.qual
= 100;
487 /* TODO: Find real max RSSI and stick here */
488 range
->max_qual
.level
= 0;
489 range
->max_qual
.noise
= -98;
490 range
->max_qual
.updated
= 7; /* Updated all three */
492 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
493 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
494 range
->avg_qual
.level
= 20 + -98;
495 range
->avg_qual
.noise
= 0;
496 range
->avg_qual
.updated
= 7; /* Updated all three */
498 range
->num_bitrates
= RATE_COUNT
;
500 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++) {
501 range
->bitrate
[i
] = rtl8180_rates
[i
];
504 range
->min_frag
= MIN_FRAG_THRESHOLD
;
505 range
->max_frag
= MAX_FRAG_THRESHOLD
;
508 range
->max_pmp
= 5000000;
510 range
->max_pmt
= 65535*1000;
511 range
->pmp_flags
= IW_POWER_PERIOD
;
512 range
->pmt_flags
= IW_POWER_TIMEOUT
;
513 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
515 range
->we_version_compiled
= WIRELESS_EXT
;
516 range
->we_version_source
= 16;
518 // range->retry_capa; /* What retry options are supported */
519 // range->retry_flags; /* How to decode max/min retry limit */
520 // range->r_time_flags; /* How to decode max/min retry life */
521 // range->min_retry; /* Minimal number of retries */
522 // range->max_retry; /* Maximal number of retries */
523 // range->min_r_time; /* Minimal retry lifetime */
524 // range->max_r_time; /* Maximal retry lifetime */
527 for (i
= 0, val
= 0; i
< 14; i
++) {
529 // Include only legal frequencies for some countries
530 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
531 range
->freq
[val
].i
= i
+ 1;
532 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
533 range
->freq
[val
].e
= 1;
536 // FIXME: do we need to set anything for channels
540 if (val
== IW_MAX_FREQUENCIES
)
543 range
->num_frequency
= val
;
544 range
->num_channels
= val
;
545 range
->enc_capa
= IW_ENC_CAPA_WPA
|IW_ENC_CAPA_WPA2
|
546 IW_ENC_CAPA_CIPHER_TKIP
|IW_ENC_CAPA_CIPHER_CCMP
;
547 tmp
->scan_capa
= 0x01;
552 static int r8192_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
553 union iwreq_data
*wrqu
, char *b
)
555 struct r8192_priv
*priv
= ieee80211_priv(dev
);
556 struct ieee80211_device
* ieee
= priv
->ieee80211
;
559 if(!priv
->up
) return -ENETDOWN
;
561 if (priv
->ieee80211
->LinkDetectInfo
.bBusyTraffic
== true)
564 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
)
566 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
569 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
570 ieee
->current_network
.ssid_len
= req
->essid_len
;
571 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
572 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
577 if(priv
->ieee80211
->state
!= IEEE80211_LINKED
){
578 priv
->ieee80211
->scanning
= 0;
579 ieee80211_softmac_scan_syncro(priv
->ieee80211
);
583 ret
= ieee80211_wx_set_scan(priv
->ieee80211
,a
,wrqu
,b
);
589 static int r8192_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
590 union iwreq_data
*wrqu
, char *b
)
594 struct r8192_priv
*priv
= ieee80211_priv(dev
);
596 if(!priv
->up
) return -ENETDOWN
;
600 ret
= ieee80211_wx_get_scan(priv
->ieee80211
,a
,wrqu
,b
);
607 static int r8192_wx_set_essid(struct net_device
*dev
,
608 struct iw_request_info
*a
,
609 union iwreq_data
*wrqu
, char *b
)
611 struct r8192_priv
*priv
= ieee80211_priv(dev
);
615 ret
= ieee80211_wx_set_essid(priv
->ieee80211
,a
,wrqu
,b
);
625 static int r8192_wx_get_essid(struct net_device
*dev
,
626 struct iw_request_info
*a
,
627 union iwreq_data
*wrqu
, char *b
)
630 struct r8192_priv
*priv
= ieee80211_priv(dev
);
634 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
642 static int r8192_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
643 union iwreq_data
*wrqu
, char *b
)
646 struct r8192_priv
*priv
= ieee80211_priv(dev
);
650 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
656 static int r8192_wx_get_name(struct net_device
*dev
,
657 struct iw_request_info
*info
,
658 union iwreq_data
*wrqu
, char *extra
)
660 struct r8192_priv
*priv
= ieee80211_priv(dev
);
661 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
665 static int r8192_wx_set_frag(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
);
671 if (wrqu
->frag
.disabled
)
672 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
674 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
675 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
678 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
685 static int r8192_wx_get_frag(struct net_device
*dev
,
686 struct iw_request_info
*info
,
687 union iwreq_data
*wrqu
, char *extra
)
689 struct r8192_priv
*priv
= ieee80211_priv(dev
);
691 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
692 wrqu
->frag
.fixed
= 0; /* no auto select */
693 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
699 static int r8192_wx_set_wap(struct net_device
*dev
,
700 struct iw_request_info
*info
,
701 union iwreq_data
*awrq
,
706 struct r8192_priv
*priv
= ieee80211_priv(dev
);
707 // struct sockaddr *temp = (struct sockaddr *)awrq;
710 ret
= ieee80211_wx_set_wap(priv
->ieee80211
,info
,awrq
,extra
);
719 static int r8192_wx_get_wap(struct net_device
*dev
,
720 struct iw_request_info
*info
,
721 union iwreq_data
*wrqu
, char *extra
)
723 struct r8192_priv
*priv
= ieee80211_priv(dev
);
725 return ieee80211_wx_get_wap(priv
->ieee80211
,info
,wrqu
,extra
);
729 static int r8192_wx_get_enc(struct net_device
*dev
,
730 struct iw_request_info
*info
,
731 union iwreq_data
*wrqu
, char *key
)
733 struct r8192_priv
*priv
= ieee80211_priv(dev
);
735 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
738 static int r8192_wx_set_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
);
743 struct ieee80211_device
*ieee
= priv
->ieee80211
;
747 u32 hwkey
[4]={0,0,0,0};
750 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
751 u8 zero_addr
[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
752 {0x00,0x00,0x00,0x00,0x00,0x01},
753 {0x00,0x00,0x00,0x00,0x00,0x02},
754 {0x00,0x00,0x00,0x00,0x00,0x03} };
757 if(!priv
->up
) return -ENETDOWN
;
761 RT_TRACE(COMP_SEC
, "Setting SW wep key");
762 ret
= ieee80211_wx_set_encode(priv
->ieee80211
,info
,wrqu
,key
);
768 //sometimes, the length is zero while we do not type key value
769 if(wrqu
->encoding
.length
!=0){
771 for(i
=0 ; i
<4 ; i
++){
772 hwkey
[i
] |= key
[4*i
+0]&mask
;
773 if(i
==1&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
774 if(i
==3&&(4*i
+1)==wrqu
->encoding
.length
) mask
=0x00;
775 hwkey
[i
] |= (key
[4*i
+1]&mask
)<<8;
776 hwkey
[i
] |= (key
[4*i
+2]&mask
)<<16;
777 hwkey
[i
] |= (key
[4*i
+3]&mask
)<<24;
780 #define CONF_WEP40 0x4
781 #define CONF_WEP104 0x14
783 switch(wrqu
->encoding
.flags
& IW_ENCODE_INDEX
){
784 case 0: key_idx
= ieee
->tx_keyidx
; break;
785 case 1: key_idx
= 0; break;
786 case 2: key_idx
= 1; break;
787 case 3: key_idx
= 2; break;
788 case 4: key_idx
= 3; break;
792 if(wrqu
->encoding
.length
==0x5){
793 ieee
->pairwise_key_type
= KEY_TYPE_WEP40
;
794 EnableHWSecurityConfig8192(dev
);
799 KEY_TYPE_WEP40
, //KeyType
806 else if(wrqu
->encoding
.length
==0xd){
807 ieee
->pairwise_key_type
= KEY_TYPE_WEP104
;
808 EnableHWSecurityConfig8192(dev
);
813 KEY_TYPE_WEP104
, //KeyType
819 else printk("wrong type in WEP, not WEP40 and WEP104\n");
827 static int r8192_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
828 iwreq_data
*wrqu
, char *p
){
830 struct r8192_priv
*priv
= ieee80211_priv(dev
);
834 priv
->ieee80211
->active_scan
= mode
;
841 static int r8192_wx_set_retry(struct net_device
*dev
,
842 struct iw_request_info
*info
,
843 union iwreq_data
*wrqu
, char *extra
)
845 struct r8192_priv
*priv
= ieee80211_priv(dev
);
850 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
851 wrqu
->retry
.disabled
){
855 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)){
860 if(wrqu
->retry
.value
> R8180_MAX_RETRY
){
864 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
865 priv
->retry_rts
= wrqu
->retry
.value
;
866 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
869 priv
->retry_data
= wrqu
->retry
.value
;
870 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
874 * We might try to write directly the TX config register
875 * or to restart just the (R)TX process.
876 * I'm unsure if whole reset is really needed
882 rtl8180_rtx_disable(dev);
883 rtl8180_rx_enable(dev);
884 rtl8180_tx_enable(dev);
894 static int r8192_wx_get_retry(struct net_device
*dev
,
895 struct iw_request_info
*info
,
896 union iwreq_data
*wrqu
, char *extra
)
898 struct r8192_priv
*priv
= ieee80211_priv(dev
);
901 wrqu
->retry
.disabled
= 0; /* can't be disabled */
903 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
907 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
908 wrqu
->retry
.flags
= IW_RETRY_LIMIT
| IW_RETRY_MAX
;
909 wrqu
->retry
.value
= priv
->retry_rts
;
911 wrqu
->retry
.flags
= IW_RETRY_LIMIT
| IW_RETRY_MIN
;
912 wrqu
->retry
.value
= priv
->retry_data
;
914 //printk("returning %d",wrqu->retry.value);
920 static int r8192_wx_get_sens(struct net_device
*dev
,
921 struct iw_request_info
*info
,
922 union iwreq_data
*wrqu
, char *extra
)
924 struct r8192_priv
*priv
= ieee80211_priv(dev
);
925 if(priv
->rf_set_sens
== NULL
)
926 return -1; /* we have not this support for this radio */
927 wrqu
->sens
.value
= priv
->sens
;
932 static int r8192_wx_set_sens(struct net_device
*dev
,
933 struct iw_request_info
*info
,
934 union iwreq_data
*wrqu
, char *extra
)
937 struct r8192_priv
*priv
= ieee80211_priv(dev
);
941 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
942 if(priv
->rf_set_sens
== NULL
) {
943 err
= -1; /* we have not this support for this radio */
946 if(priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
947 priv
->sens
= wrqu
->sens
.value
;
958 static int r8192_wx_get_enc_ext(struct net_device
*dev
,
959 struct iw_request_info
*info
,
960 union iwreq_data
*wrqu
, char *extra
)
962 struct r8192_priv
*priv
= ieee80211_priv(dev
);
964 ret
= ieee80211_wx_get_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
968 //hw security need to reorganized.
969 static int r8192_wx_set_enc_ext(struct net_device
*dev
,
970 struct iw_request_info
*info
,
971 union iwreq_data
*wrqu
, char *extra
)
974 struct r8192_priv
*priv
= ieee80211_priv(dev
);
975 struct ieee80211_device
* ieee
= priv
->ieee80211
;
976 //printk("===>%s()\n", __FUNCTION__);
980 ret
= ieee80211_wx_set_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
983 u8 broadcast_addr
[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
986 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
987 struct iw_point
*encoding
= &wrqu
->encoding
;
989 static u8 CAM_CONST_ADDR
[4][6] = {
990 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
991 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
992 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
993 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
995 u8 idx
= 0, alg
= 0, group
= 0;
996 if ((encoding
->flags
& IW_ENCODE_DISABLED
) ||
997 ext
->alg
== IW_ENCODE_ALG_NONE
) //none is not allowed to use hwsec WB 2008.07.01
999 ieee
->pairwise_key_type
= ieee
->group_key_type
= KEY_TYPE_NA
;
1000 CamResetAllEntry(dev
);
1003 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;
1004 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1007 group
= ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
;
1009 if ((!group
) || (IW_MODE_ADHOC
== ieee
->iw_mode
) || (alg
== KEY_TYPE_WEP40
))
1011 if ((ext
->key_len
== 13) && (alg
== KEY_TYPE_WEP40
) )
1012 alg
= KEY_TYPE_WEP104
;
1013 ieee
->pairwise_key_type
= alg
;
1014 EnableHWSecurityConfig8192(dev
);
1016 memcpy((u8
*)key
, ext
->key
, 16); //we only get 16 bytes key.why? WB 2008.7.1
1018 if ((alg
& KEY_TYPE_WEP40
) && (ieee
->auth_mode
!=2) )
1031 ieee
->group_key_type
= alg
;
1036 broadcast_addr
, //MacAddr
1046 (u8
*)ieee
->ap_mac_addr
, //MacAddr
1059 static int r8192_wx_set_auth(struct net_device
*dev
,
1060 struct iw_request_info
*info
,
1061 union iwreq_data
*data
, char *extra
)
1065 //printk("====>%s()\n", __FUNCTION__);
1066 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1067 down(&priv
->wx_sem
);
1068 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &(data
->param
), extra
);
1073 static int r8192_wx_set_mlme(struct net_device
*dev
,
1074 struct iw_request_info
*info
,
1075 union iwreq_data
*wrqu
, char *extra
)
1077 //printk("====>%s()\n", __FUNCTION__);
1080 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1081 down(&priv
->wx_sem
);
1082 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1087 static int r8192_wx_set_gen_ie(struct net_device
*dev
,
1088 struct iw_request_info
*info
,
1089 union iwreq_data
*data
, char *extra
)
1091 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1093 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1094 down(&priv
->wx_sem
);
1096 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, data
->data
.length
);
1099 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1105 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
1106 union iwreq_data
*wrqu
,char *b
)
1112 static iw_handler r8192_wx_handlers
[] =
1114 NULL
, /* SIOCSIWCOMMIT */
1115 r8192_wx_get_name
, /* SIOCGIWNAME */
1116 dummy
, /* SIOCSIWNWID */
1117 dummy
, /* SIOCGIWNWID */
1118 r8192_wx_set_freq
, /* SIOCSIWFREQ */
1119 r8192_wx_get_freq
, /* SIOCGIWFREQ */
1120 r8192_wx_set_mode
, /* SIOCSIWMODE */
1121 r8192_wx_get_mode
, /* SIOCGIWMODE */
1122 r8192_wx_set_sens
, /* SIOCSIWSENS */
1123 r8192_wx_get_sens
, /* SIOCGIWSENS */
1124 NULL
, /* SIOCSIWRANGE */
1125 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1126 NULL
, /* SIOCSIWPRIV */
1127 NULL
, /* SIOCGIWPRIV */
1128 NULL
, /* SIOCSIWSTATS */
1129 NULL
, /* SIOCGIWSTATS */
1130 dummy
, /* SIOCSIWSPY */
1131 dummy
, /* SIOCGIWSPY */
1132 NULL
, /* SIOCGIWTHRSPY */
1133 NULL
, /* SIOCWIWTHRSPY */
1134 r8192_wx_set_wap
, /* SIOCSIWAP */
1135 r8192_wx_get_wap
, /* SIOCGIWAP */
1136 r8192_wx_set_mlme
, /* MLME-- */
1137 dummy
, /* SIOCGIWAPLIST -- depricated */
1138 r8192_wx_set_scan
, /* SIOCSIWSCAN */
1139 r8192_wx_get_scan
, /* SIOCGIWSCAN */
1140 r8192_wx_set_essid
, /* SIOCSIWESSID */
1141 r8192_wx_get_essid
, /* SIOCGIWESSID */
1142 dummy
, /* SIOCSIWNICKN */
1143 dummy
, /* SIOCGIWNICKN */
1144 NULL
, /* -- hole -- */
1145 NULL
, /* -- hole -- */
1146 r8192_wx_set_rate
, /* SIOCSIWRATE */
1147 r8192_wx_get_rate
, /* SIOCGIWRATE */
1148 r8192_wx_set_rts
, /* SIOCSIWRTS */
1149 r8192_wx_get_rts
, /* SIOCGIWRTS */
1150 r8192_wx_set_frag
, /* SIOCSIWFRAG */
1151 r8192_wx_get_frag
, /* SIOCGIWFRAG */
1152 dummy
, /* SIOCSIWTXPOW */
1153 dummy
, /* SIOCGIWTXPOW */
1154 r8192_wx_set_retry
, /* SIOCSIWRETRY */
1155 r8192_wx_get_retry
, /* SIOCGIWRETRY */
1156 r8192_wx_set_enc
, /* SIOCSIWENCODE */
1157 r8192_wx_get_enc
, /* SIOCGIWENCODE */
1158 r8192_wx_set_power
, /* SIOCSIWPOWER */
1159 r8192_wx_get_power
, /* SIOCGIWPOWER */
1160 NULL
, /*---hole---*/
1161 NULL
, /*---hole---*/
1162 r8192_wx_set_gen_ie
,//NULL, /* SIOCSIWGENIE */
1163 NULL
, /* SIOCSIWGENIE */
1165 r8192_wx_set_auth
,//NULL, /* SIOCSIWAUTH */
1166 NULL
,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1167 r8192_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1168 NULL
,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1169 NULL
, /* SIOCSIWPMKSA */
1170 NULL
, /*---hole---*/
1175 static const struct iw_priv_args r8192_private_args
[] = {
1178 SIOCIWFIRSTPRIV
+ 0x0,
1179 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1183 SIOCIWFIRSTPRIV
+ 0x1,
1184 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1188 SIOCIWFIRSTPRIV
+ 0x2,
1189 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1194 SIOCIWFIRSTPRIV
+ 0x3,
1195 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readRF"
1199 SIOCIWFIRSTPRIV
+ 0x4,
1200 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeRF"
1204 SIOCIWFIRSTPRIV
+ 0x5,
1205 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readBB"
1209 SIOCIWFIRSTPRIV
+ 0x6,
1210 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writeBB"
1214 SIOCIWFIRSTPRIV
+ 0x7,
1215 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "readnicb"
1219 SIOCIWFIRSTPRIV
+ 0x8,
1220 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "writenicb"
1224 SIOCIWFIRSTPRIV
+ 0x9,
1225 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "apinfo"
1231 SIOCIWFIRSTPRIV
+ 0x3,
1232 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "forcereset"
1238 SIOCIWFIRSTPRIV
+ 0x5,
1239 IW_PRIV_TYPE_NONE
, IW_PRIV_TYPE_INT
|IW_PRIV_SIZE_FIXED
|1,
1246 static iw_handler r8192_private_handler
[] = {
1247 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1248 r8192_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1249 // r8192_wx_set_forceassociate,
1250 // r8192_wx_set_beaconinterval,
1251 // r8192_wx_set_monitor_type,
1252 r8192_wx_set_scan_type
,
1256 r8192_wx_write_regs
,
1260 r8192_wx_write_nicb
,
1261 r8192_wx_get_ap_status
,
1263 r8192_wx_force_reset
,
1266 (iw_handler
)r8191su_wx_get_firm_version
,
1270 struct iw_statistics
*r8192_get_wireless_stats(struct net_device
*dev
)
1272 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1273 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1274 struct iw_statistics
* wstats
= &priv
->wstats
;
1278 if(ieee
->state
< IEEE80211_LINKED
)
1280 wstats
->qual
.qual
= 0;
1281 wstats
->qual
.level
= 0;
1282 wstats
->qual
.noise
= 0;
1283 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1287 tmp_level
= (&ieee
->current_network
)->stats
.rssi
;
1288 tmp_qual
= (&ieee
->current_network
)->stats
.signal
;
1289 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1290 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1292 wstats
->qual
.level
= tmp_level
;
1293 wstats
->qual
.qual
= tmp_qual
;
1294 wstats
->qual
.noise
= tmp_noise
;
1295 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1299 struct iw_handler_def r8192_wx_handlers_def
={
1300 .standard
= r8192_wx_handlers
,
1301 .num_standard
= sizeof(r8192_wx_handlers
) / sizeof(iw_handler
),
1302 .private = r8192_private_handler
,
1303 .num_private
= sizeof(r8192_private_handler
) / sizeof(iw_handler
),
1304 .num_private_args
= sizeof(r8192_private_args
) / sizeof(struct iw_priv_args
),
1305 .get_wireless_stats
= r8192_get_wireless_stats
,
1306 .private_args
= (struct iw_priv_args
*)r8192_private_args
,