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 "r8192U_hw.h"
29 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
30 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
37 static int r8192_wx_get_freq(struct net_device *dev,
38 struct iw_request_info *a,
39 union iwreq_data *wrqu, char *b)
41 struct r8192_priv *priv = ieee80211_priv(dev);
43 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
47 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
48 union iwreq_data *wrqu, char *b)
50 struct r8192_priv *priv=ieee80211_priv(dev);
52 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
57 static int r8192_wx_get_rate(struct net_device *dev,
58 struct iw_request_info *info,
59 union iwreq_data *wrqu, char *extra)
61 struct r8192_priv *priv = ieee80211_priv(dev);
62 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
67 static int r8192_wx_set_rate(struct net_device *dev,
68 struct iw_request_info *info,
69 union iwreq_data *wrqu, char *extra)
72 struct r8192_priv *priv = ieee80211_priv(dev);
76 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
84 static int r8192_wx_set_rts(struct net_device *dev,
85 struct iw_request_info *info,
86 union iwreq_data *wrqu, char *extra)
89 struct r8192_priv *priv = ieee80211_priv(dev);
93 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
100 static int r8192_wx_get_rts(struct net_device *dev,
101 struct iw_request_info *info,
102 union iwreq_data *wrqu, char *extra)
104 struct r8192_priv *priv = ieee80211_priv(dev);
105 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
108 static int r8192_wx_set_power(struct net_device *dev,
109 struct iw_request_info *info,
110 union iwreq_data *wrqu, char *extra)
113 struct r8192_priv *priv = ieee80211_priv(dev);
117 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
124 static int r8192_wx_get_power(struct net_device *dev,
125 struct iw_request_info *info,
126 union iwreq_data *wrqu, char *extra)
128 struct r8192_priv *priv = ieee80211_priv(dev);
129 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
133 u16 read_rtl8225(struct net_device *dev, u8 addr);
134 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
135 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
136 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
138 static int r8192_wx_read_regs(struct net_device *dev,
139 struct iw_request_info *info,
140 union iwreq_data *wrqu, char *extra)
142 struct r8192_priv *priv = ieee80211_priv(dev);
149 get_user(addr,(u8*)wrqu->data.pointer);
150 data1 = read_rtl8225(dev, addr);
151 wrqu->data.length = data1;
158 static int r8192_wx_write_regs(struct net_device *dev,
159 struct iw_request_info *info,
160 union iwreq_data *wrqu, char *extra)
162 struct r8192_priv *priv = ieee80211_priv(dev);
167 get_user(addr, (u8*)wrqu->data.pointer);
168 write_rtl8225(dev, addr, wrqu->data.length);
175 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
176 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
178 static int r8192_wx_read_bb(struct net_device *dev,
179 struct iw_request_info *info,
180 union iwreq_data *wrqu, char *extra)
182 struct r8192_priv *priv = ieee80211_priv(dev);
187 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
188 wrqu->data.length = databb;
194 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
195 static int r8192_wx_write_bb(struct net_device *dev,
196 struct iw_request_info *info,
197 union iwreq_data *wrqu, char *extra)
199 struct r8192_priv *priv = ieee80211_priv(dev);
204 get_user(databb, (u8*)wrqu->data.pointer);
205 rtl8187_write_phy(dev, wrqu->data.length, databb);
213 static int r8192_wx_write_nicb(struct net_device *dev,
214 struct iw_request_info *info,
215 union iwreq_data *wrqu, char *extra)
217 struct r8192_priv *priv = ieee80211_priv(dev);
222 get_user(addr, (u32*)wrqu->data.pointer);
223 write_nic_byte(dev, addr, wrqu->data.length);
229 static int r8192_wx_read_nicb(struct net_device *dev,
230 struct iw_request_info *info,
231 union iwreq_data *wrqu, char *extra)
233 struct r8192_priv *priv = ieee80211_priv(dev);
239 get_user(addr,(u32*)wrqu->data.pointer);
240 data1 = read_nic_byte(dev, addr);
241 wrqu->data.length = data1;
247 static int r8192_wx_get_ap_status(struct net_device *dev,
248 struct iw_request_info *info,
249 union iwreq_data *wrqu, char *extra)
251 struct r8192_priv *priv = ieee80211_priv(dev);
252 struct ieee80211_device *ieee = priv->ieee80211;
253 struct ieee80211_network *target;
258 //count the length of input ssid
259 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
261 //search for the correspoding info which is received
262 list_for_each_entry(target, &ieee->network_list, list) {
263 if ( (target->ssid_len == name_len) &&
264 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
265 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
266 //set flags=1 to indicate this ap is WPA
267 wrqu->data.flags = 1;
268 else wrqu->data.flags = 0;
282 static int r8192_wx_force_reset(struct net_device *dev,
283 struct iw_request_info *info,
284 union iwreq_data *wrqu, char *extra)
286 struct r8192_priv *priv = ieee80211_priv(dev);
290 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
291 priv->force_reset = *extra;
298 static int r8192_wx_set_rawtx(struct net_device *dev,
299 struct iw_request_info *info,
300 union iwreq_data *wrqu, char *extra)
302 struct r8192_priv *priv = ieee80211_priv(dev);
307 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
315 static int r8192_wx_set_crcmon(struct net_device *dev,
316 struct iw_request_info *info,
317 union iwreq_data *wrqu, char *extra)
319 struct r8192_priv *priv = ieee80211_priv(dev);
320 int *parms = (int *)extra;
321 int enable = (parms[0] > 0);
322 short prev = priv->crcmon;
331 DMESG("bad CRC in monitor mode are %s",
332 priv->crcmon ? "accepted" : "rejected");
334 if(prev != priv->crcmon && priv->up){
344 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
345 union iwreq_data *wrqu, char *b)
347 struct r8192_priv *priv = ieee80211_priv(dev);
351 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
353 rtl8192_set_rxconf(dev);
359 struct iw_range_with_scan_capa
361 /* Informative stuff (to choose between different interface) */
362 __u32 throughput; /* To give an idea... */
363 /* In theory this value should be the maximum benchmarked
364 * TCP/IP throughput, because with most of these devices the
365 * bit rate is meaningless (overhead an co) to estimate how
366 * fast the connection will go and pick the fastest one.
367 * I suggest people to play with Netperf or any benchmark...
370 /* NWID (or domain id) */
371 __u32 min_nwid; /* Minimal NWID we are able to set */
372 __u32 max_nwid; /* Maximal NWID we are able to set */
374 /* Old Frequency (backward compat - moved lower ) */
375 __u16 old_num_channels;
376 __u8 old_num_frequency;
378 /* Scan capabilities */
381 static int rtl8180_wx_get_range(struct net_device *dev,
382 struct iw_request_info *info,
383 union iwreq_data *wrqu, char *extra)
385 struct iw_range *range = (struct iw_range *)extra;
386 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
387 struct r8192_priv *priv = ieee80211_priv(dev);
391 wrqu->data.length = sizeof(*range);
392 memset(range, 0, sizeof(*range));
394 /* Let's try to keep this struct in the same order as in
395 * linux/include/wireless.h
398 /* TODO: See what values we can set, and remove the ones we can't
399 * set, or fill them with some default data.
402 /* ~5 Mb/s real (802.11b) */
403 range->throughput = 5 * 1000 * 1000;
405 // TODO: Not used in 802.11b?
406 // range->min_nwid; /* Minimal NWID we are able to set */
407 // TODO: Not used in 802.11b?
408 // range->max_nwid; /* Maximal NWID we are able to set */
410 /* Old Frequency (backward compat - moved lower ) */
411 // range->old_num_channels;
412 // range->old_num_frequency;
413 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
414 if(priv->rf_set_sens != NULL)
415 range->sensitivity = priv->max_sens; /* signal level threshold range */
417 range->max_qual.qual = 100;
418 /* TODO: Find real max RSSI and stick here */
419 range->max_qual.level = 0;
420 range->max_qual.noise = -98;
421 range->max_qual.updated = 7; /* Updated all three */
423 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
424 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
425 range->avg_qual.level = 20 + -98;
426 range->avg_qual.noise = 0;
427 range->avg_qual.updated = 7; /* Updated all three */
429 range->num_bitrates = RATE_COUNT;
431 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
432 range->bitrate[i] = rtl8180_rates[i];
435 range->min_frag = MIN_FRAG_THRESHOLD;
436 range->max_frag = MAX_FRAG_THRESHOLD;
439 range->max_pmp = 5000000;
441 range->max_pmt = 65535*1000;
442 range->pmp_flags = IW_POWER_PERIOD;
443 range->pmt_flags = IW_POWER_TIMEOUT;
444 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
446 range->we_version_compiled = WIRELESS_EXT;
447 range->we_version_source = 16;
449 // range->retry_capa; /* What retry options are supported */
450 // range->retry_flags; /* How to decode max/min retry limit */
451 // range->r_time_flags; /* How to decode max/min retry life */
452 // range->min_retry; /* Minimal number of retries */
453 // range->max_retry; /* Maximal number of retries */
454 // range->min_r_time; /* Minimal retry lifetime */
455 // range->max_r_time; /* Maximal retry lifetime */
458 for (i = 0, val = 0; i < 14; i++) {
460 // Include only legal frequencies for some countries
462 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
464 if ((priv->ieee80211->channel_map)[i+1]) {
466 range->freq[val].i = i + 1;
467 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
468 range->freq[val].e = 1;
471 // FIXME: do we need to set anything for channels
475 if (val == IW_MAX_FREQUENCIES)
478 range->num_frequency = val;
479 range->num_channels = val;
480 #if WIRELESS_EXT > 17
481 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
482 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
484 tmp->scan_capa = 0x01;
489 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
490 union iwreq_data *wrqu, char *b)
492 struct r8192_priv *priv = ieee80211_priv(dev);
493 struct ieee80211_device* ieee = priv->ieee80211;
496 if(!priv->up) return -ENETDOWN;
498 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
500 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
502 struct iw_scan_req* req = (struct iw_scan_req*)b;
505 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
506 ieee->current_network.ssid_len = req->essid_len;
507 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
508 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
513 if(priv->ieee80211->state != IEEE80211_LINKED){
514 priv->ieee80211->scanning = 0;
515 ieee80211_softmac_scan_syncro(priv->ieee80211);
519 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
525 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
526 union iwreq_data *wrqu, char *b)
530 struct r8192_priv *priv = ieee80211_priv(dev);
532 if(!priv->up) return -ENETDOWN;
536 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
543 static int r8192_wx_set_essid(struct net_device *dev,
544 struct iw_request_info *a,
545 union iwreq_data *wrqu, char *b)
547 struct r8192_priv *priv = ieee80211_priv(dev);
551 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
561 static int r8192_wx_get_essid(struct net_device *dev,
562 struct iw_request_info *a,
563 union iwreq_data *wrqu, char *b)
566 struct r8192_priv *priv = ieee80211_priv(dev);
570 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
578 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
579 union iwreq_data *wrqu, char *b)
582 struct r8192_priv *priv = ieee80211_priv(dev);
586 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
592 static int r8192_wx_get_name(struct net_device *dev,
593 struct iw_request_info *info,
594 union iwreq_data *wrqu, char *extra)
596 struct r8192_priv *priv = ieee80211_priv(dev);
597 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
601 static int r8192_wx_set_frag(struct net_device *dev,
602 struct iw_request_info *info,
603 union iwreq_data *wrqu, char *extra)
605 struct r8192_priv *priv = ieee80211_priv(dev);
607 if (wrqu->frag.disabled)
608 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
610 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
611 wrqu->frag.value > MAX_FRAG_THRESHOLD)
614 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
621 static int r8192_wx_get_frag(struct net_device *dev,
622 struct iw_request_info *info,
623 union iwreq_data *wrqu, char *extra)
625 struct r8192_priv *priv = ieee80211_priv(dev);
627 wrqu->frag.value = priv->ieee80211->fts;
628 wrqu->frag.fixed = 0; /* no auto select */
629 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
635 static int r8192_wx_set_wap(struct net_device *dev,
636 struct iw_request_info *info,
637 union iwreq_data *awrq,
642 struct r8192_priv *priv = ieee80211_priv(dev);
643 // struct sockaddr *temp = (struct sockaddr *)awrq;
646 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
655 static int r8192_wx_get_wap(struct net_device *dev,
656 struct iw_request_info *info,
657 union iwreq_data *wrqu, char *extra)
659 struct r8192_priv *priv = ieee80211_priv(dev);
661 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
665 static int r8192_wx_get_enc(struct net_device *dev,
666 struct iw_request_info *info,
667 union iwreq_data *wrqu, char *key)
669 struct r8192_priv *priv = ieee80211_priv(dev);
671 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
674 static int r8192_wx_set_enc(struct net_device *dev,
675 struct iw_request_info *info,
676 union iwreq_data *wrqu, char *key)
678 struct r8192_priv *priv = ieee80211_priv(dev);
679 struct ieee80211_device *ieee = priv->ieee80211;
683 u32 hwkey[4]={0,0,0,0};
686 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
687 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
688 {0x00,0x00,0x00,0x00,0x00,0x01},
689 {0x00,0x00,0x00,0x00,0x00,0x02},
690 {0x00,0x00,0x00,0x00,0x00,0x03} };
693 if(!priv->up) return -ENETDOWN;
697 RT_TRACE(COMP_SEC, "Setting SW wep key");
698 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
704 //sometimes, the length is zero while we do not type key value
705 if(wrqu->encoding.length!=0){
707 for(i=0 ; i<4 ; i++){
708 hwkey[i] |= key[4*i+0]&mask;
709 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
710 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
711 hwkey[i] |= (key[4*i+1]&mask)<<8;
712 hwkey[i] |= (key[4*i+2]&mask)<<16;
713 hwkey[i] |= (key[4*i+3]&mask)<<24;
716 #define CONF_WEP40 0x4
717 #define CONF_WEP104 0x14
719 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
720 case 0: key_idx = ieee->tx_keyidx; break;
721 case 1: key_idx = 0; break;
722 case 2: key_idx = 1; break;
723 case 3: key_idx = 2; break;
724 case 4: key_idx = 3; break;
728 if(wrqu->encoding.length==0x5){
729 ieee->pairwise_key_type = KEY_TYPE_WEP40;
730 EnableHWSecurityConfig8192(dev);
735 KEY_TYPE_WEP40, //KeyType
742 else if(wrqu->encoding.length==0xd){
743 ieee->pairwise_key_type = KEY_TYPE_WEP104;
744 EnableHWSecurityConfig8192(dev);
749 KEY_TYPE_WEP104, //KeyType
755 else printk("wrong type in WEP, not WEP40 and WEP104\n");
763 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
764 iwreq_data *wrqu, char *p){
766 struct r8192_priv *priv = ieee80211_priv(dev);
770 priv->ieee80211->active_scan = mode;
777 static int r8192_wx_set_retry(struct net_device *dev,
778 struct iw_request_info *info,
779 union iwreq_data *wrqu, char *extra)
781 struct r8192_priv *priv = ieee80211_priv(dev);
786 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
787 wrqu->retry.disabled){
791 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
796 if(wrqu->retry.value > R8180_MAX_RETRY){
800 if (wrqu->retry.flags & IW_RETRY_MAX) {
801 priv->retry_rts = wrqu->retry.value;
802 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
805 priv->retry_data = wrqu->retry.value;
806 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
810 * We might try to write directly the TX config register
811 * or to restart just the (R)TX process.
812 * I'm unsure if whole reset is really needed
818 rtl8180_rtx_disable(dev);
819 rtl8180_rx_enable(dev);
820 rtl8180_tx_enable(dev);
830 static int r8192_wx_get_retry(struct net_device *dev,
831 struct iw_request_info *info,
832 union iwreq_data *wrqu, char *extra)
834 struct r8192_priv *priv = ieee80211_priv(dev);
837 wrqu->retry.disabled = 0; /* can't be disabled */
839 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
843 if (wrqu->retry.flags & IW_RETRY_MAX) {
844 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
845 wrqu->retry.value = priv->retry_rts;
847 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
848 wrqu->retry.value = priv->retry_data;
850 //printk("returning %d",wrqu->retry.value);
856 static int r8192_wx_get_sens(struct net_device *dev,
857 struct iw_request_info *info,
858 union iwreq_data *wrqu, char *extra)
860 struct r8192_priv *priv = ieee80211_priv(dev);
861 if(priv->rf_set_sens == NULL)
862 return -1; /* we have not this support for this radio */
863 wrqu->sens.value = priv->sens;
868 static int r8192_wx_set_sens(struct net_device *dev,
869 struct iw_request_info *info,
870 union iwreq_data *wrqu, char *extra)
873 struct r8192_priv *priv = ieee80211_priv(dev);
877 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
878 if(priv->rf_set_sens == NULL) {
879 err= -1; /* we have not this support for this radio */
882 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
883 priv->sens = wrqu->sens.value;
893 #if (WIRELESS_EXT >= 18)
894 //hw security need to reorganized.
895 static int r8192_wx_set_enc_ext(struct net_device *dev,
896 struct iw_request_info *info,
897 union iwreq_data *wrqu, char *extra)
900 struct r8192_priv *priv = ieee80211_priv(dev);
901 struct ieee80211_device* ieee = priv->ieee80211;
902 //printk("===>%s()\n", __FUNCTION__);
906 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
909 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
912 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
913 struct iw_point *encoding = &wrqu->encoding;
914 u8 idx = 0, alg = 0, group = 0;
915 if ((encoding->flags & IW_ENCODE_DISABLED) ||
916 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
919 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;
920 idx = encoding->flags & IW_ENCODE_INDEX;
923 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
925 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
927 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
928 alg = KEY_TYPE_WEP104;
929 ieee->pairwise_key_type = alg;
930 EnableHWSecurityConfig8192(dev);
932 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
934 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
947 ieee->group_key_type = alg;
952 broadcast_addr, //MacAddr
962 (u8*)ieee->ap_mac_addr, //MacAddr
976 static int r8192_wx_set_auth(struct net_device *dev,
977 struct iw_request_info *info,
978 union iwreq_data *data, char *extra)
981 //printk("====>%s()\n", __FUNCTION__);
982 struct r8192_priv *priv = ieee80211_priv(dev);
984 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
989 static int r8192_wx_set_mlme(struct net_device *dev,
990 struct iw_request_info *info,
991 union iwreq_data *wrqu, char *extra)
993 //printk("====>%s()\n", __FUNCTION__);
996 struct r8192_priv *priv = ieee80211_priv(dev);
998 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1004 static int r8192_wx_set_gen_ie(struct net_device *dev,
1005 struct iw_request_info *info,
1006 union iwreq_data *data, char *extra)
1008 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1010 struct r8192_priv *priv = ieee80211_priv(dev);
1011 down(&priv->wx_sem);
1012 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1014 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1020 static int dummy(struct net_device *dev, struct iw_request_info *a,
1021 union iwreq_data *wrqu,char *b)
1027 static iw_handler r8192_wx_handlers[] =
1029 NULL, /* SIOCSIWCOMMIT */
1030 r8192_wx_get_name, /* SIOCGIWNAME */
1031 dummy, /* SIOCSIWNWID */
1032 dummy, /* SIOCGIWNWID */
1033 r8192_wx_set_freq, /* SIOCSIWFREQ */
1034 r8192_wx_get_freq, /* SIOCGIWFREQ */
1035 r8192_wx_set_mode, /* SIOCSIWMODE */
1036 r8192_wx_get_mode, /* SIOCGIWMODE */
1037 r8192_wx_set_sens, /* SIOCSIWSENS */
1038 r8192_wx_get_sens, /* SIOCGIWSENS */
1039 NULL, /* SIOCSIWRANGE */
1040 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1041 NULL, /* SIOCSIWPRIV */
1042 NULL, /* SIOCGIWPRIV */
1043 NULL, /* SIOCSIWSTATS */
1044 NULL, /* SIOCGIWSTATS */
1045 dummy, /* SIOCSIWSPY */
1046 dummy, /* SIOCGIWSPY */
1047 NULL, /* SIOCGIWTHRSPY */
1048 NULL, /* SIOCWIWTHRSPY */
1049 r8192_wx_set_wap, /* SIOCSIWAP */
1050 r8192_wx_get_wap, /* SIOCGIWAP */
1051 #if (WIRELESS_EXT >= 18)
1052 r8192_wx_set_mlme, /* MLME-- */
1056 dummy, /* SIOCGIWAPLIST -- depricated */
1057 r8192_wx_set_scan, /* SIOCSIWSCAN */
1058 r8192_wx_get_scan, /* SIOCGIWSCAN */
1059 r8192_wx_set_essid, /* SIOCSIWESSID */
1060 r8192_wx_get_essid, /* SIOCGIWESSID */
1061 dummy, /* SIOCSIWNICKN */
1062 dummy, /* SIOCGIWNICKN */
1063 NULL, /* -- hole -- */
1064 NULL, /* -- hole -- */
1065 r8192_wx_set_rate, /* SIOCSIWRATE */
1066 r8192_wx_get_rate, /* SIOCGIWRATE */
1067 r8192_wx_set_rts, /* SIOCSIWRTS */
1068 r8192_wx_get_rts, /* SIOCGIWRTS */
1069 r8192_wx_set_frag, /* SIOCSIWFRAG */
1070 r8192_wx_get_frag, /* SIOCGIWFRAG */
1071 dummy, /* SIOCSIWTXPOW */
1072 dummy, /* SIOCGIWTXPOW */
1073 r8192_wx_set_retry, /* SIOCSIWRETRY */
1074 r8192_wx_get_retry, /* SIOCGIWRETRY */
1075 r8192_wx_set_enc, /* SIOCSIWENCODE */
1076 r8192_wx_get_enc, /* SIOCGIWENCODE */
1077 r8192_wx_set_power, /* SIOCSIWPOWER */
1078 r8192_wx_get_power, /* SIOCGIWPOWER */
1079 NULL, /*---hole---*/
1080 NULL, /*---hole---*/
1081 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1082 NULL, /* SIOCSIWGENIE */
1084 #if (WIRELESS_EXT >= 18)
1085 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1086 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1087 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1088 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1095 NULL, /* SIOCSIWPMKSA */
1096 NULL, /*---hole---*/
1101 static const struct iw_priv_args r8192_private_args[] = {
1104 SIOCIWFIRSTPRIV + 0x0,
1105 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1109 SIOCIWFIRSTPRIV + 0x1,
1110 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1114 SIOCIWFIRSTPRIV + 0x2,
1115 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1120 SIOCIWFIRSTPRIV + 0x3,
1121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1125 SIOCIWFIRSTPRIV + 0x4,
1126 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1130 SIOCIWFIRSTPRIV + 0x5,
1131 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1135 SIOCIWFIRSTPRIV + 0x6,
1136 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1140 SIOCIWFIRSTPRIV + 0x7,
1141 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1145 SIOCIWFIRSTPRIV + 0x8,
1146 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1150 SIOCIWFIRSTPRIV + 0x9,
1151 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1157 SIOCIWFIRSTPRIV + 0x3,
1158 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1165 static iw_handler r8192_private_handler[] = {
1166 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1167 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1168 // r8192_wx_set_forceassociate,
1169 // r8192_wx_set_beaconinterval,
1170 // r8192_wx_set_monitor_type,
1171 r8192_wx_set_scan_type,
1175 r8192_wx_write_regs,
1179 r8192_wx_write_nicb,
1180 r8192_wx_get_ap_status,
1183 r8192_wx_force_reset,
1186 //#if WIRELESS_EXT >= 17
1187 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1189 struct r8192_priv *priv = ieee80211_priv(dev);
1190 struct ieee80211_device* ieee = priv->ieee80211;
1191 struct iw_statistics* wstats = &priv->wstats;
1195 if(ieee->state < IEEE80211_LINKED)
1197 wstats->qual.qual = 0;
1198 wstats->qual.level = 0;
1199 wstats->qual.noise = 0;
1200 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1204 tmp_level = (&ieee->current_network)->stats.rssi;
1205 tmp_qual = (&ieee->current_network)->stats.signal;
1206 tmp_noise = (&ieee->current_network)->stats.noise;
1207 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1209 wstats->qual.level = tmp_level;
1210 wstats->qual.qual = tmp_qual;
1211 wstats->qual.noise = tmp_noise;
1212 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1218 struct iw_handler_def r8192_wx_handlers_def={
1219 .standard = r8192_wx_handlers,
1220 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1221 .private = r8192_private_handler,
1222 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1223 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1224 #if WIRELESS_EXT >= 17
1225 .get_wireless_stats = r8192_get_wireless_stats,
1227 .private_args = (struct iw_priv_args *)r8192_private_args,