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"
28 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
29 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);
47 static int r8192_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
48 union iwreq_data *wrqu, char *b)
50 int *parms = (int *)b;
53 struct r8192_priv *priv = ieee80211_priv(dev);
56 DMESG("setting beacon interval to %x",bi);
58 priv->ieee80211->beacon_interval=bi;
66 static int r8192_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
67 union iwreq_data *wrqu, char *extra)
69 struct r8192_priv *priv=ieee80211_priv(dev);
70 int *parms = (int *)extra;
72 priv->ieee80211->force_associate = (parms[0] > 0);
79 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
80 union iwreq_data *wrqu, char *b)
82 struct r8192_priv *priv=ieee80211_priv(dev);
84 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
89 static int r8192_wx_get_rate(struct net_device *dev,
90 struct iw_request_info *info,
91 union iwreq_data *wrqu, char *extra)
93 struct r8192_priv *priv = ieee80211_priv(dev);
94 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
99 static int r8192_wx_set_rate(struct net_device *dev,
100 struct iw_request_info *info,
101 union iwreq_data *wrqu, char *extra)
104 struct r8192_priv *priv = ieee80211_priv(dev);
108 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
116 static int r8192_wx_set_rts(struct net_device *dev,
117 struct iw_request_info *info,
118 union iwreq_data *wrqu, char *extra)
121 struct r8192_priv *priv = ieee80211_priv(dev);
125 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
132 static int r8192_wx_get_rts(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_rts(priv->ieee80211,info,wrqu,extra);
140 static int r8192_wx_set_power(struct net_device *dev,
141 struct iw_request_info *info,
142 union iwreq_data *wrqu, char *extra)
145 struct r8192_priv *priv = ieee80211_priv(dev);
149 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
156 static int r8192_wx_get_power(struct net_device *dev,
157 struct iw_request_info *info,
158 union iwreq_data *wrqu, char *extra)
160 struct r8192_priv *priv = ieee80211_priv(dev);
161 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
165 u16 read_rtl8225(struct net_device *dev, u8 addr);
166 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
167 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
168 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
170 static int r8192_wx_read_regs(struct net_device *dev,
171 struct iw_request_info *info,
172 union iwreq_data *wrqu, char *extra)
174 struct r8192_priv *priv = ieee80211_priv(dev);
181 get_user(addr,(u8*)wrqu->data.pointer);
182 data1 = read_rtl8225(dev, addr);
183 wrqu->data.length = data1;
190 static int r8192_wx_write_regs(struct net_device *dev,
191 struct iw_request_info *info,
192 union iwreq_data *wrqu, char *extra)
194 struct r8192_priv *priv = ieee80211_priv(dev);
199 get_user(addr, (u8*)wrqu->data.pointer);
200 write_rtl8225(dev, addr, wrqu->data.length);
207 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
208 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
210 static int r8192_wx_read_bb(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);
218 for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
223 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
224 wrqu->data.length = databb;
230 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
231 static int r8192_wx_write_bb(struct net_device *dev,
232 struct iw_request_info *info,
233 union iwreq_data *wrqu, char *extra)
235 struct r8192_priv *priv = ieee80211_priv(dev);
240 get_user(databb, (u8*)wrqu->data.pointer);
241 rtl8187_write_phy(dev, wrqu->data.length, databb);
249 static int r8192_wx_write_nicb(struct net_device *dev,
250 struct iw_request_info *info,
251 union iwreq_data *wrqu, char *extra)
253 struct r8192_priv *priv = ieee80211_priv(dev);
258 get_user(addr, (u32*)wrqu->data.pointer);
259 write_nic_byte(dev, addr, wrqu->data.length);
265 static int r8192_wx_read_nicb(struct net_device *dev,
266 struct iw_request_info *info,
267 union iwreq_data *wrqu, char *extra)
269 struct r8192_priv *priv = ieee80211_priv(dev);
275 get_user(addr,(u32*)wrqu->data.pointer);
276 data1 = read_nic_byte(dev, addr);
277 wrqu->data.length = data1;
283 static int r8192_wx_get_ap_status(struct net_device *dev,
284 struct iw_request_info *info,
285 union iwreq_data *wrqu, char *extra)
287 struct r8192_priv *priv = ieee80211_priv(dev);
288 struct ieee80211_device *ieee = priv->ieee80211;
289 struct ieee80211_network *target;
294 //count the length of input ssid
295 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
297 //search for the correspoding info which is received
298 list_for_each_entry(target, &ieee->network_list, list) {
299 if ( (target->ssid_len == name_len) &&
300 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
301 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
302 //set flags=1 to indicate this ap is WPA
303 wrqu->data.flags = 1;
304 else wrqu->data.flags = 0;
319 static int r8192_wx_set_rawtx(struct net_device *dev,
320 struct iw_request_info *info,
321 union iwreq_data *wrqu, char *extra)
323 struct r8192_priv *priv = ieee80211_priv(dev);
328 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
336 static int r8192_wx_force_reset(struct net_device *dev,
337 struct iw_request_info *info,
338 union iwreq_data *wrqu, char *extra)
340 struct r8192_priv *priv = ieee80211_priv(dev);
344 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
345 priv->force_reset = *extra;
352 static int r8192_wx_set_crcmon(struct net_device *dev,
353 struct iw_request_info *info,
354 union iwreq_data *wrqu, char *extra)
356 struct r8192_priv *priv = ieee80211_priv(dev);
357 int *parms = (int *)extra;
358 int enable = (parms[0] > 0);
359 short prev = priv->crcmon;
368 DMESG("bad CRC in monitor mode are %s",
369 priv->crcmon ? "accepted" : "rejected");
371 if(prev != priv->crcmon && priv->up){
381 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
382 union iwreq_data *wrqu, char *b)
384 struct r8192_priv *priv = ieee80211_priv(dev);
385 RT_RF_POWER_STATE rtState;
388 rtState = priv->ieee80211->eRFPowerState;
391 if(wrqu->mode == IW_MODE_ADHOC){
393 if(priv->ieee80211->PowerSaveControl.bInactivePs){
394 if(rtState == eRfOff){
395 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
397 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
402 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
409 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
411 //rtl8187_set_rxconf(dev);
417 struct iw_range_with_scan_capa
419 /* Informative stuff (to choose between different interface) */
420 __u32 throughput; /* To give an idea... */
421 /* In theory this value should be the maximum benchmarked
422 * TCP/IP throughput, because with most of these devices the
423 * bit rate is meaningless (overhead an co) to estimate how
424 * fast the connection will go and pick the fastest one.
425 * I suggest people to play with Netperf or any benchmark...
428 /* NWID (or domain id) */
429 __u32 min_nwid; /* Minimal NWID we are able to set */
430 __u32 max_nwid; /* Maximal NWID we are able to set */
432 /* Old Frequency (backward compat - moved lower ) */
433 __u16 old_num_channels;
434 __u8 old_num_frequency;
436 /* Scan capabilities */
439 static int rtl8180_wx_get_range(struct net_device *dev,
440 struct iw_request_info *info,
441 union iwreq_data *wrqu, char *extra)
443 struct iw_range *range = (struct iw_range *)extra;
444 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
445 struct r8192_priv *priv = ieee80211_priv(dev);
449 wrqu->data.length = sizeof(*range);
450 memset(range, 0, sizeof(*range));
452 /* Let's try to keep this struct in the same order as in
453 * linux/include/wireless.h
456 /* TODO: See what values we can set, and remove the ones we can't
457 * set, or fill them with some default data.
460 /* ~5 Mb/s real (802.11b) */
461 range->throughput = 5 * 1000 * 1000;
463 // TODO: Not used in 802.11b?
464 // range->min_nwid; /* Minimal NWID we are able to set */
465 // TODO: Not used in 802.11b?
466 // range->max_nwid; /* Maximal NWID we are able to set */
468 /* Old Frequency (backward compat - moved lower ) */
469 // range->old_num_channels;
470 // range->old_num_frequency;
471 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
472 if(priv->rf_set_sens != NULL)
473 range->sensitivity = priv->max_sens; /* signal level threshold range */
475 range->max_qual.qual = 100;
476 /* TODO: Find real max RSSI and stick here */
477 range->max_qual.level = 0;
478 range->max_qual.noise = -98;
479 range->max_qual.updated = 7; /* Updated all three */
481 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
482 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
483 range->avg_qual.level = 20 + -98;
484 range->avg_qual.noise = 0;
485 range->avg_qual.updated = 7; /* Updated all three */
487 range->num_bitrates = RATE_COUNT;
489 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
490 range->bitrate[i] = rtl8180_rates[i];
493 range->min_frag = MIN_FRAG_THRESHOLD;
494 range->max_frag = MAX_FRAG_THRESHOLD;
497 range->max_pmp = 5000000;
499 range->max_pmt = 65535*1000;
500 range->pmp_flags = IW_POWER_PERIOD;
501 range->pmt_flags = IW_POWER_TIMEOUT;
502 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
503 range->we_version_compiled = WIRELESS_EXT;
504 range->we_version_source = 16;
506 // range->retry_capa; /* What retry options are supported */
507 // range->retry_flags; /* How to decode max/min retry limit */
508 // range->r_time_flags; /* How to decode max/min retry life */
509 // range->min_retry; /* Minimal number of retries */
510 // range->max_retry; /* Maximal number of retries */
511 // range->min_r_time; /* Minimal retry lifetime */
512 // range->max_r_time; /* Maximal retry lifetime */
515 for (i = 0, val = 0; i < 14; i++) {
517 // Include only legal frequencies for some countries
519 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
521 if ((priv->ieee80211->channel_map)[i+1]) {
523 range->freq[val].i = i + 1;
524 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
525 range->freq[val].e = 1;
528 // FIXME: do we need to set anything for channels
532 if (val == IW_MAX_FREQUENCIES)
535 range->num_frequency = val;
536 range->num_channels = val;
537 #if WIRELESS_EXT > 17
538 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
539 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
541 tmp->scan_capa = 0x01;
546 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
547 union iwreq_data *wrqu, char *b)
549 struct r8192_priv *priv = ieee80211_priv(dev);
550 struct ieee80211_device* ieee = priv->ieee80211;
551 RT_RF_POWER_STATE rtState;
553 rtState = priv->ieee80211->eRFPowerState;
554 if(!priv->up) return -ENETDOWN;
555 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
558 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
560 struct iw_scan_req* req = (struct iw_scan_req*)b;
563 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
564 ieee->current_network.ssid_len = req->essid_len;
565 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
566 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
572 priv->ieee80211->actscanning = true;
573 if(priv->ieee80211->state != IEEE80211_LINKED){
574 if(priv->ieee80211->PowerSaveControl.bInactivePs){
575 if(rtState == eRfOff){
576 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
578 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
583 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
588 priv->ieee80211->scanning = 0;
589 ieee80211_softmac_scan_syncro(priv->ieee80211);
595 if(priv->ieee80211->state != IEEE80211_LINKED){
596 priv->ieee80211->scanning = 0;
597 ieee80211_softmac_scan_syncro(priv->ieee80211);
602 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
609 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
610 union iwreq_data *wrqu, char *b)
614 struct r8192_priv *priv = ieee80211_priv(dev);
616 if(!priv->up) return -ENETDOWN;
620 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
627 static int r8192_wx_set_essid(struct net_device *dev,
628 struct iw_request_info *a,
629 union iwreq_data *wrqu, char *b)
631 struct r8192_priv *priv = ieee80211_priv(dev);
632 RT_RF_POWER_STATE rtState;
635 rtState = priv->ieee80211->eRFPowerState;
638 if(priv->ieee80211->PowerSaveControl.bInactivePs){
639 if(rtState == eRfOff){
640 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
642 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
647 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
653 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
663 static int r8192_wx_get_essid(struct net_device *dev,
664 struct iw_request_info *a,
665 union iwreq_data *wrqu, char *b)
668 struct r8192_priv *priv = ieee80211_priv(dev);
672 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
680 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
681 union iwreq_data *wrqu, char *b)
684 struct r8192_priv *priv = ieee80211_priv(dev);
688 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
694 static int r8192_wx_get_name(struct net_device *dev,
695 struct iw_request_info *info,
696 union iwreq_data *wrqu, char *extra)
698 struct r8192_priv *priv = ieee80211_priv(dev);
699 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
703 static int r8192_wx_set_frag(struct net_device *dev,
704 struct iw_request_info *info,
705 union iwreq_data *wrqu, char *extra)
707 struct r8192_priv *priv = ieee80211_priv(dev);
709 if (wrqu->frag.disabled)
710 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
712 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
713 wrqu->frag.value > MAX_FRAG_THRESHOLD)
716 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
723 static int r8192_wx_get_frag(struct net_device *dev,
724 struct iw_request_info *info,
725 union iwreq_data *wrqu, char *extra)
727 struct r8192_priv *priv = ieee80211_priv(dev);
729 wrqu->frag.value = priv->ieee80211->fts;
730 wrqu->frag.fixed = 0; /* no auto select */
731 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
737 static int r8192_wx_set_wap(struct net_device *dev,
738 struct iw_request_info *info,
739 union iwreq_data *awrq,
744 struct r8192_priv *priv = ieee80211_priv(dev);
745 // struct sockaddr *temp = (struct sockaddr *)awrq;
749 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
758 static int r8192_wx_get_wap(struct net_device *dev,
759 struct iw_request_info *info,
760 union iwreq_data *wrqu, char *extra)
762 struct r8192_priv *priv = ieee80211_priv(dev);
764 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
768 static int r8192_wx_get_enc(struct net_device *dev,
769 struct iw_request_info *info,
770 union iwreq_data *wrqu, char *key)
772 struct r8192_priv *priv = ieee80211_priv(dev);
774 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
777 static int r8192_wx_set_enc(struct net_device *dev,
778 struct iw_request_info *info,
779 union iwreq_data *wrqu, char *key)
781 struct r8192_priv *priv = ieee80211_priv(dev);
784 struct ieee80211_device *ieee = priv->ieee80211;
786 u32 hwkey[4]={0,0,0,0};
789 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
790 {0x00,0x00,0x00,0x00,0x00,0x01},
791 {0x00,0x00,0x00,0x00,0x00,0x02},
792 {0x00,0x00,0x00,0x00,0x00,0x03} };
795 if(!priv->up) return -ENETDOWN;
799 RT_TRACE(COMP_SEC, "Setting SW wep key");
800 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
805 //sometimes, the length is zero while we do not type key value
806 if(wrqu->encoding.length!=0){
808 for(i=0 ; i<4 ; i++){
809 hwkey[i] |= key[4*i+0]&mask;
810 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
811 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
812 hwkey[i] |= (key[4*i+1]&mask)<<8;
813 hwkey[i] |= (key[4*i+2]&mask)<<16;
814 hwkey[i] |= (key[4*i+3]&mask)<<24;
817 #define CONF_WEP40 0x4
818 #define CONF_WEP104 0x14
820 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
821 case 0: key_idx = ieee->tx_keyidx; break;
822 case 1: key_idx = 0; break;
823 case 2: key_idx = 1; break;
824 case 3: key_idx = 2; break;
825 case 4: key_idx = 3; break;
829 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
830 if(wrqu->encoding.length==0x5){
831 ieee->pairwise_key_type = KEY_TYPE_WEP40;
832 EnableHWSecurityConfig8192(dev);
836 KEY_TYPE_WEP40, //KeyType
844 //write_nic_byte(dev, SECR, 7);
848 KEY_TYPE_WEP40, //KeyType
849 broadcast_addr, //addr
856 else if(wrqu->encoding.length==0xd){
857 ieee->pairwise_key_type = KEY_TYPE_WEP104;
858 EnableHWSecurityConfig8192(dev);
862 KEY_TYPE_WEP104, //KeyType
869 //write_nic_byte(dev, SECR, 7);
873 KEY_TYPE_WEP104, //KeyType
874 broadcast_addr, //addr
880 else printk("wrong type in WEP, not WEP40 and WEP104\n");
886 //consider the setting different key index situation
887 //wrqu->encoding.flags = 801 means that we set key with index "1"
888 if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
890 //write_nic_byte(dev, SECR, 7);
891 EnableHWSecurityConfig8192(dev);
892 //copy wpa config from default key(key0~key3) to broadcast key(key5)
894 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
895 write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
896 write_cam(dev, (4*6)+1, 0xffffffff);
897 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
898 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
899 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
900 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
908 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
909 iwreq_data *wrqu, char *p){
911 struct r8192_priv *priv = ieee80211_priv(dev);
915 priv->ieee80211->active_scan = mode;
922 static int r8192_wx_set_retry(struct net_device *dev,
923 struct iw_request_info *info,
924 union iwreq_data *wrqu, char *extra)
926 struct r8192_priv *priv = ieee80211_priv(dev);
931 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
932 wrqu->retry.disabled){
936 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
941 if(wrqu->retry.value > R8180_MAX_RETRY){
945 if (wrqu->retry.flags & IW_RETRY_MAX) {
946 priv->retry_rts = wrqu->retry.value;
947 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
950 priv->retry_data = wrqu->retry.value;
951 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
955 * We might try to write directly the TX config register
956 * or to restart just the (R)TX process.
957 * I'm unsure if whole reset is really needed
963 rtl8180_rtx_disable(dev);
964 rtl8180_rx_enable(dev);
965 rtl8180_tx_enable(dev);
975 static int r8192_wx_get_retry(struct net_device *dev,
976 struct iw_request_info *info,
977 union iwreq_data *wrqu, char *extra)
979 struct r8192_priv *priv = ieee80211_priv(dev);
982 wrqu->retry.disabled = 0; /* can't be disabled */
984 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
988 if (wrqu->retry.flags & IW_RETRY_MAX) {
989 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
990 wrqu->retry.value = priv->retry_rts;
992 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
993 wrqu->retry.value = priv->retry_data;
995 //DMESG("returning %d",wrqu->retry.value);
1001 static int r8192_wx_get_sens(struct net_device *dev,
1002 struct iw_request_info *info,
1003 union iwreq_data *wrqu, char *extra)
1005 struct r8192_priv *priv = ieee80211_priv(dev);
1006 if(priv->rf_set_sens == NULL)
1007 return -1; /* we have not this support for this radio */
1008 wrqu->sens.value = priv->sens;
1013 static int r8192_wx_set_sens(struct net_device *dev,
1014 struct iw_request_info *info,
1015 union iwreq_data *wrqu, char *extra)
1018 struct r8192_priv *priv = ieee80211_priv(dev);
1021 down(&priv->wx_sem);
1022 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
1023 if(priv->rf_set_sens == NULL) {
1024 err= -1; /* we have not this support for this radio */
1027 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
1028 priv->sens = wrqu->sens.value;
1038 #if (WIRELESS_EXT >= 18)
1040 static int r8192_wx_get_enc_ext(struct net_device *dev,
1041 struct iw_request_info *info,
1042 union iwreq_data *wrqu, char *extra)
1044 struct r8192_priv *priv = ieee80211_priv(dev);
1046 ret = ieee80211_wx_get_encode_ext(priv->ieee80211, info, wrqu, extra);
1050 static int r8192_wx_set_enc_ext(struct net_device *dev,
1051 struct iw_request_info *info,
1052 union iwreq_data *wrqu, char *extra)
1055 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1056 struct r8192_priv *priv = ieee80211_priv(dev);
1057 struct ieee80211_device* ieee = priv->ieee80211;
1059 down(&priv->wx_sem);
1060 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
1063 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1066 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1067 struct iw_point *encoding = &wrqu->encoding;
1069 static u8 CAM_CONST_ADDR[4][6] = {
1070 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1071 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1072 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1073 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1075 u8 idx = 0, alg = 0, group = 0;
1076 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1077 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
1079 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1080 CamResetAllEntry(dev);
1083 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;
1084 idx = encoding->flags & IW_ENCODE_INDEX;
1087 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1089 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
1091 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1092 alg = KEY_TYPE_WEP104;
1093 ieee->pairwise_key_type = alg;
1094 EnableHWSecurityConfig8192(dev);
1096 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1098 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1100 if (ext->key_len == 13)
1101 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1112 ieee->group_key_type = alg;
1117 broadcast_addr, //MacAddr
1123 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
1124 write_nic_byte(dev, 0x173, 1); //fix aes bug
1130 (u8*)ieee->ap_mac_addr, //MacAddr
1144 static int r8192_wx_set_auth(struct net_device *dev,
1145 struct iw_request_info *info,
1146 union iwreq_data *data, char *extra)
1149 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1150 //printk("====>%s()\n", __FUNCTION__);
1151 struct r8192_priv *priv = ieee80211_priv(dev);
1152 down(&priv->wx_sem);
1153 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1159 static int r8192_wx_set_mlme(struct net_device *dev,
1160 struct iw_request_info *info,
1161 union iwreq_data *wrqu, char *extra)
1163 //printk("====>%s()\n", __FUNCTION__);
1166 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1167 struct r8192_priv *priv = ieee80211_priv(dev);
1168 down(&priv->wx_sem);
1169 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1175 static int r8192_wx_set_gen_ie(struct net_device *dev,
1176 struct iw_request_info *info,
1177 union iwreq_data *data, char *extra)
1179 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1181 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1182 struct r8192_priv *priv = ieee80211_priv(dev);
1183 down(&priv->wx_sem);
1185 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1188 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1195 static int dummy(struct net_device *dev, struct iw_request_info *a,
1196 union iwreq_data *wrqu,char *b)
1202 static iw_handler r8192_wx_handlers[] =
1204 NULL, /* SIOCSIWCOMMIT */
1205 r8192_wx_get_name, /* SIOCGIWNAME */
1206 dummy, /* SIOCSIWNWID */
1207 dummy, /* SIOCGIWNWID */
1208 r8192_wx_set_freq, /* SIOCSIWFREQ */
1209 r8192_wx_get_freq, /* SIOCGIWFREQ */
1210 r8192_wx_set_mode, /* SIOCSIWMODE */
1211 r8192_wx_get_mode, /* SIOCGIWMODE */
1212 r8192_wx_set_sens, /* SIOCSIWSENS */
1213 r8192_wx_get_sens, /* SIOCGIWSENS */
1214 NULL, /* SIOCSIWRANGE */
1215 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1216 NULL, /* SIOCSIWPRIV */
1217 NULL, /* SIOCGIWPRIV */
1218 NULL, /* SIOCSIWSTATS */
1219 NULL, /* SIOCGIWSTATS */
1220 dummy, /* SIOCSIWSPY */
1221 dummy, /* SIOCGIWSPY */
1222 NULL, /* SIOCGIWTHRSPY */
1223 NULL, /* SIOCWIWTHRSPY */
1224 r8192_wx_set_wap, /* SIOCSIWAP */
1225 r8192_wx_get_wap, /* SIOCGIWAP */
1226 #if (WIRELESS_EXT >= 18)
1227 r8192_wx_set_mlme, /* MLME-- */
1231 dummy, /* SIOCGIWAPLIST -- depricated */
1232 r8192_wx_set_scan, /* SIOCSIWSCAN */
1233 r8192_wx_get_scan, /* SIOCGIWSCAN */
1234 r8192_wx_set_essid, /* SIOCSIWESSID */
1235 r8192_wx_get_essid, /* SIOCGIWESSID */
1236 dummy, /* SIOCSIWNICKN */
1237 dummy, /* SIOCGIWNICKN */
1238 NULL, /* -- hole -- */
1239 NULL, /* -- hole -- */
1240 r8192_wx_set_rate, /* SIOCSIWRATE */
1241 r8192_wx_get_rate, /* SIOCGIWRATE */
1242 r8192_wx_set_rts, /* SIOCSIWRTS */
1243 r8192_wx_get_rts, /* SIOCGIWRTS */
1244 r8192_wx_set_frag, /* SIOCSIWFRAG */
1245 r8192_wx_get_frag, /* SIOCGIWFRAG */
1246 dummy, /* SIOCSIWTXPOW */
1247 dummy, /* SIOCGIWTXPOW */
1248 r8192_wx_set_retry, /* SIOCSIWRETRY */
1249 r8192_wx_get_retry, /* SIOCGIWRETRY */
1250 r8192_wx_set_enc, /* SIOCSIWENCODE */
1251 r8192_wx_get_enc, /* SIOCGIWENCODE */
1252 r8192_wx_set_power, /* SIOCSIWPOWER */
1253 r8192_wx_get_power, /* SIOCGIWPOWER */
1254 NULL, /*---hole---*/
1255 NULL, /*---hole---*/
1256 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1257 NULL, /* SIOCSIWGENIE */
1258 #if (WIRELESS_EXT >= 18)
1259 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1260 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1261 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1267 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1268 NULL, /* SIOCSIWPMKSA */
1269 NULL, /*---hole---*/
1274 static const struct iw_priv_args r8192_private_args[] = {
1277 SIOCIWFIRSTPRIV + 0x0,
1278 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1282 SIOCIWFIRSTPRIV + 0x1,
1283 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1287 SIOCIWFIRSTPRIV + 0x2,
1288 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1293 SIOCIWFIRSTPRIV + 0x3,
1294 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1298 SIOCIWFIRSTPRIV + 0x4,
1299 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1303 SIOCIWFIRSTPRIV + 0x5,
1304 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1308 SIOCIWFIRSTPRIV + 0x6,
1309 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1313 SIOCIWFIRSTPRIV + 0x7,
1314 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1318 SIOCIWFIRSTPRIV + 0x8,
1319 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1323 SIOCIWFIRSTPRIV + 0x9,
1324 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1330 SIOCIWFIRSTPRIV + 0x3,
1331 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1338 static iw_handler r8192_private_handler[] = {
1339 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1340 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1341 // r8192_wx_set_forceassociate,
1342 // r8192_wx_set_beaconinterval,
1343 // r8192_wx_set_monitor_type,
1344 r8192_wx_set_scan_type,
1348 r8192_wx_write_regs,
1352 r8192_wx_write_nicb,
1353 r8192_wx_get_ap_status
1355 r8192_wx_force_reset,
1358 //#if WIRELESS_EXT >= 17
1359 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1361 struct r8192_priv *priv = ieee80211_priv(dev);
1362 struct ieee80211_device* ieee = priv->ieee80211;
1363 struct iw_statistics* wstats = &priv->wstats;
1367 if(ieee->state < IEEE80211_LINKED)
1369 wstats->qual.qual = 0;
1370 wstats->qual.level = 0;
1371 wstats->qual.noise = 0;
1372 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1373 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1375 wstats->qual.updated = 0x0f;
1380 tmp_level = (&ieee->current_network)->stats.rssi;
1381 tmp_qual = (&ieee->current_network)->stats.signal;
1382 tmp_noise = (&ieee->current_network)->stats.noise;
1383 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1385 wstats->qual.level = tmp_level;
1386 wstats->qual.qual = tmp_qual;
1387 wstats->qual.noise = tmp_noise;
1388 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1389 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1391 wstats->qual.updated = 0x0f;
1398 struct iw_handler_def r8192_wx_handlers_def={
1399 .standard = r8192_wx_handlers,
1400 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1401 .private = r8192_private_handler,
1402 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1403 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1404 #if WIRELESS_EXT >= 17
1405 .get_wireless_stats = r8192_get_wireless_stats,
1407 .private_args = (struct iw_priv_args *)r8192_private_args,