First Support on Ginger and OMAP TI
[linux-ginger.git] / drivers / staging / rtl8192su / r8192U_wx.c
blob2208c9b1e726d90bb77a71258b2cda2204445ba8
1 /*
2 This file contains wireless extension handlers.
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
8 Parts of this driver are based on the GPL part
9 of the official realtek driver.
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon.
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16 We want to tanks the Authors of those projects and the Ndiswrapper
17 project Authors.
20 #include <linux/string.h>
21 #include "r8192U.h"
22 #include "r8192S_hw.h"
24 #include "ieee80211/dot11d.h"
26 #define RATE_COUNT 12
27 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
28 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31 #ifndef ENETDOWN
32 #define ENETDOWN 1
33 #endif
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);
44 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
45 union iwreq_data *wrqu, char *b)
47 struct r8192_priv *priv=ieee80211_priv(dev);
49 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
54 static int r8192_wx_get_rate(struct net_device *dev,
55 struct iw_request_info *info,
56 union iwreq_data *wrqu, char *extra)
58 struct r8192_priv *priv = ieee80211_priv(dev);
59 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
64 static int r8192_wx_set_rate(struct net_device *dev,
65 struct iw_request_info *info,
66 union iwreq_data *wrqu, char *extra)
68 int ret;
69 struct r8192_priv *priv = ieee80211_priv(dev);
71 down(&priv->wx_sem);
73 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
75 up(&priv->wx_sem);
77 return ret;
81 static int r8192_wx_set_rts(struct net_device *dev,
82 struct iw_request_info *info,
83 union iwreq_data *wrqu, char *extra)
85 int ret;
86 struct r8192_priv *priv = ieee80211_priv(dev);
88 down(&priv->wx_sem);
90 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
92 up(&priv->wx_sem);
94 return ret;
97 static int r8192_wx_get_rts(struct net_device *dev,
98 struct iw_request_info *info,
99 union iwreq_data *wrqu, char *extra)
101 struct r8192_priv *priv = ieee80211_priv(dev);
102 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
105 static int r8192_wx_set_power(struct net_device *dev,
106 struct iw_request_info *info,
107 union iwreq_data *wrqu, char *extra)
109 int ret;
110 struct r8192_priv *priv = ieee80211_priv(dev);
112 down(&priv->wx_sem);
114 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
116 up(&priv->wx_sem);
118 return ret;
121 static int r8192_wx_get_power(struct net_device *dev,
122 struct iw_request_info *info,
123 union iwreq_data *wrqu, char *extra)
125 struct r8192_priv *priv = ieee80211_priv(dev);
126 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
129 #ifdef JOHN_IOCTL
130 u16 read_rtl8225(struct net_device *dev, u8 addr);
131 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
132 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
133 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
135 static int r8192_wx_read_regs(struct net_device *dev,
136 struct iw_request_info *info,
137 union iwreq_data *wrqu, char *extra)
139 struct r8192_priv *priv = ieee80211_priv(dev);
140 u8 addr;
141 u16 data1;
143 down(&priv->wx_sem);
146 get_user(addr,(u8*)wrqu->data.pointer);
147 data1 = read_rtl8225(dev, addr);
148 wrqu->data.length = data1;
150 up(&priv->wx_sem);
151 return 0;
155 static int r8192_wx_write_regs(struct net_device *dev,
156 struct iw_request_info *info,
157 union iwreq_data *wrqu, char *extra)
159 struct r8192_priv *priv = ieee80211_priv(dev);
160 u8 addr;
162 down(&priv->wx_sem);
164 get_user(addr, (u8*)wrqu->data.pointer);
165 write_rtl8225(dev, addr, wrqu->data.length);
167 up(&priv->wx_sem);
168 return 0;
172 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
173 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
175 static int r8192_wx_read_bb(struct net_device *dev,
176 struct iw_request_info *info,
177 union iwreq_data *wrqu, char *extra)
179 struct r8192_priv *priv = ieee80211_priv(dev);
180 u8 databb;
182 down(&priv->wx_sem);
184 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
185 wrqu->data.length = databb;
187 up(&priv->wx_sem);
188 return 0;
191 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
192 static int r8192_wx_write_bb(struct net_device *dev,
193 struct iw_request_info *info,
194 union iwreq_data *wrqu, char *extra)
196 struct r8192_priv *priv = ieee80211_priv(dev);
197 u8 databb;
199 down(&priv->wx_sem);
201 get_user(databb, (u8*)wrqu->data.pointer);
202 rtl8187_write_phy(dev, wrqu->data.length, databb);
204 up(&priv->wx_sem);
205 return 0;
210 static int r8192_wx_write_nicb(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);
215 u32 addr;
217 down(&priv->wx_sem);
219 get_user(addr, (u32*)wrqu->data.pointer);
220 write_nic_byte(dev, addr, wrqu->data.length);
222 up(&priv->wx_sem);
223 return 0;
226 static int r8192_wx_read_nicb(struct net_device *dev,
227 struct iw_request_info *info,
228 union iwreq_data *wrqu, char *extra)
230 struct r8192_priv *priv = ieee80211_priv(dev);
231 u32 addr;
232 u16 data1;
234 down(&priv->wx_sem);
236 get_user(addr,(u32*)wrqu->data.pointer);
237 data1 = read_nic_byte(dev, addr);
238 wrqu->data.length = data1;
240 up(&priv->wx_sem);
241 return 0;
244 static int r8192_wx_get_ap_status(struct net_device *dev,
245 struct iw_request_info *info,
246 union iwreq_data *wrqu, char *extra)
248 struct r8192_priv *priv = ieee80211_priv(dev);
249 struct ieee80211_device *ieee = priv->ieee80211;
250 struct ieee80211_network *target;
251 int name_len;
253 down(&priv->wx_sem);
255 //count the length of input ssid
256 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
258 //search for the correspoding info which is received
259 list_for_each_entry(target, &ieee->network_list, list) {
260 if ( (target->ssid_len == name_len) &&
261 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
262 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
263 //set flags=1 to indicate this ap is WPA
264 wrqu->data.flags = 1;
265 else wrqu->data.flags = 0;
268 break;
272 up(&priv->wx_sem);
273 return 0;
278 #endif
279 static int r8192_wx_force_reset(struct net_device *dev,
280 struct iw_request_info *info,
281 union iwreq_data *wrqu, char *extra)
283 struct r8192_priv *priv = ieee80211_priv(dev);
285 down(&priv->wx_sem);
287 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
288 priv->force_reset = *extra;
289 up(&priv->wx_sem);
290 return 0;
294 static int r8191su_wx_get_firm_version(struct net_device *dev,
295 struct iw_request_info *info,
296 struct iw_param *wrqu, char *extra)
298 struct r8192_priv *priv = ieee80211_priv(dev);
299 u16 firmware_version;
301 down(&priv->wx_sem);
302 firmware_version = priv->pFirmware->FirmwareVersion;
303 wrqu->value = firmware_version;
304 wrqu->fixed = 1;
306 up(&priv->wx_sem);
307 return 0;
312 static int r8192_wx_set_rawtx(struct net_device *dev,
313 struct iw_request_info *info,
314 union iwreq_data *wrqu, char *extra)
316 struct r8192_priv *priv = ieee80211_priv(dev);
317 int ret;
319 down(&priv->wx_sem);
321 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
323 up(&priv->wx_sem);
325 return ret;
329 static int r8192_wx_set_crcmon(struct net_device *dev,
330 struct iw_request_info *info,
331 union iwreq_data *wrqu, char *extra)
333 struct r8192_priv *priv = ieee80211_priv(dev);
334 int *parms = (int *)extra;
335 int enable = (parms[0] > 0);
336 short prev = priv->crcmon;
338 down(&priv->wx_sem);
340 if(enable)
341 priv->crcmon=1;
342 else
343 priv->crcmon=0;
345 DMESG("bad CRC in monitor mode are %s",
346 priv->crcmon ? "accepted" : "rejected");
348 if(prev != priv->crcmon && priv->up){
349 //rtl8180_down(dev);
350 //rtl8180_up(dev);
353 up(&priv->wx_sem);
355 return 0;
358 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
359 union iwreq_data *wrqu, char *b)
361 struct r8192_priv *priv = ieee80211_priv(dev);
362 int ret;
363 down(&priv->wx_sem);
365 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
367 rtl8192_set_rxconf(dev);
369 up(&priv->wx_sem);
370 return ret;
373 struct iw_range_with_scan_capa
375 /* Informative stuff (to choose between different interface) */
376 __u32 throughput; /* To give an idea... */
377 /* In theory this value should be the maximum benchmarked
378 * TCP/IP throughput, because with most of these devices the
379 * bit rate is meaningless (overhead an co) to estimate how
380 * fast the connection will go and pick the fastest one.
381 * I suggest people to play with Netperf or any benchmark...
384 /* NWID (or domain id) */
385 __u32 min_nwid; /* Minimal NWID we are able to set */
386 __u32 max_nwid; /* Maximal NWID we are able to set */
388 /* Old Frequency (backward compat - moved lower ) */
389 __u16 old_num_channels;
390 __u8 old_num_frequency;
392 /* Scan capabilities */
393 __u8 scan_capa;
395 static int rtl8180_wx_get_range(struct net_device *dev,
396 struct iw_request_info *info,
397 union iwreq_data *wrqu, char *extra)
399 struct iw_range *range = (struct iw_range *)extra;
400 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
401 struct r8192_priv *priv = ieee80211_priv(dev);
402 u16 val;
403 int i;
405 wrqu->data.length = sizeof(*range);
406 memset(range, 0, sizeof(*range));
408 /* Let's try to keep this struct in the same order as in
409 * linux/include/wireless.h
412 /* TODO: See what values we can set, and remove the ones we can't
413 * set, or fill them with some default data.
416 /* ~5 Mb/s real (802.11b) */
417 range->throughput = 5 * 1000 * 1000;
419 // TODO: Not used in 802.11b?
420 // range->min_nwid; /* Minimal NWID we are able to set */
421 // TODO: Not used in 802.11b?
422 // range->max_nwid; /* Maximal NWID we are able to set */
424 /* Old Frequency (backward compat - moved lower ) */
425 // range->old_num_channels;
426 // range->old_num_frequency;
427 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
428 if(priv->rf_set_sens != NULL)
429 range->sensitivity = priv->max_sens; /* signal level threshold range */
431 range->max_qual.qual = 100;
432 /* TODO: Find real max RSSI and stick here */
433 range->max_qual.level = 0;
434 range->max_qual.noise = -98;
435 range->max_qual.updated = 7; /* Updated all three */
437 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
438 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
439 range->avg_qual.level = 20 + -98;
440 range->avg_qual.noise = 0;
441 range->avg_qual.updated = 7; /* Updated all three */
443 range->num_bitrates = RATE_COUNT;
445 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
446 range->bitrate[i] = rtl8180_rates[i];
449 range->min_frag = MIN_FRAG_THRESHOLD;
450 range->max_frag = MAX_FRAG_THRESHOLD;
452 range->min_pmp=0;
453 range->max_pmp = 5000000;
454 range->min_pmt = 0;
455 range->max_pmt = 65535*1000;
456 range->pmp_flags = IW_POWER_PERIOD;
457 range->pmt_flags = IW_POWER_TIMEOUT;
458 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
460 range->we_version_compiled = WIRELESS_EXT;
461 range->we_version_source = 16;
463 // range->retry_capa; /* What retry options are supported */
464 // range->retry_flags; /* How to decode max/min retry limit */
465 // range->r_time_flags; /* How to decode max/min retry life */
466 // range->min_retry; /* Minimal number of retries */
467 // range->max_retry; /* Maximal number of retries */
468 // range->min_r_time; /* Minimal retry lifetime */
469 // range->max_r_time; /* Maximal retry lifetime */
472 for (i = 0, val = 0; i < 14; i++) {
474 // Include only legal frequencies for some countries
475 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
476 range->freq[val].i = i + 1;
477 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
478 range->freq[val].e = 1;
479 val++;
480 } else {
481 // FIXME: do we need to set anything for channels
482 // we don't use ?
485 if (val == IW_MAX_FREQUENCIES)
486 break;
488 range->num_frequency = val;
489 range->num_channels = val;
490 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
491 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
492 tmp->scan_capa = 0x01;
493 return 0;
497 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
498 union iwreq_data *wrqu, char *b)
500 struct r8192_priv *priv = ieee80211_priv(dev);
501 struct ieee80211_device* ieee = priv->ieee80211;
502 int ret = 0;
504 if(!priv->up) return -ENETDOWN;
506 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
507 return -EAGAIN;
509 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
511 struct iw_scan_req* req = (struct iw_scan_req*)b;
512 if (req->essid_len)
514 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
515 ieee->current_network.ssid_len = req->essid_len;
516 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
517 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
521 down(&priv->wx_sem);
522 if(priv->ieee80211->state != IEEE80211_LINKED){
523 priv->ieee80211->scanning = 0;
524 ieee80211_softmac_scan_syncro(priv->ieee80211);
525 ret = 0;
527 else
528 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
529 up(&priv->wx_sem);
530 return ret;
534 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
535 union iwreq_data *wrqu, char *b)
538 int ret;
539 struct r8192_priv *priv = ieee80211_priv(dev);
541 if(!priv->up) return -ENETDOWN;
543 down(&priv->wx_sem);
545 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
547 up(&priv->wx_sem);
549 return ret;
552 static int r8192_wx_set_essid(struct net_device *dev,
553 struct iw_request_info *a,
554 union iwreq_data *wrqu, char *b)
556 struct r8192_priv *priv = ieee80211_priv(dev);
557 int ret;
558 down(&priv->wx_sem);
560 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
562 up(&priv->wx_sem);
564 return ret;
570 static int r8192_wx_get_essid(struct net_device *dev,
571 struct iw_request_info *a,
572 union iwreq_data *wrqu, char *b)
574 int ret;
575 struct r8192_priv *priv = ieee80211_priv(dev);
577 down(&priv->wx_sem);
579 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
581 up(&priv->wx_sem);
583 return ret;
587 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
588 union iwreq_data *wrqu, char *b)
590 int ret;
591 struct r8192_priv *priv = ieee80211_priv(dev);
593 down(&priv->wx_sem);
595 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
597 up(&priv->wx_sem);
598 return ret;
601 static int r8192_wx_get_name(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);
606 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
610 static int r8192_wx_set_frag(struct net_device *dev,
611 struct iw_request_info *info,
612 union iwreq_data *wrqu, char *extra)
614 struct r8192_priv *priv = ieee80211_priv(dev);
616 if (wrqu->frag.disabled)
617 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
618 else {
619 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
620 wrqu->frag.value > MAX_FRAG_THRESHOLD)
621 return -EINVAL;
623 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
626 return 0;
630 static int r8192_wx_get_frag(struct net_device *dev,
631 struct iw_request_info *info,
632 union iwreq_data *wrqu, char *extra)
634 struct r8192_priv *priv = ieee80211_priv(dev);
636 wrqu->frag.value = priv->ieee80211->fts;
637 wrqu->frag.fixed = 0; /* no auto select */
638 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
640 return 0;
644 static int r8192_wx_set_wap(struct net_device *dev,
645 struct iw_request_info *info,
646 union iwreq_data *awrq,
647 char *extra)
650 int ret;
651 struct r8192_priv *priv = ieee80211_priv(dev);
652 // struct sockaddr *temp = (struct sockaddr *)awrq;
653 down(&priv->wx_sem);
655 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
657 up(&priv->wx_sem);
659 return ret;
664 static int r8192_wx_get_wap(struct net_device *dev,
665 struct iw_request_info *info,
666 union iwreq_data *wrqu, char *extra)
668 struct r8192_priv *priv = ieee80211_priv(dev);
670 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
674 static int r8192_wx_get_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);
680 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
683 static int r8192_wx_set_enc(struct net_device *dev,
684 struct iw_request_info *info,
685 union iwreq_data *wrqu, char *key)
687 struct r8192_priv *priv = ieee80211_priv(dev);
688 struct ieee80211_device *ieee = priv->ieee80211;
689 int ret;
691 //u32 TargetContent;
692 u32 hwkey[4]={0,0,0,0};
693 u8 mask=0xff;
694 u32 key_idx=0;
695 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
696 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
697 {0x00,0x00,0x00,0x00,0x00,0x01},
698 {0x00,0x00,0x00,0x00,0x00,0x02},
699 {0x00,0x00,0x00,0x00,0x00,0x03} };
700 int i;
702 if(!priv->up) return -ENETDOWN;
704 down(&priv->wx_sem);
706 RT_TRACE(COMP_SEC, "Setting SW wep key");
707 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
709 up(&priv->wx_sem);
713 //sometimes, the length is zero while we do not type key value
714 if(wrqu->encoding.length!=0){
716 for(i=0 ; i<4 ; i++){
717 hwkey[i] |= key[4*i+0]&mask;
718 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
719 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
720 hwkey[i] |= (key[4*i+1]&mask)<<8;
721 hwkey[i] |= (key[4*i+2]&mask)<<16;
722 hwkey[i] |= (key[4*i+3]&mask)<<24;
725 #define CONF_WEP40 0x4
726 #define CONF_WEP104 0x14
728 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
729 case 0: key_idx = ieee->tx_keyidx; break;
730 case 1: key_idx = 0; break;
731 case 2: key_idx = 1; break;
732 case 3: key_idx = 2; break;
733 case 4: key_idx = 3; break;
734 default: break;
737 if(wrqu->encoding.length==0x5){
738 ieee->pairwise_key_type = KEY_TYPE_WEP40;
739 EnableHWSecurityConfig8192(dev);
741 setKey( dev,
742 key_idx, //EntryNo
743 key_idx, //KeyIndex
744 KEY_TYPE_WEP40, //KeyType
745 zero_addr[key_idx],
746 0, //DefaultKey
747 hwkey); //KeyContent
751 else if(wrqu->encoding.length==0xd){
752 ieee->pairwise_key_type = KEY_TYPE_WEP104;
753 EnableHWSecurityConfig8192(dev);
755 setKey( dev,
756 key_idx, //EntryNo
757 key_idx, //KeyIndex
758 KEY_TYPE_WEP104, //KeyType
759 zero_addr[key_idx],
760 0, //DefaultKey
761 hwkey); //KeyContent
764 else printk("wrong type in WEP, not WEP40 and WEP104\n");
768 return ret;
772 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
773 iwreq_data *wrqu, char *p){
775 struct r8192_priv *priv = ieee80211_priv(dev);
776 int *parms=(int*)p;
777 int mode=parms[0];
779 priv->ieee80211->active_scan = mode;
781 return 1;
786 static int r8192_wx_set_retry(struct net_device *dev,
787 struct iw_request_info *info,
788 union iwreq_data *wrqu, char *extra)
790 struct r8192_priv *priv = ieee80211_priv(dev);
791 int err = 0;
793 down(&priv->wx_sem);
795 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
796 wrqu->retry.disabled){
797 err = -EINVAL;
798 goto exit;
800 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
801 err = -EINVAL;
802 goto exit;
805 if(wrqu->retry.value > R8180_MAX_RETRY){
806 err= -EINVAL;
807 goto exit;
809 if (wrqu->retry.flags & IW_RETRY_MAX) {
810 priv->retry_rts = wrqu->retry.value;
811 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
813 }else {
814 priv->retry_data = wrqu->retry.value;
815 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
818 /* FIXME !
819 * We might try to write directly the TX config register
820 * or to restart just the (R)TX process.
821 * I'm unsure if whole reset is really needed
824 rtl8192_commit(dev);
826 if(priv->up){
827 rtl8180_rtx_disable(dev);
828 rtl8180_rx_enable(dev);
829 rtl8180_tx_enable(dev);
833 exit:
834 up(&priv->wx_sem);
836 return err;
839 static int r8192_wx_get_retry(struct net_device *dev,
840 struct iw_request_info *info,
841 union iwreq_data *wrqu, char *extra)
843 struct r8192_priv *priv = ieee80211_priv(dev);
846 wrqu->retry.disabled = 0; /* can't be disabled */
848 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
849 IW_RETRY_LIFETIME)
850 return -EINVAL;
852 if (wrqu->retry.flags & IW_RETRY_MAX) {
853 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
854 wrqu->retry.value = priv->retry_rts;
855 } else {
856 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
857 wrqu->retry.value = priv->retry_data;
859 //printk("returning %d",wrqu->retry.value);
862 return 0;
865 static int r8192_wx_get_sens(struct net_device *dev,
866 struct iw_request_info *info,
867 union iwreq_data *wrqu, char *extra)
869 struct r8192_priv *priv = ieee80211_priv(dev);
870 if(priv->rf_set_sens == NULL)
871 return -1; /* we have not this support for this radio */
872 wrqu->sens.value = priv->sens;
873 return 0;
877 static int r8192_wx_set_sens(struct net_device *dev,
878 struct iw_request_info *info,
879 union iwreq_data *wrqu, char *extra)
882 struct r8192_priv *priv = ieee80211_priv(dev);
884 short err = 0;
885 down(&priv->wx_sem);
886 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
887 if(priv->rf_set_sens == NULL) {
888 err= -1; /* we have not this support for this radio */
889 goto exit;
891 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
892 priv->sens = wrqu->sens.value;
893 else
894 err= -EINVAL;
896 exit:
897 up(&priv->wx_sem);
899 return err;
902 //hw security need to reorganized.
903 static int r8192_wx_set_enc_ext(struct net_device *dev,
904 struct iw_request_info *info,
905 union iwreq_data *wrqu, char *extra)
907 int ret=0;
908 struct r8192_priv *priv = ieee80211_priv(dev);
909 struct ieee80211_device* ieee = priv->ieee80211;
910 //printk("===>%s()\n", __FUNCTION__);
913 down(&priv->wx_sem);
914 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
917 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
918 u8 zero[6] = {0};
919 u32 key[4] = {0};
920 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
921 struct iw_point *encoding = &wrqu->encoding;
922 u8 idx = 0, alg = 0, group = 0;
923 if ((encoding->flags & IW_ENCODE_DISABLED) ||
924 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
926 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
927 CamResetAllEntry(dev);
928 goto end_hw_sec;
930 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;
931 idx = encoding->flags & IW_ENCODE_INDEX;
932 if (idx)
933 idx --;
934 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
936 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
938 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
939 alg = KEY_TYPE_WEP104;
940 ieee->pairwise_key_type = alg;
941 EnableHWSecurityConfig8192(dev);
943 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
945 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
948 setKey( dev,
949 idx,//EntryNo
950 idx, //KeyIndex
951 alg, //KeyType
952 zero, //MacAddr
953 0, //DefaultKey
954 key); //KeyContent
956 else if (group)
958 ieee->group_key_type = alg;
959 setKey( dev,
960 idx,//EntryNo
961 idx, //KeyIndex
962 alg, //KeyType
963 broadcast_addr, //MacAddr
964 0, //DefaultKey
965 key); //KeyContent
967 else //pairwise key
969 setKey( dev,
970 4,//EntryNo
971 idx, //KeyIndex
972 alg, //KeyType
973 (u8*)ieee->ap_mac_addr, //MacAddr
974 0, //DefaultKey
975 key); //KeyContent
981 end_hw_sec:
983 up(&priv->wx_sem);
984 return ret;
986 static int r8192_wx_set_auth(struct net_device *dev,
987 struct iw_request_info *info,
988 union iwreq_data *data, char *extra)
990 int ret=0;
992 //printk("====>%s()\n", __FUNCTION__);
993 struct r8192_priv *priv = ieee80211_priv(dev);
994 down(&priv->wx_sem);
995 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
996 up(&priv->wx_sem);
997 return ret;
1000 static int r8192_wx_set_mlme(struct net_device *dev,
1001 struct iw_request_info *info,
1002 union iwreq_data *wrqu, char *extra)
1004 //printk("====>%s()\n", __FUNCTION__);
1006 int ret=0;
1007 struct r8192_priv *priv = ieee80211_priv(dev);
1008 down(&priv->wx_sem);
1009 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1010 up(&priv->wx_sem);
1011 return ret;
1014 static int r8192_wx_set_gen_ie(struct net_device *dev,
1015 struct iw_request_info *info,
1016 union iwreq_data *data, char *extra)
1018 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1019 int ret=0;
1020 struct r8192_priv *priv = ieee80211_priv(dev);
1021 down(&priv->wx_sem);
1022 #if 1
1023 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1024 #endif
1025 up(&priv->wx_sem);
1026 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1027 return ret;
1032 static int dummy(struct net_device *dev, struct iw_request_info *a,
1033 union iwreq_data *wrqu,char *b)
1035 return -1;
1039 static iw_handler r8192_wx_handlers[] =
1041 NULL, /* SIOCSIWCOMMIT */
1042 r8192_wx_get_name, /* SIOCGIWNAME */
1043 dummy, /* SIOCSIWNWID */
1044 dummy, /* SIOCGIWNWID */
1045 r8192_wx_set_freq, /* SIOCSIWFREQ */
1046 r8192_wx_get_freq, /* SIOCGIWFREQ */
1047 r8192_wx_set_mode, /* SIOCSIWMODE */
1048 r8192_wx_get_mode, /* SIOCGIWMODE */
1049 r8192_wx_set_sens, /* SIOCSIWSENS */
1050 r8192_wx_get_sens, /* SIOCGIWSENS */
1051 NULL, /* SIOCSIWRANGE */
1052 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1053 NULL, /* SIOCSIWPRIV */
1054 NULL, /* SIOCGIWPRIV */
1055 NULL, /* SIOCSIWSTATS */
1056 NULL, /* SIOCGIWSTATS */
1057 dummy, /* SIOCSIWSPY */
1058 dummy, /* SIOCGIWSPY */
1059 NULL, /* SIOCGIWTHRSPY */
1060 NULL, /* SIOCWIWTHRSPY */
1061 r8192_wx_set_wap, /* SIOCSIWAP */
1062 r8192_wx_get_wap, /* SIOCGIWAP */
1063 r8192_wx_set_mlme, /* MLME-- */
1064 dummy, /* SIOCGIWAPLIST -- depricated */
1065 r8192_wx_set_scan, /* SIOCSIWSCAN */
1066 r8192_wx_get_scan, /* SIOCGIWSCAN */
1067 r8192_wx_set_essid, /* SIOCSIWESSID */
1068 r8192_wx_get_essid, /* SIOCGIWESSID */
1069 dummy, /* SIOCSIWNICKN */
1070 dummy, /* SIOCGIWNICKN */
1071 NULL, /* -- hole -- */
1072 NULL, /* -- hole -- */
1073 r8192_wx_set_rate, /* SIOCSIWRATE */
1074 r8192_wx_get_rate, /* SIOCGIWRATE */
1075 r8192_wx_set_rts, /* SIOCSIWRTS */
1076 r8192_wx_get_rts, /* SIOCGIWRTS */
1077 r8192_wx_set_frag, /* SIOCSIWFRAG */
1078 r8192_wx_get_frag, /* SIOCGIWFRAG */
1079 dummy, /* SIOCSIWTXPOW */
1080 dummy, /* SIOCGIWTXPOW */
1081 r8192_wx_set_retry, /* SIOCSIWRETRY */
1082 r8192_wx_get_retry, /* SIOCGIWRETRY */
1083 r8192_wx_set_enc, /* SIOCSIWENCODE */
1084 r8192_wx_get_enc, /* SIOCGIWENCODE */
1085 r8192_wx_set_power, /* SIOCSIWPOWER */
1086 r8192_wx_get_power, /* SIOCGIWPOWER */
1087 NULL, /*---hole---*/
1088 NULL, /*---hole---*/
1089 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1090 NULL, /* SIOCSIWGENIE */
1092 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1093 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1094 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1095 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1096 NULL, /* SIOCSIWPMKSA */
1097 NULL, /*---hole---*/
1102 static const struct iw_priv_args r8192_private_args[] = {
1105 SIOCIWFIRSTPRIV + 0x0,
1106 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1110 SIOCIWFIRSTPRIV + 0x1,
1111 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1115 SIOCIWFIRSTPRIV + 0x2,
1116 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1118 #ifdef JOHN_IOCTL
1121 SIOCIWFIRSTPRIV + 0x3,
1122 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1126 SIOCIWFIRSTPRIV + 0x4,
1127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1131 SIOCIWFIRSTPRIV + 0x5,
1132 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1136 SIOCIWFIRSTPRIV + 0x6,
1137 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1141 SIOCIWFIRSTPRIV + 0x7,
1142 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1146 SIOCIWFIRSTPRIV + 0x8,
1147 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1151 SIOCIWFIRSTPRIV + 0x9,
1152 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1155 #endif
1158 SIOCIWFIRSTPRIV + 0x3,
1159 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1164 SIOCIWFIRSTPRIV + 0x5,
1165 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
1166 "firm_ver"
1171 static iw_handler r8192_private_handler[] = {
1172 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1173 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1174 // r8192_wx_set_forceassociate,
1175 // r8192_wx_set_beaconinterval,
1176 // r8192_wx_set_monitor_type,
1177 r8192_wx_set_scan_type,
1178 r8192_wx_set_rawtx,
1179 #ifdef JOHN_IOCTL
1180 r8192_wx_read_regs,
1181 r8192_wx_write_regs,
1182 r8192_wx_read_bb,
1183 r8192_wx_write_bb,
1184 r8192_wx_read_nicb,
1185 r8192_wx_write_nicb,
1186 r8192_wx_get_ap_status,
1187 #endif
1188 r8192_wx_force_reset,
1189 (iw_handler)NULL,
1190 (iw_handler)r8191su_wx_get_firm_version,
1193 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1195 struct r8192_priv *priv = ieee80211_priv(dev);
1196 struct ieee80211_device* ieee = priv->ieee80211;
1197 struct iw_statistics* wstats = &priv->wstats;
1198 int tmp_level = 0;
1199 int tmp_qual = 0;
1200 int tmp_noise = 0;
1201 if(ieee->state < IEEE80211_LINKED)
1203 wstats->qual.qual = 0;
1204 wstats->qual.level = 0;
1205 wstats->qual.noise = 0;
1206 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1207 return wstats;
1210 tmp_level = (&ieee->current_network)->stats.rssi;
1211 tmp_qual = (&ieee->current_network)->stats.signal;
1212 tmp_noise = (&ieee->current_network)->stats.noise;
1213 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1215 wstats->qual.level = tmp_level;
1216 wstats->qual.qual = tmp_qual;
1217 wstats->qual.noise = tmp_noise;
1218 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1219 return wstats;
1222 struct iw_handler_def r8192_wx_handlers_def={
1223 .standard = r8192_wx_handlers,
1224 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1225 .private = r8192_private_handler,
1226 .num_private = ARRAY_SIZE(r8192_private_handler),
1227 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1228 .get_wireless_stats = r8192_get_wireless_stats,
1229 .private_args = (struct iw_priv_args *)r8192_private_args,