1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 * Linux device driver for RTL8192U
5 * This program is distributed in the hope that it will be useful, but WITHOUT
6 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
10 * You should have received a copy of the GNU General Public License along with
11 * this program; if not, write to the Free Software Foundation, Inc.,
12 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 ******************************************************************************/
22 #include <linux/string.h>
24 #include "r8192S_hw.h"
26 #include "ieee80211/dot11d.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);
46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47 union iwreq_data *wrqu, char *b)
49 struct r8192_priv *priv=ieee80211_priv(dev);
51 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
56 static int r8192_wx_get_rate(struct net_device *dev,
57 struct iw_request_info *info,
58 union iwreq_data *wrqu, char *extra)
60 struct r8192_priv *priv = ieee80211_priv(dev);
61 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
66 static int r8192_wx_set_rate(struct net_device *dev,
67 struct iw_request_info *info,
68 union iwreq_data *wrqu, char *extra)
71 struct r8192_priv *priv = ieee80211_priv(dev);
75 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
83 static int r8192_wx_set_rts(struct net_device *dev,
84 struct iw_request_info *info,
85 union iwreq_data *wrqu, char *extra)
88 struct r8192_priv *priv = ieee80211_priv(dev);
92 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
99 static int r8192_wx_get_rts(struct net_device *dev,
100 struct iw_request_info *info,
101 union iwreq_data *wrqu, char *extra)
103 struct r8192_priv *priv = ieee80211_priv(dev);
104 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
107 static int r8192_wx_set_power(struct net_device *dev,
108 struct iw_request_info *info,
109 union iwreq_data *wrqu, char *extra)
112 struct r8192_priv *priv = ieee80211_priv(dev);
116 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
123 static int r8192_wx_get_power(struct net_device *dev,
124 struct iw_request_info *info,
125 union iwreq_data *wrqu, char *extra)
127 struct r8192_priv *priv = ieee80211_priv(dev);
128 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
132 u16 read_rtl8225(struct net_device *dev, u8 addr);
133 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
134 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
135 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
137 static int r8192_wx_read_regs(struct net_device *dev,
138 struct iw_request_info *info,
139 union iwreq_data *wrqu, char *extra)
141 struct r8192_priv *priv = ieee80211_priv(dev);
148 get_user(addr,(u8*)wrqu->data.pointer);
149 data1 = read_rtl8225(dev, addr);
150 wrqu->data.length = data1;
157 static int r8192_wx_write_regs(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);
166 get_user(addr, (u8*)wrqu->data.pointer);
167 write_rtl8225(dev, addr, wrqu->data.length);
174 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
175 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
177 static int r8192_wx_read_bb(struct net_device *dev,
178 struct iw_request_info *info,
179 union iwreq_data *wrqu, char *extra)
181 struct r8192_priv *priv = ieee80211_priv(dev);
186 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
187 wrqu->data.length = databb;
193 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
194 static int r8192_wx_write_bb(struct net_device *dev,
195 struct iw_request_info *info,
196 union iwreq_data *wrqu, char *extra)
198 struct r8192_priv *priv = ieee80211_priv(dev);
203 get_user(databb, (u8*)wrqu->data.pointer);
204 rtl8187_write_phy(dev, wrqu->data.length, databb);
212 static int r8192_wx_write_nicb(struct net_device *dev,
213 struct iw_request_info *info,
214 union iwreq_data *wrqu, char *extra)
216 struct r8192_priv *priv = ieee80211_priv(dev);
221 get_user(addr, (u32*)wrqu->data.pointer);
222 write_nic_byte(dev, addr, wrqu->data.length);
228 static int r8192_wx_read_nicb(struct net_device *dev,
229 struct iw_request_info *info,
230 union iwreq_data *wrqu, char *extra)
232 struct r8192_priv *priv = ieee80211_priv(dev);
238 get_user(addr,(u32*)wrqu->data.pointer);
239 data1 = read_nic_byte(dev, addr);
240 wrqu->data.length = data1;
246 static int r8192_wx_get_ap_status(struct net_device *dev,
247 struct iw_request_info *info,
248 union iwreq_data *wrqu, char *extra)
250 struct r8192_priv *priv = ieee80211_priv(dev);
251 struct ieee80211_device *ieee = priv->ieee80211;
252 struct ieee80211_network *target;
253 struct ieee80211_network *latest = NULL;
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 ((latest == NULL) ||(target->last_scanned > latest->last_scanned))
273 wrqu->data.length = latest->SignalStrength;
275 if(latest->wpa_ie_len>0 || latest->rsn_ie_len>0 ) {
276 wrqu->data.flags = 1;
278 wrqu->data.flags = 0;
289 static int r8192_wx_force_reset(struct net_device *dev,
290 struct iw_request_info *info,
291 union iwreq_data *wrqu, char *extra)
293 struct r8192_priv *priv = ieee80211_priv(dev);
297 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
298 priv->force_reset = *extra;
304 static int r8191su_wx_get_firm_version(struct net_device *dev,
305 struct iw_request_info *info,
306 struct iw_param *wrqu, char *extra)
308 struct r8192_priv *priv = ieee80211_priv(dev);
309 u16 firmware_version;
312 firmware_version = priv->pFirmware->FirmwareVersion;
313 wrqu->value = firmware_version;
322 static int r8192_wx_set_rawtx(struct net_device *dev,
323 struct iw_request_info *info,
324 union iwreq_data *wrqu, char *extra)
326 struct r8192_priv *priv = ieee80211_priv(dev);
331 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
339 static int r8192_wx_set_crcmon(struct net_device *dev,
340 struct iw_request_info *info,
341 union iwreq_data *wrqu, char *extra)
343 struct r8192_priv *priv = ieee80211_priv(dev);
344 int *parms = (int *)extra;
345 int enable = (parms[0] > 0);
346 short prev = priv->crcmon;
355 DMESG("bad CRC in monitor mode are %s",
356 priv->crcmon ? "accepted" : "rejected");
358 if(prev != priv->crcmon && priv->up){
368 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
369 union iwreq_data *wrqu, char *b)
371 struct r8192_priv *priv = ieee80211_priv(dev);
375 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
377 rtl8192_set_rxconf(dev);
383 struct iw_range_with_scan_capa
385 /* Informative stuff (to choose between different interface) */
386 __u32 throughput; /* To give an idea... */
387 /* In theory this value should be the maximum benchmarked
388 * TCP/IP throughput, because with most of these devices the
389 * bit rate is meaningless (overhead an co) to estimate how
390 * fast the connection will go and pick the fastest one.
391 * I suggest people to play with Netperf or any benchmark...
394 /* NWID (or domain id) */
395 __u32 min_nwid; /* Minimal NWID we are able to set */
396 __u32 max_nwid; /* Maximal NWID we are able to set */
398 /* Old Frequency (backward compat - moved lower ) */
399 __u16 old_num_channels;
400 __u8 old_num_frequency;
402 /* Scan capabilities */
405 static int rtl8180_wx_get_range(struct net_device *dev,
406 struct iw_request_info *info,
407 union iwreq_data *wrqu, char *extra)
409 struct iw_range *range = (struct iw_range *)extra;
410 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
411 struct r8192_priv *priv = ieee80211_priv(dev);
415 wrqu->data.length = sizeof(*range);
416 memset(range, 0, sizeof(*range));
418 /* Let's try to keep this struct in the same order as in
419 * linux/include/wireless.h
422 /* TODO: See what values we can set, and remove the ones we can't
423 * set, or fill them with some default data.
426 /* ~5 Mb/s real (802.11b) */
427 range->throughput = 5 * 1000 * 1000;
429 // TODO: Not used in 802.11b?
430 // range->min_nwid; /* Minimal NWID we are able to set */
431 // TODO: Not used in 802.11b?
432 // range->max_nwid; /* Maximal NWID we are able to set */
434 /* Old Frequency (backward compat - moved lower ) */
435 // range->old_num_channels;
436 // range->old_num_frequency;
437 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
438 if(priv->rf_set_sens != NULL)
439 range->sensitivity = priv->max_sens; /* signal level threshold range */
441 range->max_qual.qual = 100;
442 /* TODO: Find real max RSSI and stick here */
443 range->max_qual.level = 0;
444 range->max_qual.noise = -98;
445 range->max_qual.updated = 7; /* Updated all three */
447 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
448 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
449 range->avg_qual.level = 20 + -98;
450 range->avg_qual.noise = 0;
451 range->avg_qual.updated = 7; /* Updated all three */
453 range->num_bitrates = RATE_COUNT;
455 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
456 range->bitrate[i] = rtl8180_rates[i];
459 range->min_frag = MIN_FRAG_THRESHOLD;
460 range->max_frag = MAX_FRAG_THRESHOLD;
463 range->max_pmp = 5000000;
465 range->max_pmt = 65535*1000;
466 range->pmp_flags = IW_POWER_PERIOD;
467 range->pmt_flags = IW_POWER_TIMEOUT;
468 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
470 range->we_version_compiled = WIRELESS_EXT;
471 range->we_version_source = 16;
474 for (i = 0, val = 0; i < 14; i++) {
476 // Include only legal frequencies for some countries
477 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
478 range->freq[val].i = i + 1;
479 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
480 range->freq[val].e = 1;
483 // FIXME: do we need to set anything for channels
487 if (val == IW_MAX_FREQUENCIES)
490 range->num_frequency = val;
491 range->num_channels = val;
492 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
493 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
494 tmp->scan_capa = 0x01;
499 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
500 union iwreq_data *wrqu, char *b)
502 struct r8192_priv *priv = ieee80211_priv(dev);
503 struct ieee80211_device* ieee = priv->ieee80211;
506 if(!priv->up) return -ENETDOWN;
508 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
511 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
513 struct iw_scan_req* req = (struct iw_scan_req*)b;
516 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
517 ieee->current_network.ssid_len = req->essid_len;
518 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
519 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
524 if(priv->ieee80211->state != IEEE80211_LINKED){
525 priv->ieee80211->scanning = 0;
526 ieee80211_softmac_scan_syncro(priv->ieee80211);
530 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
536 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
537 union iwreq_data *wrqu, char *b)
541 struct r8192_priv *priv = ieee80211_priv(dev);
543 if(!priv->up) return -ENETDOWN;
547 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
554 static int r8192_wx_set_essid(struct net_device *dev,
555 struct iw_request_info *a,
556 union iwreq_data *wrqu, char *b)
558 struct r8192_priv *priv = ieee80211_priv(dev);
562 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
572 static int r8192_wx_get_essid(struct net_device *dev,
573 struct iw_request_info *a,
574 union iwreq_data *wrqu, char *b)
577 struct r8192_priv *priv = ieee80211_priv(dev);
581 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
589 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
590 union iwreq_data *wrqu, char *b)
593 struct r8192_priv *priv = ieee80211_priv(dev);
597 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
603 static int r8192_wx_get_name(struct net_device *dev,
604 struct iw_request_info *info,
605 union iwreq_data *wrqu, char *extra)
607 struct r8192_priv *priv = ieee80211_priv(dev);
608 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
612 static int r8192_wx_set_frag(struct net_device *dev,
613 struct iw_request_info *info,
614 union iwreq_data *wrqu, char *extra)
616 struct r8192_priv *priv = ieee80211_priv(dev);
618 if (wrqu->frag.disabled)
619 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
621 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
622 wrqu->frag.value > MAX_FRAG_THRESHOLD)
625 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
632 static int r8192_wx_get_frag(struct net_device *dev,
633 struct iw_request_info *info,
634 union iwreq_data *wrqu, char *extra)
636 struct r8192_priv *priv = ieee80211_priv(dev);
638 wrqu->frag.value = priv->ieee80211->fts;
639 wrqu->frag.fixed = 0; /* no auto select */
640 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
646 static int r8192_wx_set_wap(struct net_device *dev,
647 struct iw_request_info *info,
648 union iwreq_data *awrq,
653 struct r8192_priv *priv = ieee80211_priv(dev);
654 // struct sockaddr *temp = (struct sockaddr *)awrq;
657 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
666 static int r8192_wx_get_wap(struct net_device *dev,
667 struct iw_request_info *info,
668 union iwreq_data *wrqu, char *extra)
670 struct r8192_priv *priv = ieee80211_priv(dev);
672 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
676 static int r8192_wx_get_enc(struct net_device *dev,
677 struct iw_request_info *info,
678 union iwreq_data *wrqu, char *key)
680 struct r8192_priv *priv = ieee80211_priv(dev);
682 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
685 static int r8192_wx_set_enc(struct net_device *dev,
686 struct iw_request_info *info,
687 union iwreq_data *wrqu, char *key)
689 struct r8192_priv *priv = ieee80211_priv(dev);
690 struct ieee80211_device *ieee = priv->ieee80211;
694 u32 hwkey[4]={0,0,0,0};
697 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
698 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
699 {0x00,0x00,0x00,0x00,0x00,0x01},
700 {0x00,0x00,0x00,0x00,0x00,0x02},
701 {0x00,0x00,0x00,0x00,0x00,0x03} };
704 if(!priv->up) return -ENETDOWN;
708 RT_TRACE(COMP_SEC, "Setting SW wep key");
709 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
715 //sometimes, the length is zero while we do not type key value
716 if(wrqu->encoding.length!=0){
718 for(i=0 ; i<4 ; i++){
719 hwkey[i] |= key[4*i+0]&mask;
720 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
721 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
722 hwkey[i] |= (key[4*i+1]&mask)<<8;
723 hwkey[i] |= (key[4*i+2]&mask)<<16;
724 hwkey[i] |= (key[4*i+3]&mask)<<24;
727 #define CONF_WEP40 0x4
728 #define CONF_WEP104 0x14
730 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
731 case 0: key_idx = ieee->tx_keyidx; break;
732 case 1: key_idx = 0; break;
733 case 2: key_idx = 1; break;
734 case 3: key_idx = 2; break;
735 case 4: key_idx = 3; break;
739 if(wrqu->encoding.length==0x5){
740 ieee->pairwise_key_type = KEY_TYPE_WEP40;
741 EnableHWSecurityConfig8192(dev);
746 KEY_TYPE_WEP40, //KeyType
753 else if(wrqu->encoding.length==0xd){
754 ieee->pairwise_key_type = KEY_TYPE_WEP104;
755 EnableHWSecurityConfig8192(dev);
760 KEY_TYPE_WEP104, //KeyType
766 else printk("wrong type in WEP, not WEP40 and WEP104\n");
774 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
775 iwreq_data *wrqu, char *p){
777 struct r8192_priv *priv = ieee80211_priv(dev);
781 priv->ieee80211->active_scan = mode;
788 static int r8192_wx_set_retry(struct net_device *dev,
789 struct iw_request_info *info,
790 union iwreq_data *wrqu, char *extra)
792 struct r8192_priv *priv = ieee80211_priv(dev);
797 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
798 wrqu->retry.disabled){
802 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
807 if(wrqu->retry.value > R8180_MAX_RETRY){
811 if (wrqu->retry.flags & IW_RETRY_MAX) {
812 priv->retry_rts = wrqu->retry.value;
813 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
816 priv->retry_data = wrqu->retry.value;
817 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
821 * We might try to write directly the TX config register
822 * or to restart just the (R)TX process.
823 * I'm unsure if whole reset is really needed
829 rtl8180_rtx_disable(dev);
830 rtl8180_rx_enable(dev);
831 rtl8180_tx_enable(dev);
841 static int r8192_wx_get_retry(struct net_device *dev,
842 struct iw_request_info *info,
843 union iwreq_data *wrqu, char *extra)
845 struct r8192_priv *priv = ieee80211_priv(dev);
848 wrqu->retry.disabled = 0; /* can't be disabled */
850 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
854 if (wrqu->retry.flags & IW_RETRY_MAX) {
855 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
856 wrqu->retry.value = priv->retry_rts;
858 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
859 wrqu->retry.value = priv->retry_data;
861 //printk("returning %d",wrqu->retry.value);
867 static int r8192_wx_get_sens(struct net_device *dev,
868 struct iw_request_info *info,
869 union iwreq_data *wrqu, char *extra)
871 struct r8192_priv *priv = ieee80211_priv(dev);
872 if(priv->rf_set_sens == NULL)
873 return -1; /* we have not this support for this radio */
874 wrqu->sens.value = priv->sens;
879 static int r8192_wx_set_sens(struct net_device *dev,
880 struct iw_request_info *info,
881 union iwreq_data *wrqu, char *extra)
884 struct r8192_priv *priv = ieee80211_priv(dev);
888 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
889 if(priv->rf_set_sens == NULL) {
890 err= -1; /* we have not this support for this radio */
893 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
894 priv->sens = wrqu->sens.value;
904 //hw security need to reorganized.
905 static int r8192_wx_set_enc_ext(struct net_device *dev,
906 struct iw_request_info *info,
907 union iwreq_data *wrqu, char *extra)
910 struct r8192_priv *priv = ieee80211_priv(dev);
911 struct ieee80211_device* ieee = priv->ieee80211;
912 //printk("===>%s()\n", __FUNCTION__);
916 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
919 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
922 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
923 struct iw_point *encoding = &wrqu->encoding;
924 u8 idx = 0, alg = 0, group = 0;
925 if ((encoding->flags & IW_ENCODE_DISABLED) ||
926 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
928 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
929 CamResetAllEntry(dev);
932 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;
933 idx = encoding->flags & IW_ENCODE_INDEX;
936 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
938 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
940 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
941 alg = KEY_TYPE_WEP104;
942 ieee->pairwise_key_type = alg;
943 EnableHWSecurityConfig8192(dev);
945 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
947 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
960 ieee->group_key_type = alg;
965 broadcast_addr, //MacAddr
975 (u8*)ieee->ap_mac_addr, //MacAddr
988 static int r8192_wx_set_auth(struct net_device *dev,
989 struct iw_request_info *info,
990 union iwreq_data *data, char *extra)
994 //printk("====>%s()\n", __FUNCTION__);
995 struct r8192_priv *priv = ieee80211_priv(dev);
997 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1002 static int r8192_wx_set_mlme(struct net_device *dev,
1003 struct iw_request_info *info,
1004 union iwreq_data *wrqu, char *extra)
1006 //printk("====>%s()\n", __FUNCTION__);
1009 struct r8192_priv *priv = ieee80211_priv(dev);
1010 down(&priv->wx_sem);
1011 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1016 static int r8192_wx_set_pmkid(struct net_device *dev,
1017 struct iw_request_info *info,
1018 union iwreq_data *wrqu, char *extra)
1021 struct r8192_priv *priv = ieee80211_priv(dev);
1022 struct ieee80211_device* ieee = priv->ieee80211;
1023 struct iw_pmksa* pPMK = (struct iw_pmksa*)extra;
1024 int intReturn = false;
1029 for (i = 0; i < NUM_PMKID_CACHE; i++)
1031 if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == 0)
1033 memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1034 memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
1035 ieee->PMKIDList[i].bUsed = true;
1041 for (i = 0; i < NUM_PMKID_CACHE; i++)
1043 if (ieee->PMKIDList[i].bUsed == false)
1045 memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1046 memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
1047 ieee->PMKIDList[i].bUsed = true;
1054 case IW_PMKSA_REMOVE:
1055 for (i = 0; i < NUM_PMKID_CACHE; i++)
1057 if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == true)
1059 memset(&ieee->PMKIDList[i], 0x00, sizeof(RT_PMKID_LIST));
1066 case IW_PMKSA_FLUSH:
1067 memset(&ieee->PMKIDList[0], 0x00, (sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE));
1080 static int r8192_wx_set_gen_ie(struct net_device *dev,
1081 struct iw_request_info *info,
1082 union iwreq_data *data, char *extra)
1084 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1086 struct r8192_priv *priv = ieee80211_priv(dev);
1087 down(&priv->wx_sem);
1089 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1092 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1098 static int dummy(struct net_device *dev, struct iw_request_info *a,
1099 union iwreq_data *wrqu,char *b)
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 r8192_wx_set_mlme, /* MLME-- */
1130 dummy, /* SIOCGIWAPLIST -- depricated */
1131 r8192_wx_set_scan, /* SIOCSIWSCAN */
1132 r8192_wx_get_scan, /* SIOCGIWSCAN */
1133 r8192_wx_set_essid, /* SIOCSIWESSID */
1134 r8192_wx_get_essid, /* SIOCGIWESSID */
1135 dummy, /* SIOCSIWNICKN */
1136 dummy, /* SIOCGIWNICKN */
1137 NULL, /* -- hole -- */
1138 NULL, /* -- hole -- */
1139 r8192_wx_set_rate, /* SIOCSIWRATE */
1140 r8192_wx_get_rate, /* SIOCGIWRATE */
1141 r8192_wx_set_rts, /* SIOCSIWRTS */
1142 r8192_wx_get_rts, /* SIOCGIWRTS */
1143 r8192_wx_set_frag, /* SIOCSIWFRAG */
1144 r8192_wx_get_frag, /* SIOCGIWFRAG */
1145 dummy, /* SIOCSIWTXPOW */
1146 dummy, /* SIOCGIWTXPOW */
1147 r8192_wx_set_retry, /* SIOCSIWRETRY */
1148 r8192_wx_get_retry, /* SIOCGIWRETRY */
1149 r8192_wx_set_enc, /* SIOCSIWENCODE */
1150 r8192_wx_get_enc, /* SIOCGIWENCODE */
1151 r8192_wx_set_power, /* SIOCSIWPOWER */
1152 r8192_wx_get_power, /* SIOCGIWPOWER */
1153 NULL, /*---hole---*/
1154 NULL, /*---hole---*/
1155 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1156 NULL, /* SIOCSIWGENIE */
1158 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1159 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1160 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1161 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1162 r8192_wx_set_pmkid, /* SIOCSIWPMKSA */
1163 NULL, /*---hole---*/
1168 static const struct iw_priv_args r8192_private_args[] = {
1171 SIOCIWFIRSTPRIV + 0x0,
1172 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1176 SIOCIWFIRSTPRIV + 0x1,
1177 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1181 SIOCIWFIRSTPRIV + 0x2,
1182 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1187 SIOCIWFIRSTPRIV + 0x3,
1188 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1192 SIOCIWFIRSTPRIV + 0x4,
1193 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1197 SIOCIWFIRSTPRIV + 0x5,
1198 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1202 SIOCIWFIRSTPRIV + 0x6,
1203 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1207 SIOCIWFIRSTPRIV + 0x7,
1208 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1212 SIOCIWFIRSTPRIV + 0x8,
1213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1217 SIOCIWFIRSTPRIV + 0x9,
1218 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1224 SIOCIWFIRSTPRIV + 0x3,
1225 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1230 SIOCIWFIRSTPRIV + 0x5,
1231 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
1237 static iw_handler r8192_private_handler[] = {
1238 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1239 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1240 // r8192_wx_set_forceassociate,
1241 // r8192_wx_set_beaconinterval,
1242 // r8192_wx_set_monitor_type,
1243 r8192_wx_set_scan_type,
1247 r8192_wx_write_regs,
1251 r8192_wx_write_nicb,
1252 r8192_wx_get_ap_status,
1254 r8192_wx_force_reset,
1256 (iw_handler)r8191su_wx_get_firm_version,
1259 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1261 struct r8192_priv *priv = ieee80211_priv(dev);
1262 struct ieee80211_device* ieee = priv->ieee80211;
1263 struct iw_statistics* wstats = &priv->wstats;
1267 if(ieee->state < IEEE80211_LINKED)
1269 wstats->qual.qual = 0;
1270 wstats->qual.level = 0;
1271 wstats->qual.noise = 0;
1272 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1276 tmp_level = (&ieee->current_network)->stats.rssi;
1277 tmp_qual = (&ieee->current_network)->stats.signal;
1278 tmp_noise = (&ieee->current_network)->stats.noise;
1279 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1281 wstats->qual.level = tmp_level;
1282 wstats->qual.qual = tmp_qual;
1283 wstats->qual.noise = tmp_noise;
1284 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1288 struct iw_handler_def r8192_wx_handlers_def={
1289 .standard = r8192_wx_handlers,
1290 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1291 .private = r8192_private_handler,
1292 .num_private = ARRAY_SIZE(r8192_private_handler),
1293 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1294 .get_wireless_stats = r8192_get_wireless_stats,
1295 .private_args = (struct iw_priv_args *)r8192_private_args,