staging: rtl8192e: Remove unused members from r8192_priv
[wandboard.git] / drivers / staging / rtl8192e / r8192E_wx.c
blob15b08013aae0ad46478e54f4a91a139ac4cb0d23
1 /*
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
17 project Authors.
20 #include <linux/string.h>
21 #include "r8192E.h"
22 #include "r8192E_hw.h"
23 #include "r8192E_wx.h"
24 #ifdef ENABLE_DOT11D
25 #include "ieee80211/dot11d.h"
26 #endif
28 #define RATE_COUNT 12
29 static const u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
30 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
33 #ifndef ENETDOWN
34 #define ENETDOWN 1
35 #endif
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)
70 int ret;
71 struct r8192_priv *priv = ieee80211_priv(dev);
73 if (priv->bHwRadioOff)
74 return 0;
76 down(&priv->wx_sem);
78 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
80 up(&priv->wx_sem);
82 return ret;
86 static int r8192_wx_set_rts(struct net_device *dev,
87 struct iw_request_info *info,
88 union iwreq_data *wrqu, char *extra)
90 int ret;
91 struct r8192_priv *priv = ieee80211_priv(dev);
93 if (priv->bHwRadioOff)
94 return 0;
96 down(&priv->wx_sem);
98 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
100 up(&priv->wx_sem);
102 return ret;
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)
117 int ret;
118 struct r8192_priv *priv = ieee80211_priv(dev);
120 if (priv->bHwRadioOff)
121 return 0;
123 down(&priv->wx_sem);
125 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
127 up(&priv->wx_sem);
129 return ret;
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);
145 int ret;
147 if (priv->bHwRadioOff)
148 return 0;
150 down(&priv->wx_sem);
152 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
154 up(&priv->wx_sem);
156 return ret;
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);
166 down(&priv->wx_sem);
168 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
169 priv->force_reset = *extra;
170 up(&priv->wx_sem);
171 return 0;
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)
186 return 0;
188 down(&priv->wx_sem);
190 if(enable)
191 priv->crcmon=1;
192 else
193 priv->crcmon=0;
195 DMESG("bad CRC in monitor mode are %s",
196 priv->crcmon ? "accepted" : "rejected");
198 if(prev != priv->crcmon && priv->up){
199 //rtl8180_down(dev);
200 //rtl8180_up(dev);
203 up(&priv->wx_sem);
205 return 0;
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;
213 int ret;
215 if (priv->bHwRadioOff)
216 return 0;
218 rtState = priv->ieee80211->eRFPowerState;
219 down(&priv->wx_sem);
220 #ifdef ENABLE_IPS
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__);
228 up(&priv->wx_sem);
229 return -1;
231 else{
232 RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
233 down(&priv->ieee80211->ips_sem);
234 IPSLeave(dev);
235 up(&priv->ieee80211->ips_sem);
240 #endif
241 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
243 //rtl8187_set_rxconf(dev);
245 up(&priv->wx_sem);
246 return ret;
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 */
269 __u8 scan_capa;
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);
278 u16 val;
279 int i;
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 */
305 range->max_qual.qual = 100;
306 /* TODO: Find real max RSSI and stick here */
307 range->max_qual.level = 0;
308 range->max_qual.noise = -98;
309 range->max_qual.updated = 7; /* Updated all three */
311 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
312 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
313 range->avg_qual.level = 20 + -98;
314 range->avg_qual.noise = 0;
315 range->avg_qual.updated = 7; /* Updated all three */
317 range->num_bitrates = RATE_COUNT;
319 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
320 range->bitrate[i] = rtl8180_rates[i];
323 range->min_frag = MIN_FRAG_THRESHOLD;
324 range->max_frag = MAX_FRAG_THRESHOLD;
326 range->min_pmp=0;
327 range->max_pmp = 5000000;
328 range->min_pmt = 0;
329 range->max_pmt = 65535*1000;
330 range->pmp_flags = IW_POWER_PERIOD;
331 range->pmt_flags = IW_POWER_TIMEOUT;
332 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
333 range->we_version_compiled = WIRELESS_EXT;
334 range->we_version_source = 18;
336 // range->retry_capa; /* What retry options are supported */
337 // range->retry_flags; /* How to decode max/min retry limit */
338 // range->r_time_flags; /* How to decode max/min retry life */
339 // range->min_retry; /* Minimal number of retries */
340 // range->max_retry; /* Maximal number of retries */
341 // range->min_r_time; /* Minimal retry lifetime */
342 // range->max_r_time; /* Maximal retry lifetime */
345 for (i = 0, val = 0; i < 14; i++) {
347 // Include only legal frequencies for some countries
348 #ifdef ENABLE_DOT11D
349 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
350 #else
351 if ((priv->ieee80211->channel_map)[i+1]) {
352 #endif
353 range->freq[val].i = i + 1;
354 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
355 range->freq[val].e = 1;
356 val++;
357 } else {
358 // FIXME: do we need to set anything for channels
359 // we don't use ?
362 if (val == IW_MAX_FREQUENCIES)
363 break;
365 range->num_frequency = val;
366 range->num_channels = val;
367 #if WIRELESS_EXT > 17
368 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
369 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
370 #endif
371 tmp->scan_capa = 0x01;
372 return 0;
376 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
377 union iwreq_data *wrqu, char *b)
379 struct r8192_priv *priv = ieee80211_priv(dev);
380 struct ieee80211_device* ieee = priv->ieee80211;
381 RT_RF_POWER_STATE rtState;
382 int ret;
384 if (priv->bHwRadioOff)
385 return 0;
387 rtState = priv->ieee80211->eRFPowerState;
389 if(!priv->up) return -ENETDOWN;
390 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
391 return -EAGAIN;
393 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
395 struct iw_scan_req* req = (struct iw_scan_req*)b;
396 if (req->essid_len)
398 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
399 ieee->current_network.ssid_len = req->essid_len;
400 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
401 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
405 down(&priv->wx_sem);
406 #ifdef ENABLE_IPS
407 priv->ieee80211->actscanning = true;
408 if(priv->ieee80211->state != IEEE80211_LINKED){
409 if(priv->ieee80211->PowerSaveControl.bInactivePs){
410 if(rtState == eRfOff){
411 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
413 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
414 up(&priv->wx_sem);
415 return -1;
417 else{
418 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
419 down(&priv->ieee80211->ips_sem);
420 IPSLeave(dev);
421 up(&priv->ieee80211->ips_sem);
425 priv->ieee80211->scanning = 0;
426 ieee80211_softmac_scan_syncro(priv->ieee80211);
427 ret = 0;
429 else
430 #else
432 if(priv->ieee80211->state != IEEE80211_LINKED){
433 priv->ieee80211->scanning = 0;
434 ieee80211_softmac_scan_syncro(priv->ieee80211);
435 ret = 0;
437 else
438 #endif
439 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
441 up(&priv->wx_sem);
442 return ret;
446 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
447 union iwreq_data *wrqu, char *b)
450 int ret;
451 struct r8192_priv *priv = ieee80211_priv(dev);
453 if (priv->bHwRadioOff)
454 return 0;
456 if(!priv->up) return -ENETDOWN;
458 down(&priv->wx_sem);
460 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
462 up(&priv->wx_sem);
464 return ret;
467 static int r8192_wx_set_essid(struct net_device *dev,
468 struct iw_request_info *a,
469 union iwreq_data *wrqu, char *b)
471 struct r8192_priv *priv = ieee80211_priv(dev);
472 RT_RF_POWER_STATE rtState;
473 int ret;
475 if (priv->bHwRadioOff)
476 return 0;
478 rtState = priv->ieee80211->eRFPowerState;
479 down(&priv->wx_sem);
481 #ifdef ENABLE_IPS
482 down(&priv->ieee80211->ips_sem);
483 IPSLeave(dev);
484 up(&priv->ieee80211->ips_sem);
485 #endif
486 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
488 up(&priv->wx_sem);
490 return ret;
496 static int r8192_wx_get_essid(struct net_device *dev,
497 struct iw_request_info *a,
498 union iwreq_data *wrqu, char *b)
500 int ret;
501 struct r8192_priv *priv = ieee80211_priv(dev);
503 down(&priv->wx_sem);
505 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
507 up(&priv->wx_sem);
509 return ret;
513 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
514 union iwreq_data *wrqu, char *b)
516 int ret;
517 struct r8192_priv *priv = ieee80211_priv(dev);
519 if (priv->bHwRadioOff)
520 return 0;
522 down(&priv->wx_sem);
524 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
526 up(&priv->wx_sem);
527 return ret;
530 static int r8192_wx_get_name(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *extra)
534 struct r8192_priv *priv = ieee80211_priv(dev);
535 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
539 static int r8192_wx_set_frag(struct net_device *dev,
540 struct iw_request_info *info,
541 union iwreq_data *wrqu, char *extra)
543 struct r8192_priv *priv = ieee80211_priv(dev);
545 if (priv->bHwRadioOff)
546 return 0;
548 if (wrqu->frag.disabled)
549 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
550 else {
551 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
552 wrqu->frag.value > MAX_FRAG_THRESHOLD)
553 return -EINVAL;
555 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
558 return 0;
562 static int r8192_wx_get_frag(struct net_device *dev,
563 struct iw_request_info *info,
564 union iwreq_data *wrqu, char *extra)
566 struct r8192_priv *priv = ieee80211_priv(dev);
568 wrqu->frag.value = priv->ieee80211->fts;
569 wrqu->frag.fixed = 0; /* no auto select */
570 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
572 return 0;
576 static int r8192_wx_set_wap(struct net_device *dev,
577 struct iw_request_info *info,
578 union iwreq_data *awrq,
579 char *extra)
582 int ret;
583 struct r8192_priv *priv = ieee80211_priv(dev);
584 // struct sockaddr *temp = (struct sockaddr *)awrq;
586 if (priv->bHwRadioOff)
587 return 0;
589 down(&priv->wx_sem);
591 #ifdef ENABLE_IPS
592 down(&priv->ieee80211->ips_sem);
593 IPSLeave(dev);
594 up(&priv->ieee80211->ips_sem);
595 #endif
596 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
598 up(&priv->wx_sem);
600 return ret;
605 static int r8192_wx_get_wap(struct net_device *dev,
606 struct iw_request_info *info,
607 union iwreq_data *wrqu, char *extra)
609 struct r8192_priv *priv = ieee80211_priv(dev);
611 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
615 static int r8192_wx_get_enc(struct net_device *dev,
616 struct iw_request_info *info,
617 union iwreq_data *wrqu, char *key)
619 struct r8192_priv *priv = ieee80211_priv(dev);
621 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
624 static int r8192_wx_set_enc(struct net_device *dev,
625 struct iw_request_info *info,
626 union iwreq_data *wrqu, char *key)
628 struct r8192_priv *priv = ieee80211_priv(dev);
629 int ret;
631 struct ieee80211_device *ieee = priv->ieee80211;
632 //u32 TargetContent;
633 u32 hwkey[4]={0,0,0,0};
634 u8 mask=0xff;
635 u32 key_idx=0;
636 u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
637 {0x00,0x00,0x00,0x00,0x00,0x01},
638 {0x00,0x00,0x00,0x00,0x00,0x02},
639 {0x00,0x00,0x00,0x00,0x00,0x03} };
640 int i;
642 if (priv->bHwRadioOff)
643 return 0;
645 if(!priv->up) return -ENETDOWN;
647 priv->ieee80211->wx_set_enc = 1;
648 #ifdef ENABLE_IPS
649 down(&priv->ieee80211->ips_sem);
650 IPSLeave(dev);
651 up(&priv->ieee80211->ips_sem);
652 #endif
654 down(&priv->wx_sem);
656 RT_TRACE(COMP_SEC, "Setting SW wep key");
657 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
659 up(&priv->wx_sem);
661 //sometimes, the length is zero while we do not type key value
662 if(wrqu->encoding.length!=0){
664 for(i=0 ; i<4 ; i++){
665 hwkey[i] |= key[4*i+0]&mask;
666 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
667 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
668 hwkey[i] |= (key[4*i+1]&mask)<<8;
669 hwkey[i] |= (key[4*i+2]&mask)<<16;
670 hwkey[i] |= (key[4*i+3]&mask)<<24;
673 #define CONF_WEP40 0x4
674 #define CONF_WEP104 0x14
676 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
677 case 0: key_idx = ieee->tx_keyidx; break;
678 case 1: key_idx = 0; break;
679 case 2: key_idx = 1; break;
680 case 3: key_idx = 2; break;
681 case 4: key_idx = 3; break;
682 default: break;
685 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
686 if(wrqu->encoding.length==0x5){
687 ieee->pairwise_key_type = KEY_TYPE_WEP40;
688 EnableHWSecurityConfig8192(dev);
689 setKey( dev,
690 key_idx, //EntryNo
691 key_idx, //KeyIndex
692 KEY_TYPE_WEP40, //KeyType
693 zero_addr[key_idx],
694 0, //DefaultKey
695 hwkey); //KeyContent
697 #if 0
698 if(key_idx == 0){
700 //write_nic_byte(dev, SECR, 7);
701 setKey( dev,
702 4, //EntryNo
703 key_idx, //KeyIndex
704 KEY_TYPE_WEP40, //KeyType
705 broadcast_addr, //addr
706 0, //DefaultKey
707 hwkey); //KeyContent
709 #endif
712 else if(wrqu->encoding.length==0xd){
713 ieee->pairwise_key_type = KEY_TYPE_WEP104;
714 EnableHWSecurityConfig8192(dev);
715 setKey( dev,
716 key_idx, //EntryNo
717 key_idx, //KeyIndex
718 KEY_TYPE_WEP104, //KeyType
719 zero_addr[key_idx],
720 0, //DefaultKey
721 hwkey); //KeyContent
722 #if 0
723 if(key_idx == 0){
725 //write_nic_byte(dev, SECR, 7);
726 setKey( dev,
727 4, //EntryNo
728 key_idx, //KeyIndex
729 KEY_TYPE_WEP104, //KeyType
730 broadcast_addr, //addr
731 0, //DefaultKey
732 hwkey); //KeyContent
734 #endif
736 else printk("wrong type in WEP, not WEP40 and WEP104\n");
741 #if 0
742 //consider the setting different key index situation
743 //wrqu->encoding.flags = 801 means that we set key with index "1"
744 if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
745 printk("===>1\n");
746 //write_nic_byte(dev, SECR, 7);
747 EnableHWSecurityConfig8192(dev);
748 //copy wpa config from default key(key0~key3) to broadcast key(key5)
750 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
751 write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
752 write_cam(dev, (4*6)+1, 0xffffffff);
753 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
754 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
755 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
756 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
758 #endif
760 priv->ieee80211->wx_set_enc = 0;
762 return ret;
766 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
767 iwreq_data *wrqu, char *p){
769 struct r8192_priv *priv = ieee80211_priv(dev);
770 int *parms=(int*)p;
771 int mode=parms[0];
773 priv->ieee80211->active_scan = mode;
775 return 1;
780 static int r8192_wx_set_retry(struct net_device *dev,
781 struct iw_request_info *info,
782 union iwreq_data *wrqu, char *extra)
784 struct r8192_priv *priv = ieee80211_priv(dev);
785 int err = 0;
787 if (priv->bHwRadioOff)
788 return 0;
790 down(&priv->wx_sem);
792 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
793 wrqu->retry.disabled){
794 err = -EINVAL;
795 goto exit;
797 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
798 err = -EINVAL;
799 goto exit;
802 if(wrqu->retry.value > R8180_MAX_RETRY){
803 err= -EINVAL;
804 goto exit;
806 if (wrqu->retry.flags & IW_RETRY_MAX) {
807 priv->retry_rts = wrqu->retry.value;
808 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
810 }else {
811 priv->retry_data = wrqu->retry.value;
812 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
815 /* FIXME !
816 * We might try to write directly the TX config register
817 * or to restart just the (R)TX process.
818 * I'm unsure if whole reset is really needed
821 rtl8192_commit(dev);
823 if(priv->up){
824 rtl8180_rtx_disable(dev);
825 rtl8180_rx_enable(dev);
826 rtl8180_tx_enable(dev);
830 exit:
831 up(&priv->wx_sem);
833 return err;
836 static int r8192_wx_get_retry(struct net_device *dev,
837 struct iw_request_info *info,
838 union iwreq_data *wrqu, char *extra)
840 struct r8192_priv *priv = ieee80211_priv(dev);
843 wrqu->retry.disabled = 0; /* can't be disabled */
845 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
846 IW_RETRY_LIFETIME)
847 return -EINVAL;
849 if (wrqu->retry.flags & IW_RETRY_MAX) {
850 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
851 wrqu->retry.value = priv->retry_rts;
852 } else {
853 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
854 wrqu->retry.value = priv->retry_data;
856 //DMESG("returning %d",wrqu->retry.value);
859 return 0;
862 static int r8192_wx_get_sens(struct net_device *dev,
863 struct iw_request_info *info,
864 union iwreq_data *wrqu, char *extra)
866 struct r8192_priv *priv = ieee80211_priv(dev);
867 if(priv->rf_set_sens == NULL)
868 return -1; /* we have not this support for this radio */
869 wrqu->sens.value = priv->sens;
870 return 0;
874 static int r8192_wx_set_sens(struct net_device *dev,
875 struct iw_request_info *info,
876 union iwreq_data *wrqu, char *extra)
879 struct r8192_priv *priv = ieee80211_priv(dev);
881 short err = 0;
883 if (priv->bHwRadioOff)
884 return 0;
886 down(&priv->wx_sem);
887 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
888 if(priv->rf_set_sens == NULL) {
889 err= -1; /* we have not this support for this radio */
890 goto exit;
892 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
893 priv->sens = wrqu->sens.value;
894 else
895 err= -EINVAL;
897 exit:
898 up(&priv->wx_sem);
900 return err;
903 #if (WIRELESS_EXT >= 18)
904 static int r8192_wx_set_enc_ext(struct net_device *dev,
905 struct iw_request_info *info,
906 union iwreq_data *wrqu, char *extra)
908 int ret=0;
909 struct r8192_priv *priv = ieee80211_priv(dev);
910 struct ieee80211_device* ieee = priv->ieee80211;
912 if (priv->bHwRadioOff)
913 return 0;
915 down(&priv->wx_sem);
917 priv->ieee80211->wx_set_enc = 1;
919 #ifdef ENABLE_IPS
920 down(&priv->ieee80211->ips_sem);
921 IPSLeave(dev);
922 up(&priv->ieee80211->ips_sem);
923 #endif
925 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
928 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
929 u8 zero[6] = {0};
930 u32 key[4] = {0};
931 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
932 struct iw_point *encoding = &wrqu->encoding;
933 #if 0
934 static u8 CAM_CONST_ADDR[4][6] = {
935 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
936 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
937 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
938 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
939 #endif
940 u8 idx = 0, alg = 0, group = 0;
941 if ((encoding->flags & IW_ENCODE_DISABLED) ||
942 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
944 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
945 CamResetAllEntry(dev);
946 goto end_hw_sec;
948 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;
949 idx = encoding->flags & IW_ENCODE_INDEX;
950 if (idx)
951 idx --;
952 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
954 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
956 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
957 alg = KEY_TYPE_WEP104;
958 ieee->pairwise_key_type = alg;
959 EnableHWSecurityConfig8192(dev);
961 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
963 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
965 if (ext->key_len == 13)
966 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
967 setKey( dev,
968 idx,//EntryNo
969 idx, //KeyIndex
970 alg, //KeyType
971 zero, //MacAddr
972 0, //DefaultKey
973 key); //KeyContent
975 else if (group)
977 ieee->group_key_type = alg;
978 setKey( dev,
979 idx,//EntryNo
980 idx, //KeyIndex
981 alg, //KeyType
982 broadcast_addr, //MacAddr
983 0, //DefaultKey
984 key); //KeyContent
986 else //pairwise key
988 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
989 write_nic_byte(dev, 0x173, 1); //fix aes bug
991 setKey( dev,
992 4,//EntryNo
993 idx, //KeyIndex
994 alg, //KeyType
995 (u8*)ieee->ap_mac_addr, //MacAddr
996 0, //DefaultKey
997 key); //KeyContent
1003 end_hw_sec:
1004 priv->ieee80211->wx_set_enc = 0;
1005 up(&priv->wx_sem);
1006 return ret;
1009 static int r8192_wx_set_auth(struct net_device *dev,
1010 struct iw_request_info *info,
1011 union iwreq_data *data, char *extra)
1013 int ret=0;
1014 //printk("====>%s()\n", __FUNCTION__);
1015 struct r8192_priv *priv = ieee80211_priv(dev);
1017 if (priv->bHwRadioOff)
1018 return 0;
1020 down(&priv->wx_sem);
1021 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1022 up(&priv->wx_sem);
1023 return ret;
1026 static int r8192_wx_set_mlme(struct net_device *dev,
1027 struct iw_request_info *info,
1028 union iwreq_data *wrqu, char *extra)
1030 //printk("====>%s()\n", __FUNCTION__);
1032 int ret=0;
1033 struct r8192_priv *priv = ieee80211_priv(dev);
1035 if (priv->bHwRadioOff)
1036 return 0;
1038 down(&priv->wx_sem);
1039 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1040 up(&priv->wx_sem);
1041 return ret;
1043 #endif
1044 static int r8192_wx_set_gen_ie(struct net_device *dev,
1045 struct iw_request_info *info,
1046 union iwreq_data *data, char *extra)
1048 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1049 int ret=0;
1050 struct r8192_priv *priv = ieee80211_priv(dev);
1052 if (priv->bHwRadioOff)
1053 return 0;
1055 down(&priv->wx_sem);
1056 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1057 up(&priv->wx_sem);
1058 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1059 return ret;
1062 static int dummy(struct net_device *dev, struct iw_request_info *a,
1063 union iwreq_data *wrqu,char *b)
1065 return -1;
1068 // check ac/dc status with the help of user space application */
1069 static int r8192_wx_adapter_power_status(struct net_device *dev,
1070 struct iw_request_info *info,
1071 union iwreq_data *wrqu, char *extra)
1073 struct r8192_priv *priv = ieee80211_priv(dev);
1074 #ifdef ENABLE_LPS
1075 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
1076 struct ieee80211_device* ieee = priv->ieee80211;
1077 #endif
1078 down(&priv->wx_sem);
1080 #ifdef ENABLE_LPS
1081 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1082 // ieee->ps shall not be set under DC mode, otherwise it conflict
1083 // with Leisure power save mode setting.
1085 if(*extra || priv->force_lps) {
1086 priv->ps_force = false;
1087 pPSC->bLeisurePs = true;
1088 } else {
1089 //LZM for PS-Poll AID issue. 090429
1090 if(priv->ieee80211->state == IEEE80211_LINKED)
1091 LeisurePSLeave(dev);
1093 priv->ps_force = true;
1094 pPSC->bLeisurePs = false;
1095 ieee->ps = *extra;
1098 #endif
1099 up(&priv->wx_sem);
1100 return 0;
1105 static iw_handler r8192_wx_handlers[] =
1107 NULL, /* SIOCSIWCOMMIT */
1108 r8192_wx_get_name, /* SIOCGIWNAME */
1109 dummy, /* SIOCSIWNWID */
1110 dummy, /* SIOCGIWNWID */
1111 r8192_wx_set_freq, /* SIOCSIWFREQ */
1112 r8192_wx_get_freq, /* SIOCGIWFREQ */
1113 r8192_wx_set_mode, /* SIOCSIWMODE */
1114 r8192_wx_get_mode, /* SIOCGIWMODE */
1115 r8192_wx_set_sens, /* SIOCSIWSENS */
1116 r8192_wx_get_sens, /* SIOCGIWSENS */
1117 NULL, /* SIOCSIWRANGE */
1118 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1119 NULL, /* SIOCSIWPRIV */
1120 NULL, /* SIOCGIWPRIV */
1121 NULL, /* SIOCSIWSTATS */
1122 NULL, /* SIOCGIWSTATS */
1123 dummy, /* SIOCSIWSPY */
1124 dummy, /* SIOCGIWSPY */
1125 NULL, /* SIOCGIWTHRSPY */
1126 NULL, /* SIOCWIWTHRSPY */
1127 r8192_wx_set_wap, /* SIOCSIWAP */
1128 r8192_wx_get_wap, /* SIOCGIWAP */
1129 #if (WIRELESS_EXT >= 18)
1130 r8192_wx_set_mlme, /* MLME-- */
1131 #else
1132 NULL,
1133 #endif
1134 dummy, /* SIOCGIWAPLIST -- depricated */
1135 r8192_wx_set_scan, /* SIOCSIWSCAN */
1136 r8192_wx_get_scan, /* SIOCGIWSCAN */
1137 r8192_wx_set_essid, /* SIOCSIWESSID */
1138 r8192_wx_get_essid, /* SIOCGIWESSID */
1139 dummy, /* SIOCSIWNICKN */
1140 dummy, /* SIOCGIWNICKN */
1141 NULL, /* -- hole -- */
1142 NULL, /* -- hole -- */
1143 r8192_wx_set_rate, /* SIOCSIWRATE */
1144 r8192_wx_get_rate, /* SIOCGIWRATE */
1145 r8192_wx_set_rts, /* SIOCSIWRTS */
1146 r8192_wx_get_rts, /* SIOCGIWRTS */
1147 r8192_wx_set_frag, /* SIOCSIWFRAG */
1148 r8192_wx_get_frag, /* SIOCGIWFRAG */
1149 dummy, /* SIOCSIWTXPOW */
1150 dummy, /* SIOCGIWTXPOW */
1151 r8192_wx_set_retry, /* SIOCSIWRETRY */
1152 r8192_wx_get_retry, /* SIOCGIWRETRY */
1153 r8192_wx_set_enc, /* SIOCSIWENCODE */
1154 r8192_wx_get_enc, /* SIOCGIWENCODE */
1155 r8192_wx_set_power, /* SIOCSIWPOWER */
1156 r8192_wx_get_power, /* SIOCGIWPOWER */
1157 NULL, /*---hole---*/
1158 NULL, /*---hole---*/
1159 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1160 NULL, /* SIOCSIWGENIE */
1161 #if (WIRELESS_EXT >= 18)
1162 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1163 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1164 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1165 #else
1166 NULL,
1167 NULL,
1168 NULL,
1169 #endif
1170 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1171 NULL, /* SIOCSIWPMKSA */
1172 NULL, /*---hole---*/
1177 static const struct iw_priv_args r8192_private_args[] = {
1180 SIOCIWFIRSTPRIV + 0x0,
1181 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1185 SIOCIWFIRSTPRIV + 0x1,
1186 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1190 SIOCIWFIRSTPRIV + 0x2,
1191 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1195 SIOCIWFIRSTPRIV + 0x3,
1196 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1201 SIOCIWFIRSTPRIV + 0x4,
1202 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1203 "set_power"
1209 static iw_handler r8192_private_handler[] = {
1210 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1211 r8192_wx_set_scan_type,
1212 r8192_wx_set_rawtx,
1213 r8192_wx_force_reset,
1214 r8192_wx_adapter_power_status,
1217 //#if WIRELESS_EXT >= 17
1218 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1220 struct r8192_priv *priv = ieee80211_priv(dev);
1221 struct ieee80211_device* ieee = priv->ieee80211;
1222 struct iw_statistics* wstats = &priv->wstats;
1223 int tmp_level = 0;
1224 int tmp_qual = 0;
1225 int tmp_noise = 0;
1226 if(ieee->state < IEEE80211_LINKED)
1228 wstats->qual.qual = 0;
1229 wstats->qual.level = 0;
1230 wstats->qual.noise = 0;
1231 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1232 return wstats;
1235 tmp_level = (&ieee->current_network)->stats.rssi;
1236 tmp_qual = (&ieee->current_network)->stats.signal;
1237 tmp_noise = (&ieee->current_network)->stats.noise;
1238 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1240 wstats->qual.level = tmp_level;
1241 wstats->qual.qual = tmp_qual;
1242 wstats->qual.noise = tmp_noise;
1243 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1244 return wstats;
1246 //#endif
1249 struct iw_handler_def r8192_wx_handlers_def={
1250 .standard = r8192_wx_handlers,
1251 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1252 .private = r8192_private_handler,
1253 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1254 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1255 #if WIRELESS_EXT >= 17
1256 .get_wireless_stats = r8192_get_wireless_stats,
1257 #endif
1258 .private_args = (struct iw_priv_args *)r8192_private_args,