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"
25 #include "ieee80211/dot11d.h"
29 static const 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);
73 if(priv->bHwRadioOff == true)
78 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
86 static int r8192_wx_set_rts(struct net_device *dev,
87 struct iw_request_info *info,
88 union iwreq_data *wrqu, char *extra)
91 struct r8192_priv *priv = ieee80211_priv(dev);
93 if(priv->bHwRadioOff == true)
98 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
105 static int r8192_wx_get_rts(struct net_device *dev,
106 struct iw_request_info *info,
107 union iwreq_data *wrqu, char *extra)
109 struct r8192_priv *priv = ieee80211_priv(dev);
110 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
113 static int r8192_wx_set_power(struct net_device *dev,
114 struct iw_request_info *info,
115 union iwreq_data *wrqu, char *extra)
118 struct r8192_priv *priv = ieee80211_priv(dev);
120 if(priv->bHwRadioOff == true)
125 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
132 static int r8192_wx_get_power(struct net_device *dev,
133 struct iw_request_info *info,
134 union iwreq_data *wrqu, char *extra)
136 struct r8192_priv *priv = ieee80211_priv(dev);
137 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
140 static int r8192_wx_set_rawtx(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);
147 if(priv->bHwRadioOff == true)
152 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
160 static int r8192_wx_force_reset(struct net_device *dev,
161 struct iw_request_info *info,
162 union iwreq_data *wrqu, char *extra)
164 struct r8192_priv *priv = ieee80211_priv(dev);
168 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
169 priv->force_reset = *extra;
176 static int r8192_wx_set_crcmon(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);
181 int *parms = (int *)extra;
182 int enable = (parms[0] > 0);
183 short prev = priv->crcmon;
185 if(priv->bHwRadioOff == true)
195 DMESG("bad CRC in monitor mode are %s",
196 priv->crcmon ? "accepted" : "rejected");
198 if(prev != priv->crcmon && priv->up){
208 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
209 union iwreq_data *wrqu, char *b)
211 struct r8192_priv *priv = ieee80211_priv(dev);
212 RT_RF_POWER_STATE rtState;
215 if(priv->bHwRadioOff == true)
218 rtState = priv->ieee80211->eRFPowerState;
221 if(wrqu->mode == IW_MODE_ADHOC){
223 if(priv->ieee80211->PowerSaveControl.bInactivePs){
224 if(rtState == eRfOff){
225 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
227 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
232 RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
233 down(&priv->ieee80211->ips_sem);
235 up(&priv->ieee80211->ips_sem);
241 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
243 //rtl8187_set_rxconf(dev);
249 struct iw_range_with_scan_capa
251 /* Informative stuff (to choose between different interface) */
252 __u32 throughput; /* To give an idea... */
253 /* In theory this value should be the maximum benchmarked
254 * TCP/IP throughput, because with most of these devices the
255 * bit rate is meaningless (overhead an co) to estimate how
256 * fast the connection will go and pick the fastest one.
257 * I suggest people to play with Netperf or any benchmark...
260 /* NWID (or domain id) */
261 __u32 min_nwid; /* Minimal NWID we are able to set */
262 __u32 max_nwid; /* Maximal NWID we are able to set */
264 /* Old Frequency (backward compat - moved lower ) */
265 __u16 old_num_channels;
266 __u8 old_num_frequency;
268 /* Scan capabilities */
271 static int rtl8180_wx_get_range(struct net_device *dev,
272 struct iw_request_info *info,
273 union iwreq_data *wrqu, char *extra)
275 struct iw_range *range = (struct iw_range *)extra;
276 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
277 struct r8192_priv *priv = ieee80211_priv(dev);
281 wrqu->data.length = sizeof(*range);
282 memset(range, 0, sizeof(*range));
284 /* Let's try to keep this struct in the same order as in
285 * linux/include/wireless.h
288 /* TODO: See what values we can set, and remove the ones we can't
289 * set, or fill them with some default data.
292 /* ~5 Mb/s real (802.11b) */
293 range->throughput = 130 * 1000 * 1000;
295 // TODO: Not used in 802.11b?
296 // range->min_nwid; /* Minimal NWID we are able to set */
297 // TODO: Not used in 802.11b?
298 // range->max_nwid; /* Maximal NWID we are able to set */
300 /* Old Frequency (backward compat - moved lower ) */
301 // range->old_num_channels;
302 // range->old_num_frequency;
303 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
304 if(priv->rf_set_sens != NULL)
305 range->sensitivity = priv->max_sens; /* signal level threshold range */
307 range->max_qual.qual = 100;
308 /* TODO: Find real max RSSI and stick here */
309 range->max_qual.level = 0;
310 range->max_qual.noise = -98;
311 range->max_qual.updated = 7; /* Updated all three */
313 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
314 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
315 range->avg_qual.level = 20 + -98;
316 range->avg_qual.noise = 0;
317 range->avg_qual.updated = 7; /* Updated all three */
319 range->num_bitrates = RATE_COUNT;
321 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
322 range->bitrate[i] = rtl8180_rates[i];
325 range->min_frag = MIN_FRAG_THRESHOLD;
326 range->max_frag = MAX_FRAG_THRESHOLD;
329 range->max_pmp = 5000000;
331 range->max_pmt = 65535*1000;
332 range->pmp_flags = IW_POWER_PERIOD;
333 range->pmt_flags = IW_POWER_TIMEOUT;
334 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
335 range->we_version_compiled = WIRELESS_EXT;
336 range->we_version_source = 18;
338 // range->retry_capa; /* What retry options are supported */
339 // range->retry_flags; /* How to decode max/min retry limit */
340 // range->r_time_flags; /* How to decode max/min retry life */
341 // range->min_retry; /* Minimal number of retries */
342 // range->max_retry; /* Maximal number of retries */
343 // range->min_r_time; /* Minimal retry lifetime */
344 // range->max_r_time; /* Maximal retry lifetime */
347 for (i = 0, val = 0; i < 14; i++) {
349 // Include only legal frequencies for some countries
351 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
353 if ((priv->ieee80211->channel_map)[i+1]) {
355 range->freq[val].i = i + 1;
356 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
357 range->freq[val].e = 1;
360 // FIXME: do we need to set anything for channels
364 if (val == IW_MAX_FREQUENCIES)
367 range->num_frequency = val;
368 range->num_channels = val;
369 #if WIRELESS_EXT > 17
370 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
371 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
373 tmp->scan_capa = 0x01;
378 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
379 union iwreq_data *wrqu, char *b)
381 struct r8192_priv *priv = ieee80211_priv(dev);
382 struct ieee80211_device* ieee = priv->ieee80211;
383 RT_RF_POWER_STATE rtState;
386 if(priv->bHwRadioOff == true)
389 rtState = priv->ieee80211->eRFPowerState;
391 if(!priv->up) return -ENETDOWN;
392 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
395 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
397 struct iw_scan_req* req = (struct iw_scan_req*)b;
400 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
401 ieee->current_network.ssid_len = req->essid_len;
402 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
403 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
409 priv->ieee80211->actscanning = true;
410 if(priv->ieee80211->state != IEEE80211_LINKED){
411 if(priv->ieee80211->PowerSaveControl.bInactivePs){
412 if(rtState == eRfOff){
413 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
415 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
420 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
421 down(&priv->ieee80211->ips_sem);
423 up(&priv->ieee80211->ips_sem);
427 priv->ieee80211->scanning = 0;
428 ieee80211_softmac_scan_syncro(priv->ieee80211);
434 if(priv->ieee80211->state != IEEE80211_LINKED){
435 priv->ieee80211->scanning = 0;
436 ieee80211_softmac_scan_syncro(priv->ieee80211);
441 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
448 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
449 union iwreq_data *wrqu, char *b)
453 struct r8192_priv *priv = ieee80211_priv(dev);
455 if(priv->bHwRadioOff == true)
458 if(!priv->up) return -ENETDOWN;
462 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
469 static int r8192_wx_set_essid(struct net_device *dev,
470 struct iw_request_info *a,
471 union iwreq_data *wrqu, char *b)
473 struct r8192_priv *priv = ieee80211_priv(dev);
474 RT_RF_POWER_STATE rtState;
477 if(priv->bHwRadioOff == true)
480 rtState = priv->ieee80211->eRFPowerState;
484 down(&priv->ieee80211->ips_sem);
486 up(&priv->ieee80211->ips_sem);
488 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
498 static int r8192_wx_get_essid(struct net_device *dev,
499 struct iw_request_info *a,
500 union iwreq_data *wrqu, char *b)
503 struct r8192_priv *priv = ieee80211_priv(dev);
507 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
515 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
516 union iwreq_data *wrqu, char *b)
519 struct r8192_priv *priv = ieee80211_priv(dev);
521 if(priv->bHwRadioOff == true)
526 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
532 static int r8192_wx_get_name(struct net_device *dev,
533 struct iw_request_info *info,
534 union iwreq_data *wrqu, char *extra)
536 struct r8192_priv *priv = ieee80211_priv(dev);
537 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
541 static int r8192_wx_set_frag(struct net_device *dev,
542 struct iw_request_info *info,
543 union iwreq_data *wrqu, char *extra)
545 struct r8192_priv *priv = ieee80211_priv(dev);
547 if(priv->bHwRadioOff == true)
550 if (wrqu->frag.disabled)
551 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
553 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
554 wrqu->frag.value > MAX_FRAG_THRESHOLD)
557 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
564 static int r8192_wx_get_frag(struct net_device *dev,
565 struct iw_request_info *info,
566 union iwreq_data *wrqu, char *extra)
568 struct r8192_priv *priv = ieee80211_priv(dev);
570 wrqu->frag.value = priv->ieee80211->fts;
571 wrqu->frag.fixed = 0; /* no auto select */
572 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
578 static int r8192_wx_set_wap(struct net_device *dev,
579 struct iw_request_info *info,
580 union iwreq_data *awrq,
585 struct r8192_priv *priv = ieee80211_priv(dev);
586 // struct sockaddr *temp = (struct sockaddr *)awrq;
588 if(priv->bHwRadioOff == true)
594 down(&priv->ieee80211->ips_sem);
596 up(&priv->ieee80211->ips_sem);
598 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
607 static int r8192_wx_get_wap(struct net_device *dev,
608 struct iw_request_info *info,
609 union iwreq_data *wrqu, char *extra)
611 struct r8192_priv *priv = ieee80211_priv(dev);
613 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
617 static int r8192_wx_get_enc(struct net_device *dev,
618 struct iw_request_info *info,
619 union iwreq_data *wrqu, char *key)
621 struct r8192_priv *priv = ieee80211_priv(dev);
623 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
626 static int r8192_wx_set_enc(struct net_device *dev,
627 struct iw_request_info *info,
628 union iwreq_data *wrqu, char *key)
630 struct r8192_priv *priv = ieee80211_priv(dev);
633 struct ieee80211_device *ieee = priv->ieee80211;
635 u32 hwkey[4]={0,0,0,0};
638 u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
639 {0x00,0x00,0x00,0x00,0x00,0x01},
640 {0x00,0x00,0x00,0x00,0x00,0x02},
641 {0x00,0x00,0x00,0x00,0x00,0x03} };
644 if(priv->bHwRadioOff == true)
647 if(!priv->up) return -ENETDOWN;
649 priv->ieee80211->wx_set_enc = 1;
651 down(&priv->ieee80211->ips_sem);
653 up(&priv->ieee80211->ips_sem);
658 RT_TRACE(COMP_SEC, "Setting SW wep key");
659 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
663 //sometimes, the length is zero while we do not type key value
664 if(wrqu->encoding.length!=0){
666 for(i=0 ; i<4 ; i++){
667 hwkey[i] |= key[4*i+0]&mask;
668 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
669 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
670 hwkey[i] |= (key[4*i+1]&mask)<<8;
671 hwkey[i] |= (key[4*i+2]&mask)<<16;
672 hwkey[i] |= (key[4*i+3]&mask)<<24;
675 #define CONF_WEP40 0x4
676 #define CONF_WEP104 0x14
678 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
679 case 0: key_idx = ieee->tx_keyidx; break;
680 case 1: key_idx = 0; break;
681 case 2: key_idx = 1; break;
682 case 3: key_idx = 2; break;
683 case 4: key_idx = 3; break;
687 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
688 if(wrqu->encoding.length==0x5){
689 ieee->pairwise_key_type = KEY_TYPE_WEP40;
690 EnableHWSecurityConfig8192(dev);
694 KEY_TYPE_WEP40, //KeyType
702 //write_nic_byte(dev, SECR, 7);
706 KEY_TYPE_WEP40, //KeyType
707 broadcast_addr, //addr
714 else if(wrqu->encoding.length==0xd){
715 ieee->pairwise_key_type = KEY_TYPE_WEP104;
716 EnableHWSecurityConfig8192(dev);
720 KEY_TYPE_WEP104, //KeyType
727 //write_nic_byte(dev, SECR, 7);
731 KEY_TYPE_WEP104, //KeyType
732 broadcast_addr, //addr
738 else printk("wrong type in WEP, not WEP40 and WEP104\n");
744 //consider the setting different key index situation
745 //wrqu->encoding.flags = 801 means that we set key with index "1"
746 if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
748 //write_nic_byte(dev, SECR, 7);
749 EnableHWSecurityConfig8192(dev);
750 //copy wpa config from default key(key0~key3) to broadcast key(key5)
752 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
753 write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
754 write_cam(dev, (4*6)+1, 0xffffffff);
755 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
756 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
757 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
758 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
762 priv->ieee80211->wx_set_enc = 0;
768 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
769 iwreq_data *wrqu, char *p){
771 struct r8192_priv *priv = ieee80211_priv(dev);
775 priv->ieee80211->active_scan = mode;
782 static int r8192_wx_set_retry(struct net_device *dev,
783 struct iw_request_info *info,
784 union iwreq_data *wrqu, char *extra)
786 struct r8192_priv *priv = ieee80211_priv(dev);
789 if(priv->bHwRadioOff == true)
794 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
795 wrqu->retry.disabled){
799 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
804 if(wrqu->retry.value > R8180_MAX_RETRY){
808 if (wrqu->retry.flags & IW_RETRY_MAX) {
809 priv->retry_rts = wrqu->retry.value;
810 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
813 priv->retry_data = wrqu->retry.value;
814 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
818 * We might try to write directly the TX config register
819 * or to restart just the (R)TX process.
820 * I'm unsure if whole reset is really needed
826 rtl8180_rtx_disable(dev);
827 rtl8180_rx_enable(dev);
828 rtl8180_tx_enable(dev);
838 static int r8192_wx_get_retry(struct net_device *dev,
839 struct iw_request_info *info,
840 union iwreq_data *wrqu, char *extra)
842 struct r8192_priv *priv = ieee80211_priv(dev);
845 wrqu->retry.disabled = 0; /* can't be disabled */
847 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
851 if (wrqu->retry.flags & IW_RETRY_MAX) {
852 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
853 wrqu->retry.value = priv->retry_rts;
855 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
856 wrqu->retry.value = priv->retry_data;
858 //DMESG("returning %d",wrqu->retry.value);
864 static int r8192_wx_get_sens(struct net_device *dev,
865 struct iw_request_info *info,
866 union iwreq_data *wrqu, char *extra)
868 struct r8192_priv *priv = ieee80211_priv(dev);
869 if(priv->rf_set_sens == NULL)
870 return -1; /* we have not this support for this radio */
871 wrqu->sens.value = priv->sens;
876 static int r8192_wx_set_sens(struct net_device *dev,
877 struct iw_request_info *info,
878 union iwreq_data *wrqu, char *extra)
881 struct r8192_priv *priv = ieee80211_priv(dev);
885 if(priv->bHwRadioOff == true)
889 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
890 if(priv->rf_set_sens == NULL) {
891 err= -1; /* we have not this support for this radio */
894 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
895 priv->sens = wrqu->sens.value;
905 #if (WIRELESS_EXT >= 18)
906 static int r8192_wx_set_enc_ext(struct net_device *dev,
907 struct iw_request_info *info,
908 union iwreq_data *wrqu, char *extra)
911 struct r8192_priv *priv = ieee80211_priv(dev);
912 struct ieee80211_device* ieee = priv->ieee80211;
914 if(priv->bHwRadioOff == true)
919 priv->ieee80211->wx_set_enc = 1;
922 down(&priv->ieee80211->ips_sem);
924 up(&priv->ieee80211->ips_sem);
927 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
930 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
933 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
934 struct iw_point *encoding = &wrqu->encoding;
936 static u8 CAM_CONST_ADDR[4][6] = {
937 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
938 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
939 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
940 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
942 u8 idx = 0, alg = 0, group = 0;
943 if ((encoding->flags & IW_ENCODE_DISABLED) ||
944 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
946 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
947 CamResetAllEntry(dev);
950 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;
951 idx = encoding->flags & IW_ENCODE_INDEX;
954 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
956 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
958 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
959 alg = KEY_TYPE_WEP104;
960 ieee->pairwise_key_type = alg;
961 EnableHWSecurityConfig8192(dev);
963 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
965 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
967 if (ext->key_len == 13)
968 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
979 ieee->group_key_type = alg;
984 broadcast_addr, //MacAddr
990 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
991 write_nic_byte(dev, 0x173, 1); //fix aes bug
997 (u8*)ieee->ap_mac_addr, //MacAddr
1006 priv->ieee80211->wx_set_enc = 0;
1011 static int r8192_wx_set_auth(struct net_device *dev,
1012 struct iw_request_info *info,
1013 union iwreq_data *data, char *extra)
1016 //printk("====>%s()\n", __FUNCTION__);
1017 struct r8192_priv *priv = ieee80211_priv(dev);
1019 if(priv->bHwRadioOff == true)
1022 down(&priv->wx_sem);
1023 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1028 static int r8192_wx_set_mlme(struct net_device *dev,
1029 struct iw_request_info *info,
1030 union iwreq_data *wrqu, char *extra)
1032 //printk("====>%s()\n", __FUNCTION__);
1035 struct r8192_priv *priv = ieee80211_priv(dev);
1037 if(priv->bHwRadioOff == true)
1040 down(&priv->wx_sem);
1041 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1046 static int r8192_wx_set_gen_ie(struct net_device *dev,
1047 struct iw_request_info *info,
1048 union iwreq_data *data, char *extra)
1050 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1052 struct r8192_priv *priv = ieee80211_priv(dev);
1054 if(priv->bHwRadioOff == true)
1057 down(&priv->wx_sem);
1058 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1060 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1064 static int dummy(struct net_device *dev, struct iw_request_info *a,
1065 union iwreq_data *wrqu,char *b)
1070 // check ac/dc status with the help of user space application */
1071 static int r8192_wx_adapter_power_status(struct net_device *dev,
1072 struct iw_request_info *info,
1073 union iwreq_data *wrqu, char *extra)
1075 struct r8192_priv *priv = ieee80211_priv(dev);
1077 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
1078 struct ieee80211_device* ieee = priv->ieee80211;
1080 down(&priv->wx_sem);
1083 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1084 // ieee->ps shall not be set under DC mode, otherwise it conflict
1085 // with Leisure power save mode setting.
1087 if(*extra || priv->force_lps) {
1088 priv->ps_force = false;
1089 pPSC->bLeisurePs = true;
1091 //LZM for PS-Poll AID issue. 090429
1092 if(priv->ieee80211->state == IEEE80211_LINKED)
1093 LeisurePSLeave(dev);
1095 priv->ps_force = true;
1096 pPSC->bLeisurePs = false;
1107 static iw_handler r8192_wx_handlers[] =
1109 NULL, /* SIOCSIWCOMMIT */
1110 r8192_wx_get_name, /* SIOCGIWNAME */
1111 dummy, /* SIOCSIWNWID */
1112 dummy, /* SIOCGIWNWID */
1113 r8192_wx_set_freq, /* SIOCSIWFREQ */
1114 r8192_wx_get_freq, /* SIOCGIWFREQ */
1115 r8192_wx_set_mode, /* SIOCSIWMODE */
1116 r8192_wx_get_mode, /* SIOCGIWMODE */
1117 r8192_wx_set_sens, /* SIOCSIWSENS */
1118 r8192_wx_get_sens, /* SIOCGIWSENS */
1119 NULL, /* SIOCSIWRANGE */
1120 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1121 NULL, /* SIOCSIWPRIV */
1122 NULL, /* SIOCGIWPRIV */
1123 NULL, /* SIOCSIWSTATS */
1124 NULL, /* SIOCGIWSTATS */
1125 dummy, /* SIOCSIWSPY */
1126 dummy, /* SIOCGIWSPY */
1127 NULL, /* SIOCGIWTHRSPY */
1128 NULL, /* SIOCWIWTHRSPY */
1129 r8192_wx_set_wap, /* SIOCSIWAP */
1130 r8192_wx_get_wap, /* SIOCGIWAP */
1131 #if (WIRELESS_EXT >= 18)
1132 r8192_wx_set_mlme, /* MLME-- */
1136 dummy, /* SIOCGIWAPLIST -- depricated */
1137 r8192_wx_set_scan, /* SIOCSIWSCAN */
1138 r8192_wx_get_scan, /* SIOCGIWSCAN */
1139 r8192_wx_set_essid, /* SIOCSIWESSID */
1140 r8192_wx_get_essid, /* SIOCGIWESSID */
1141 dummy, /* SIOCSIWNICKN */
1142 dummy, /* SIOCGIWNICKN */
1143 NULL, /* -- hole -- */
1144 NULL, /* -- hole -- */
1145 r8192_wx_set_rate, /* SIOCSIWRATE */
1146 r8192_wx_get_rate, /* SIOCGIWRATE */
1147 r8192_wx_set_rts, /* SIOCSIWRTS */
1148 r8192_wx_get_rts, /* SIOCGIWRTS */
1149 r8192_wx_set_frag, /* SIOCSIWFRAG */
1150 r8192_wx_get_frag, /* SIOCGIWFRAG */
1151 dummy, /* SIOCSIWTXPOW */
1152 dummy, /* SIOCGIWTXPOW */
1153 r8192_wx_set_retry, /* SIOCSIWRETRY */
1154 r8192_wx_get_retry, /* SIOCGIWRETRY */
1155 r8192_wx_set_enc, /* SIOCSIWENCODE */
1156 r8192_wx_get_enc, /* SIOCGIWENCODE */
1157 r8192_wx_set_power, /* SIOCSIWPOWER */
1158 r8192_wx_get_power, /* SIOCGIWPOWER */
1159 NULL, /*---hole---*/
1160 NULL, /*---hole---*/
1161 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1162 NULL, /* SIOCSIWGENIE */
1163 #if (WIRELESS_EXT >= 18)
1164 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1165 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1166 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1172 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1173 NULL, /* SIOCSIWPMKSA */
1174 NULL, /*---hole---*/
1179 static const struct iw_priv_args r8192_private_args[] = {
1182 SIOCIWFIRSTPRIV + 0x0,
1183 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1187 SIOCIWFIRSTPRIV + 0x1,
1188 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1192 SIOCIWFIRSTPRIV + 0x2,
1193 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1197 SIOCIWFIRSTPRIV + 0x3,
1198 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1203 SIOCIWFIRSTPRIV + 0x4,
1204 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1211 static iw_handler r8192_private_handler[] = {
1212 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1213 r8192_wx_set_scan_type,
1215 r8192_wx_force_reset,
1216 r8192_wx_adapter_power_status,
1219 //#if WIRELESS_EXT >= 17
1220 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1222 struct r8192_priv *priv = ieee80211_priv(dev);
1223 struct ieee80211_device* ieee = priv->ieee80211;
1224 struct iw_statistics* wstats = &priv->wstats;
1228 if(ieee->state < IEEE80211_LINKED)
1230 wstats->qual.qual = 0;
1231 wstats->qual.level = 0;
1232 wstats->qual.noise = 0;
1233 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1237 tmp_level = (&ieee->current_network)->stats.rssi;
1238 tmp_qual = (&ieee->current_network)->stats.signal;
1239 tmp_noise = (&ieee->current_network)->stats.noise;
1240 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1242 wstats->qual.level = tmp_level;
1243 wstats->qual.qual = tmp_qual;
1244 wstats->qual.noise = tmp_noise;
1245 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1251 struct iw_handler_def r8192_wx_handlers_def={
1252 .standard = r8192_wx_handlers,
1253 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1254 .private = r8192_private_handler,
1255 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1256 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1257 #if WIRELESS_EXT >= 17
1258 .get_wireless_stats = r8192_get_wireless_stats,
1260 .private_args = (struct iw_priv_args *)r8192_private_args,