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"
29 static 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);
48 static int r8192_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
49 union iwreq_data *wrqu, char *b)
51 int *parms = (int *)b;
54 struct r8192_priv *priv = ieee80211_priv(dev);
57 DMESG("setting beacon interval to %x",bi);
59 priv->ieee80211->beacon_interval=bi;
67 static int r8192_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
68 union iwreq_data *wrqu, char *extra)
70 struct r8192_priv *priv=ieee80211_priv(dev);
71 int *parms = (int *)extra;
73 priv->ieee80211->force_associate = (parms[0] > 0);
80 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
81 union iwreq_data *wrqu, char *b)
83 struct r8192_priv *priv=ieee80211_priv(dev);
85 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
90 static int r8192_wx_get_rate(struct net_device *dev,
91 struct iw_request_info *info,
92 union iwreq_data *wrqu, char *extra)
94 struct r8192_priv *priv = ieee80211_priv(dev);
95 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
100 static int r8192_wx_set_rate(struct net_device *dev,
101 struct iw_request_info *info,
102 union iwreq_data *wrqu, char *extra)
105 struct r8192_priv *priv = ieee80211_priv(dev);
109 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
117 static int r8192_wx_set_rts(struct net_device *dev,
118 struct iw_request_info *info,
119 union iwreq_data *wrqu, char *extra)
122 struct r8192_priv *priv = ieee80211_priv(dev);
126 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
133 static int r8192_wx_get_rts(struct net_device *dev,
134 struct iw_request_info *info,
135 union iwreq_data *wrqu, char *extra)
137 struct r8192_priv *priv = ieee80211_priv(dev);
138 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
141 static int r8192_wx_set_power(struct net_device *dev,
142 struct iw_request_info *info,
143 union iwreq_data *wrqu, char *extra)
146 struct r8192_priv *priv = ieee80211_priv(dev);
150 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
157 static int r8192_wx_get_power(struct net_device *dev,
158 struct iw_request_info *info,
159 union iwreq_data *wrqu, char *extra)
161 struct r8192_priv *priv = ieee80211_priv(dev);
162 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
166 u16 read_rtl8225(struct net_device *dev, u8 addr);
167 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
168 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
169 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
171 static int r8192_wx_read_regs(struct net_device *dev,
172 struct iw_request_info *info,
173 union iwreq_data *wrqu, char *extra)
175 struct r8192_priv *priv = ieee80211_priv(dev);
182 get_user(addr,(u8*)wrqu->data.pointer);
183 data1 = read_rtl8225(dev, addr);
184 wrqu->data.length = data1;
191 static int r8192_wx_write_regs(struct net_device *dev,
192 struct iw_request_info *info,
193 union iwreq_data *wrqu, char *extra)
195 struct r8192_priv *priv = ieee80211_priv(dev);
200 get_user(addr, (u8*)wrqu->data.pointer);
201 write_rtl8225(dev, addr, wrqu->data.length);
208 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
209 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
211 static int r8192_wx_read_bb(struct net_device *dev,
212 struct iw_request_info *info,
213 union iwreq_data *wrqu, char *extra)
215 struct r8192_priv *priv = ieee80211_priv(dev);
219 for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
224 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
225 wrqu->data.length = databb;
231 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
232 static int r8192_wx_write_bb(struct net_device *dev,
233 struct iw_request_info *info,
234 union iwreq_data *wrqu, char *extra)
236 struct r8192_priv *priv = ieee80211_priv(dev);
241 get_user(databb, (u8*)wrqu->data.pointer);
242 rtl8187_write_phy(dev, wrqu->data.length, databb);
250 static int r8192_wx_write_nicb(struct net_device *dev,
251 struct iw_request_info *info,
252 union iwreq_data *wrqu, char *extra)
254 struct r8192_priv *priv = ieee80211_priv(dev);
259 get_user(addr, (u32*)wrqu->data.pointer);
260 write_nic_byte(dev, addr, wrqu->data.length);
266 static int r8192_wx_read_nicb(struct net_device *dev,
267 struct iw_request_info *info,
268 union iwreq_data *wrqu, char *extra)
270 struct r8192_priv *priv = ieee80211_priv(dev);
276 get_user(addr,(u32*)wrqu->data.pointer);
277 data1 = read_nic_byte(dev, addr);
278 wrqu->data.length = data1;
284 static int r8192_wx_get_ap_status(struct net_device *dev,
285 struct iw_request_info *info,
286 union iwreq_data *wrqu, char *extra)
288 struct r8192_priv *priv = ieee80211_priv(dev);
289 struct ieee80211_device *ieee = priv->ieee80211;
290 struct ieee80211_network *target;
295 //count the length of input ssid
296 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
298 //search for the correspoding info which is received
299 list_for_each_entry(target, &ieee->network_list, list) {
300 if ( (target->ssid_len == name_len) &&
301 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
302 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
303 //set flags=1 to indicate this ap is WPA
304 wrqu->data.flags = 1;
305 else wrqu->data.flags = 0;
320 static int r8192_wx_set_rawtx(struct net_device *dev,
321 struct iw_request_info *info,
322 union iwreq_data *wrqu, char *extra)
324 struct r8192_priv *priv = ieee80211_priv(dev);
329 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
337 static int r8192_wx_force_reset(struct net_device *dev,
338 struct iw_request_info *info,
339 union iwreq_data *wrqu, char *extra)
341 struct r8192_priv *priv = ieee80211_priv(dev);
345 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
346 priv->force_reset = *extra;
353 static int r8192_wx_set_crcmon(struct net_device *dev,
354 struct iw_request_info *info,
355 union iwreq_data *wrqu, char *extra)
357 struct r8192_priv *priv = ieee80211_priv(dev);
358 int *parms = (int *)extra;
359 int enable = (parms[0] > 0);
360 short prev = priv->crcmon;
369 DMESG("bad CRC in monitor mode are %s",
370 priv->crcmon ? "accepted" : "rejected");
372 if(prev != priv->crcmon && priv->up){
382 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
383 union iwreq_data *wrqu, char *b)
385 struct r8192_priv *priv = ieee80211_priv(dev);
386 RT_RF_POWER_STATE rtState;
389 rtState = priv->ieee80211->eRFPowerState;
392 if(wrqu->mode == IW_MODE_ADHOC){
394 if(priv->ieee80211->PowerSaveControl.bInactivePs){
395 if(rtState == eRfOff){
396 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
398 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
403 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
410 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
412 //rtl8187_set_rxconf(dev);
418 struct iw_range_with_scan_capa
420 /* Informative stuff (to choose between different interface) */
421 __u32 throughput; /* To give an idea... */
422 /* In theory this value should be the maximum benchmarked
423 * TCP/IP throughput, because with most of these devices the
424 * bit rate is meaningless (overhead an co) to estimate how
425 * fast the connection will go and pick the fastest one.
426 * I suggest people to play with Netperf or any benchmark...
429 /* NWID (or domain id) */
430 __u32 min_nwid; /* Minimal NWID we are able to set */
431 __u32 max_nwid; /* Maximal NWID we are able to set */
433 /* Old Frequency (backward compat - moved lower ) */
434 __u16 old_num_channels;
435 __u8 old_num_frequency;
437 /* Scan capabilities */
440 static int rtl8180_wx_get_range(struct net_device *dev,
441 struct iw_request_info *info,
442 union iwreq_data *wrqu, char *extra)
444 struct iw_range *range = (struct iw_range *)extra;
445 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
446 struct r8192_priv *priv = ieee80211_priv(dev);
450 wrqu->data.length = sizeof(*range);
451 memset(range, 0, sizeof(*range));
453 /* Let's try to keep this struct in the same order as in
454 * linux/include/wireless.h
457 /* TODO: See what values we can set, and remove the ones we can't
458 * set, or fill them with some default data.
461 /* ~5 Mb/s real (802.11b) */
462 range->throughput = 5 * 1000 * 1000;
464 // TODO: Not used in 802.11b?
465 // range->min_nwid; /* Minimal NWID we are able to set */
466 // TODO: Not used in 802.11b?
467 // range->max_nwid; /* Maximal NWID we are able to set */
469 /* Old Frequency (backward compat - moved lower ) */
470 // range->old_num_channels;
471 // range->old_num_frequency;
472 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
473 if(priv->rf_set_sens != NULL)
474 range->sensitivity = priv->max_sens; /* signal level threshold range */
476 range->max_qual.qual = 100;
477 /* TODO: Find real max RSSI and stick here */
478 range->max_qual.level = 0;
479 range->max_qual.noise = -98;
480 range->max_qual.updated = 7; /* Updated all three */
482 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
483 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
484 range->avg_qual.level = 20 + -98;
485 range->avg_qual.noise = 0;
486 range->avg_qual.updated = 7; /* Updated all three */
488 range->num_bitrates = RATE_COUNT;
490 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
491 range->bitrate[i] = rtl8180_rates[i];
494 range->min_frag = MIN_FRAG_THRESHOLD;
495 range->max_frag = MAX_FRAG_THRESHOLD;
498 range->max_pmp = 5000000;
500 range->max_pmt = 65535*1000;
501 range->pmp_flags = IW_POWER_PERIOD;
502 range->pmt_flags = IW_POWER_TIMEOUT;
503 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
504 range->we_version_compiled = WIRELESS_EXT;
505 range->we_version_source = 16;
507 // range->retry_capa; /* What retry options are supported */
508 // range->retry_flags; /* How to decode max/min retry limit */
509 // range->r_time_flags; /* How to decode max/min retry life */
510 // range->min_retry; /* Minimal number of retries */
511 // range->max_retry; /* Maximal number of retries */
512 // range->min_r_time; /* Minimal retry lifetime */
513 // range->max_r_time; /* Maximal retry lifetime */
516 for (i = 0, val = 0; i < 14; i++) {
518 // Include only legal frequencies for some countries
520 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
522 if ((priv->ieee80211->channel_map)[i+1]) {
524 range->freq[val].i = i + 1;
525 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
526 range->freq[val].e = 1;
529 // FIXME: do we need to set anything for channels
533 if (val == IW_MAX_FREQUENCIES)
536 range->num_frequency = val;
537 range->num_channels = val;
538 #if WIRELESS_EXT > 17
539 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
540 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
542 tmp->scan_capa = 0x01;
547 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
548 union iwreq_data *wrqu, char *b)
550 struct r8192_priv *priv = ieee80211_priv(dev);
551 struct ieee80211_device* ieee = priv->ieee80211;
552 RT_RF_POWER_STATE rtState;
554 rtState = priv->ieee80211->eRFPowerState;
555 if(!priv->up) return -ENETDOWN;
556 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
559 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
561 struct iw_scan_req* req = (struct iw_scan_req*)b;
564 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
565 ieee->current_network.ssid_len = req->essid_len;
566 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
567 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
573 priv->ieee80211->actscanning = true;
574 if(priv->ieee80211->state != IEEE80211_LINKED){
575 if(priv->ieee80211->PowerSaveControl.bInactivePs){
576 if(rtState == eRfOff){
577 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
579 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
584 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
589 priv->ieee80211->scanning = 0;
590 ieee80211_softmac_scan_syncro(priv->ieee80211);
596 if(priv->ieee80211->state != IEEE80211_LINKED){
597 priv->ieee80211->scanning = 0;
598 ieee80211_softmac_scan_syncro(priv->ieee80211);
603 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
610 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
611 union iwreq_data *wrqu, char *b)
615 struct r8192_priv *priv = ieee80211_priv(dev);
617 if(!priv->up) return -ENETDOWN;
621 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
628 static int r8192_wx_set_essid(struct net_device *dev,
629 struct iw_request_info *a,
630 union iwreq_data *wrqu, char *b)
632 struct r8192_priv *priv = ieee80211_priv(dev);
633 RT_RF_POWER_STATE rtState;
636 rtState = priv->ieee80211->eRFPowerState;
639 if(priv->ieee80211->PowerSaveControl.bInactivePs){
640 if(rtState == eRfOff){
641 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
643 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
648 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
654 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
664 static int r8192_wx_get_essid(struct net_device *dev,
665 struct iw_request_info *a,
666 union iwreq_data *wrqu, char *b)
669 struct r8192_priv *priv = ieee80211_priv(dev);
673 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
681 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
682 union iwreq_data *wrqu, char *b)
685 struct r8192_priv *priv = ieee80211_priv(dev);
689 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
695 static int r8192_wx_get_name(struct net_device *dev,
696 struct iw_request_info *info,
697 union iwreq_data *wrqu, char *extra)
699 struct r8192_priv *priv = ieee80211_priv(dev);
700 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
704 static int r8192_wx_set_frag(struct net_device *dev,
705 struct iw_request_info *info,
706 union iwreq_data *wrqu, char *extra)
708 struct r8192_priv *priv = ieee80211_priv(dev);
710 if (wrqu->frag.disabled)
711 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
713 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
714 wrqu->frag.value > MAX_FRAG_THRESHOLD)
717 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
724 static int r8192_wx_get_frag(struct net_device *dev,
725 struct iw_request_info *info,
726 union iwreq_data *wrqu, char *extra)
728 struct r8192_priv *priv = ieee80211_priv(dev);
730 wrqu->frag.value = priv->ieee80211->fts;
731 wrqu->frag.fixed = 0; /* no auto select */
732 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
738 static int r8192_wx_set_wap(struct net_device *dev,
739 struct iw_request_info *info,
740 union iwreq_data *awrq,
745 struct r8192_priv *priv = ieee80211_priv(dev);
746 // struct sockaddr *temp = (struct sockaddr *)awrq;
750 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
759 static int r8192_wx_get_wap(struct net_device *dev,
760 struct iw_request_info *info,
761 union iwreq_data *wrqu, char *extra)
763 struct r8192_priv *priv = ieee80211_priv(dev);
765 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
769 static int r8192_wx_get_enc(struct net_device *dev,
770 struct iw_request_info *info,
771 union iwreq_data *wrqu, char *key)
773 struct r8192_priv *priv = ieee80211_priv(dev);
775 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
778 static int r8192_wx_set_enc(struct net_device *dev,
779 struct iw_request_info *info,
780 union iwreq_data *wrqu, char *key)
782 struct r8192_priv *priv = ieee80211_priv(dev);
785 struct ieee80211_device *ieee = priv->ieee80211;
787 u32 hwkey[4]={0,0,0,0};
790 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
791 {0x00,0x00,0x00,0x00,0x00,0x01},
792 {0x00,0x00,0x00,0x00,0x00,0x02},
793 {0x00,0x00,0x00,0x00,0x00,0x03} };
796 if(!priv->up) return -ENETDOWN;
800 RT_TRACE(COMP_SEC, "Setting SW wep key");
801 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
806 //sometimes, the length is zero while we do not type key value
807 if(wrqu->encoding.length!=0){
809 for(i=0 ; i<4 ; i++){
810 hwkey[i] |= key[4*i+0]&mask;
811 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
812 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
813 hwkey[i] |= (key[4*i+1]&mask)<<8;
814 hwkey[i] |= (key[4*i+2]&mask)<<16;
815 hwkey[i] |= (key[4*i+3]&mask)<<24;
818 #define CONF_WEP40 0x4
819 #define CONF_WEP104 0x14
821 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
822 case 0: key_idx = ieee->tx_keyidx; break;
823 case 1: key_idx = 0; break;
824 case 2: key_idx = 1; break;
825 case 3: key_idx = 2; break;
826 case 4: key_idx = 3; break;
830 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
831 if(wrqu->encoding.length==0x5){
832 ieee->pairwise_key_type = KEY_TYPE_WEP40;
833 EnableHWSecurityConfig8192(dev);
837 KEY_TYPE_WEP40, //KeyType
845 //write_nic_byte(dev, SECR, 7);
849 KEY_TYPE_WEP40, //KeyType
850 broadcast_addr, //addr
857 else if(wrqu->encoding.length==0xd){
858 ieee->pairwise_key_type = KEY_TYPE_WEP104;
859 EnableHWSecurityConfig8192(dev);
863 KEY_TYPE_WEP104, //KeyType
870 //write_nic_byte(dev, SECR, 7);
874 KEY_TYPE_WEP104, //KeyType
875 broadcast_addr, //addr
881 else printk("wrong type in WEP, not WEP40 and WEP104\n");
887 //consider the setting different key index situation
888 //wrqu->encoding.flags = 801 means that we set key with index "1"
889 if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
891 //write_nic_byte(dev, SECR, 7);
892 EnableHWSecurityConfig8192(dev);
893 //copy wpa config from default key(key0~key3) to broadcast key(key5)
895 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
896 write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
897 write_cam(dev, (4*6)+1, 0xffffffff);
898 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
899 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
900 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
901 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
909 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
910 iwreq_data *wrqu, char *p){
912 struct r8192_priv *priv = ieee80211_priv(dev);
916 priv->ieee80211->active_scan = mode;
923 static int r8192_wx_set_retry(struct net_device *dev,
924 struct iw_request_info *info,
925 union iwreq_data *wrqu, char *extra)
927 struct r8192_priv *priv = ieee80211_priv(dev);
932 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
933 wrqu->retry.disabled){
937 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
942 if(wrqu->retry.value > R8180_MAX_RETRY){
946 if (wrqu->retry.flags & IW_RETRY_MAX) {
947 priv->retry_rts = wrqu->retry.value;
948 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
951 priv->retry_data = wrqu->retry.value;
952 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
956 * We might try to write directly the TX config register
957 * or to restart just the (R)TX process.
958 * I'm unsure if whole reset is really needed
964 rtl8180_rtx_disable(dev);
965 rtl8180_rx_enable(dev);
966 rtl8180_tx_enable(dev);
976 static int r8192_wx_get_retry(struct net_device *dev,
977 struct iw_request_info *info,
978 union iwreq_data *wrqu, char *extra)
980 struct r8192_priv *priv = ieee80211_priv(dev);
983 wrqu->retry.disabled = 0; /* can't be disabled */
985 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
989 if (wrqu->retry.flags & IW_RETRY_MAX) {
990 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
991 wrqu->retry.value = priv->retry_rts;
993 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
994 wrqu->retry.value = priv->retry_data;
996 //DMESG("returning %d",wrqu->retry.value);
1002 static int r8192_wx_get_sens(struct net_device *dev,
1003 struct iw_request_info *info,
1004 union iwreq_data *wrqu, char *extra)
1006 struct r8192_priv *priv = ieee80211_priv(dev);
1007 if(priv->rf_set_sens == NULL)
1008 return -1; /* we have not this support for this radio */
1009 wrqu->sens.value = priv->sens;
1014 static int r8192_wx_set_sens(struct net_device *dev,
1015 struct iw_request_info *info,
1016 union iwreq_data *wrqu, char *extra)
1019 struct r8192_priv *priv = ieee80211_priv(dev);
1022 down(&priv->wx_sem);
1023 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
1024 if(priv->rf_set_sens == NULL) {
1025 err= -1; /* we have not this support for this radio */
1028 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
1029 priv->sens = wrqu->sens.value;
1039 #if (WIRELESS_EXT >= 18)
1041 static int r8192_wx_get_enc_ext(struct net_device *dev,
1042 struct iw_request_info *info,
1043 union iwreq_data *wrqu, char *extra)
1045 struct r8192_priv *priv = ieee80211_priv(dev);
1047 ret = ieee80211_wx_get_encode_ext(priv->ieee80211, info, wrqu, extra);
1051 static int r8192_wx_set_enc_ext(struct net_device *dev,
1052 struct iw_request_info *info,
1053 union iwreq_data *wrqu, char *extra)
1056 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1057 struct r8192_priv *priv = ieee80211_priv(dev);
1058 struct ieee80211_device* ieee = priv->ieee80211;
1060 down(&priv->wx_sem);
1061 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
1064 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1067 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1068 struct iw_point *encoding = &wrqu->encoding;
1070 static u8 CAM_CONST_ADDR[4][6] = {
1071 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1072 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1073 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1074 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1076 u8 idx = 0, alg = 0, group = 0;
1077 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1078 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
1080 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1081 CamResetAllEntry(dev);
1084 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;
1085 idx = encoding->flags & IW_ENCODE_INDEX;
1088 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1090 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
1092 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1093 alg = KEY_TYPE_WEP104;
1094 ieee->pairwise_key_type = alg;
1095 EnableHWSecurityConfig8192(dev);
1097 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1099 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1101 if (ext->key_len == 13)
1102 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1113 ieee->group_key_type = alg;
1118 broadcast_addr, //MacAddr
1124 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
1125 write_nic_byte(dev, 0x173, 1); //fix aes bug
1131 (u8*)ieee->ap_mac_addr, //MacAddr
1145 static int r8192_wx_set_auth(struct net_device *dev,
1146 struct iw_request_info *info,
1147 union iwreq_data *data, char *extra)
1150 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1151 //printk("====>%s()\n", __FUNCTION__);
1152 struct r8192_priv *priv = ieee80211_priv(dev);
1153 down(&priv->wx_sem);
1154 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1160 static int r8192_wx_set_mlme(struct net_device *dev,
1161 struct iw_request_info *info,
1162 union iwreq_data *wrqu, char *extra)
1164 //printk("====>%s()\n", __FUNCTION__);
1167 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1168 struct r8192_priv *priv = ieee80211_priv(dev);
1169 down(&priv->wx_sem);
1170 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1176 static int r8192_wx_set_gen_ie(struct net_device *dev,
1177 struct iw_request_info *info,
1178 union iwreq_data *data, char *extra)
1180 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1182 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1183 struct r8192_priv *priv = ieee80211_priv(dev);
1184 down(&priv->wx_sem);
1186 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1189 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1196 static int dummy(struct net_device *dev, struct iw_request_info *a,
1197 union iwreq_data *wrqu,char *b)
1203 static iw_handler r8192_wx_handlers[] =
1205 NULL, /* SIOCSIWCOMMIT */
1206 r8192_wx_get_name, /* SIOCGIWNAME */
1207 dummy, /* SIOCSIWNWID */
1208 dummy, /* SIOCGIWNWID */
1209 r8192_wx_set_freq, /* SIOCSIWFREQ */
1210 r8192_wx_get_freq, /* SIOCGIWFREQ */
1211 r8192_wx_set_mode, /* SIOCSIWMODE */
1212 r8192_wx_get_mode, /* SIOCGIWMODE */
1213 r8192_wx_set_sens, /* SIOCSIWSENS */
1214 r8192_wx_get_sens, /* SIOCGIWSENS */
1215 NULL, /* SIOCSIWRANGE */
1216 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1217 NULL, /* SIOCSIWPRIV */
1218 NULL, /* SIOCGIWPRIV */
1219 NULL, /* SIOCSIWSTATS */
1220 NULL, /* SIOCGIWSTATS */
1221 dummy, /* SIOCSIWSPY */
1222 dummy, /* SIOCGIWSPY */
1223 NULL, /* SIOCGIWTHRSPY */
1224 NULL, /* SIOCWIWTHRSPY */
1225 r8192_wx_set_wap, /* SIOCSIWAP */
1226 r8192_wx_get_wap, /* SIOCGIWAP */
1227 #if (WIRELESS_EXT >= 18)
1228 r8192_wx_set_mlme, /* MLME-- */
1232 dummy, /* SIOCGIWAPLIST -- depricated */
1233 r8192_wx_set_scan, /* SIOCSIWSCAN */
1234 r8192_wx_get_scan, /* SIOCGIWSCAN */
1235 r8192_wx_set_essid, /* SIOCSIWESSID */
1236 r8192_wx_get_essid, /* SIOCGIWESSID */
1237 dummy, /* SIOCSIWNICKN */
1238 dummy, /* SIOCGIWNICKN */
1239 NULL, /* -- hole -- */
1240 NULL, /* -- hole -- */
1241 r8192_wx_set_rate, /* SIOCSIWRATE */
1242 r8192_wx_get_rate, /* SIOCGIWRATE */
1243 r8192_wx_set_rts, /* SIOCSIWRTS */
1244 r8192_wx_get_rts, /* SIOCGIWRTS */
1245 r8192_wx_set_frag, /* SIOCSIWFRAG */
1246 r8192_wx_get_frag, /* SIOCGIWFRAG */
1247 dummy, /* SIOCSIWTXPOW */
1248 dummy, /* SIOCGIWTXPOW */
1249 r8192_wx_set_retry, /* SIOCSIWRETRY */
1250 r8192_wx_get_retry, /* SIOCGIWRETRY */
1251 r8192_wx_set_enc, /* SIOCSIWENCODE */
1252 r8192_wx_get_enc, /* SIOCGIWENCODE */
1253 r8192_wx_set_power, /* SIOCSIWPOWER */
1254 r8192_wx_get_power, /* SIOCGIWPOWER */
1255 NULL, /*---hole---*/
1256 NULL, /*---hole---*/
1257 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1258 NULL, /* SIOCSIWGENIE */
1259 #if (WIRELESS_EXT >= 18)
1260 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1261 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1262 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1268 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1269 NULL, /* SIOCSIWPMKSA */
1270 NULL, /*---hole---*/
1275 static const struct iw_priv_args r8192_private_args[] = {
1278 SIOCIWFIRSTPRIV + 0x0,
1279 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1283 SIOCIWFIRSTPRIV + 0x1,
1284 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1288 SIOCIWFIRSTPRIV + 0x2,
1289 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1294 SIOCIWFIRSTPRIV + 0x3,
1295 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1299 SIOCIWFIRSTPRIV + 0x4,
1300 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1304 SIOCIWFIRSTPRIV + 0x5,
1305 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1309 SIOCIWFIRSTPRIV + 0x6,
1310 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1314 SIOCIWFIRSTPRIV + 0x7,
1315 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1319 SIOCIWFIRSTPRIV + 0x8,
1320 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1324 SIOCIWFIRSTPRIV + 0x9,
1325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1331 SIOCIWFIRSTPRIV + 0x3,
1332 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1339 static iw_handler r8192_private_handler[] = {
1340 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1341 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1342 // r8192_wx_set_forceassociate,
1343 // r8192_wx_set_beaconinterval,
1344 // r8192_wx_set_monitor_type,
1345 r8192_wx_set_scan_type,
1349 r8192_wx_write_regs,
1353 r8192_wx_write_nicb,
1354 r8192_wx_get_ap_status
1356 r8192_wx_force_reset,
1359 //#if WIRELESS_EXT >= 17
1360 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1362 struct r8192_priv *priv = ieee80211_priv(dev);
1363 struct ieee80211_device* ieee = priv->ieee80211;
1364 struct iw_statistics* wstats = &priv->wstats;
1368 if(ieee->state < IEEE80211_LINKED)
1370 wstats->qual.qual = 0;
1371 wstats->qual.level = 0;
1372 wstats->qual.noise = 0;
1373 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1374 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1376 wstats->qual.updated = 0x0f;
1381 tmp_level = (&ieee->current_network)->stats.rssi;
1382 tmp_qual = (&ieee->current_network)->stats.signal;
1383 tmp_noise = (&ieee->current_network)->stats.noise;
1384 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1386 wstats->qual.level = tmp_level;
1387 wstats->qual.qual = tmp_qual;
1388 wstats->qual.noise = tmp_noise;
1389 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1390 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1392 wstats->qual.updated = 0x0f;
1399 struct iw_handler_def r8192_wx_handlers_def={
1400 .standard = r8192_wx_handlers,
1401 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1402 .private = r8192_private_handler,
1403 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1404 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1405 #if WIRELESS_EXT >= 17
1406 .get_wireless_stats = r8192_get_wireless_stats,
1408 .private_args = (struct iw_priv_args *)r8192_private_args,