Staging: rtl8192su: remove ENABLE_DOT11D ifdefs
[linux-2.6/linux-2.6-openrd.git] / drivers / staging / rtl8192su / r8192U_wx.c
blob8b566416d80072f04a4e4e8279a6530611332c95
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 #ifdef RTL8192SU
21 #include <linux/string.h>
22 #include "r8192U.h"
23 #include "r8192S_hw.h"
24 #else
25 #include <linux/string.h>
26 #include "r8192U.h"
27 #include "r8192U_hw.h"
28 #endif
30 #include "ieee80211/dot11d.h"
32 #define RATE_COUNT 12
33 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
34 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
37 #ifndef ENETDOWN
38 #define ENETDOWN 1
39 #endif
41 static int r8192_wx_get_freq(struct net_device *dev,
42 struct iw_request_info *a,
43 union iwreq_data *wrqu, char *b)
45 struct r8192_priv *priv = ieee80211_priv(dev);
47 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
51 #if 0
53 static int r8192_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
54 union iwreq_data *wrqu, char *b)
56 int *parms = (int *)b;
57 int bi = parms[0];
59 struct r8192_priv *priv = ieee80211_priv(dev);
61 down(&priv->wx_sem);
62 DMESG("setting beacon interval to %x",bi);
64 priv->ieee80211->beacon_interval=bi;
65 rtl8180_commit(dev);
66 up(&priv->wx_sem);
68 return 0;
72 static int r8192_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
73 union iwreq_data *wrqu, char *extra)
75 struct r8192_priv *priv=ieee80211_priv(dev);
76 int *parms = (int *)extra;
78 priv->ieee80211->force_associate = (parms[0] > 0);
81 return 0;
84 #endif
85 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
86 union iwreq_data *wrqu, char *b)
88 struct r8192_priv *priv=ieee80211_priv(dev);
90 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
95 static int r8192_wx_get_rate(struct net_device *dev,
96 struct iw_request_info *info,
97 union iwreq_data *wrqu, char *extra)
99 struct r8192_priv *priv = ieee80211_priv(dev);
100 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
105 static int r8192_wx_set_rate(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_rate(priv->ieee80211,info,wrqu,extra);
116 up(&priv->wx_sem);
118 return ret;
122 static int r8192_wx_set_rts(struct net_device *dev,
123 struct iw_request_info *info,
124 union iwreq_data *wrqu, char *extra)
126 int ret;
127 struct r8192_priv *priv = ieee80211_priv(dev);
129 down(&priv->wx_sem);
131 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
133 up(&priv->wx_sem);
135 return ret;
138 static int r8192_wx_get_rts(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);
143 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
146 static int r8192_wx_set_power(struct net_device *dev,
147 struct iw_request_info *info,
148 union iwreq_data *wrqu, char *extra)
150 int ret;
151 struct r8192_priv *priv = ieee80211_priv(dev);
153 down(&priv->wx_sem);
155 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
157 up(&priv->wx_sem);
159 return ret;
162 static int r8192_wx_get_power(struct net_device *dev,
163 struct iw_request_info *info,
164 union iwreq_data *wrqu, char *extra)
166 struct r8192_priv *priv = ieee80211_priv(dev);
167 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
170 #ifdef JOHN_IOCTL
171 u16 read_rtl8225(struct net_device *dev, u8 addr);
172 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
173 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
174 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
176 static int r8192_wx_read_regs(struct net_device *dev,
177 struct iw_request_info *info,
178 union iwreq_data *wrqu, char *extra)
180 struct r8192_priv *priv = ieee80211_priv(dev);
181 u8 addr;
182 u16 data1;
184 down(&priv->wx_sem);
187 get_user(addr,(u8*)wrqu->data.pointer);
188 data1 = read_rtl8225(dev, addr);
189 wrqu->data.length = data1;
191 up(&priv->wx_sem);
192 return 0;
196 static int r8192_wx_write_regs(struct net_device *dev,
197 struct iw_request_info *info,
198 union iwreq_data *wrqu, char *extra)
200 struct r8192_priv *priv = ieee80211_priv(dev);
201 u8 addr;
203 down(&priv->wx_sem);
205 get_user(addr, (u8*)wrqu->data.pointer);
206 write_rtl8225(dev, addr, wrqu->data.length);
208 up(&priv->wx_sem);
209 return 0;
213 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
214 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
216 static int r8192_wx_read_bb(struct net_device *dev,
217 struct iw_request_info *info,
218 union iwreq_data *wrqu, char *extra)
220 struct r8192_priv *priv = ieee80211_priv(dev);
221 u8 databb;
222 #if 0
223 int i;
224 for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
225 #endif
227 down(&priv->wx_sem);
229 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
230 wrqu->data.length = databb;
232 up(&priv->wx_sem);
233 return 0;
236 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
237 static int r8192_wx_write_bb(struct net_device *dev,
238 struct iw_request_info *info,
239 union iwreq_data *wrqu, char *extra)
241 struct r8192_priv *priv = ieee80211_priv(dev);
242 u8 databb;
244 down(&priv->wx_sem);
246 get_user(databb, (u8*)wrqu->data.pointer);
247 rtl8187_write_phy(dev, wrqu->data.length, databb);
249 up(&priv->wx_sem);
250 return 0;
255 static int r8192_wx_write_nicb(struct net_device *dev,
256 struct iw_request_info *info,
257 union iwreq_data *wrqu, char *extra)
259 struct r8192_priv *priv = ieee80211_priv(dev);
260 u32 addr;
262 down(&priv->wx_sem);
264 get_user(addr, (u32*)wrqu->data.pointer);
265 write_nic_byte(dev, addr, wrqu->data.length);
267 up(&priv->wx_sem);
268 return 0;
271 static int r8192_wx_read_nicb(struct net_device *dev,
272 struct iw_request_info *info,
273 union iwreq_data *wrqu, char *extra)
275 struct r8192_priv *priv = ieee80211_priv(dev);
276 u32 addr;
277 u16 data1;
279 down(&priv->wx_sem);
281 get_user(addr,(u32*)wrqu->data.pointer);
282 data1 = read_nic_byte(dev, addr);
283 wrqu->data.length = data1;
285 up(&priv->wx_sem);
286 return 0;
289 static int r8192_wx_get_ap_status(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);
294 struct ieee80211_device *ieee = priv->ieee80211;
295 struct ieee80211_network *target;
296 int name_len;
298 down(&priv->wx_sem);
300 //count the length of input ssid
301 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
303 //search for the correspoding info which is received
304 list_for_each_entry(target, &ieee->network_list, list) {
305 if ( (target->ssid_len == name_len) &&
306 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
307 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
308 //set flags=1 to indicate this ap is WPA
309 wrqu->data.flags = 1;
310 else wrqu->data.flags = 0;
313 break;
317 up(&priv->wx_sem);
318 return 0;
323 #endif
324 #if 0
325 static int r8192_wx_null(struct net_device *dev,
326 struct iw_request_info *info,
327 union iwreq_data *wrqu, char *extra)
329 return 0;
331 #endif
332 static int r8192_wx_force_reset(struct net_device *dev,
333 struct iw_request_info *info,
334 union iwreq_data *wrqu, char *extra)
336 struct r8192_priv *priv = ieee80211_priv(dev);
338 down(&priv->wx_sem);
340 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
341 priv->force_reset = *extra;
342 up(&priv->wx_sem);
343 return 0;
347 #ifdef RTL8192SU
348 static int r8191su_wx_get_firm_version(struct net_device *dev,
349 struct iw_request_info *info,
350 struct iw_param *wrqu, char *extra)
352 struct r8192_priv *priv = ieee80211_priv(dev);
353 u16 firmware_version;
355 down(&priv->wx_sem);
356 firmware_version = priv->pFirmware->FirmwareVersion;
357 wrqu->value = firmware_version;
358 wrqu->fixed = 1;
360 up(&priv->wx_sem);
361 return 0;
363 #endif
367 static int r8192_wx_set_rawtx(struct net_device *dev,
368 struct iw_request_info *info,
369 union iwreq_data *wrqu, char *extra)
371 struct r8192_priv *priv = ieee80211_priv(dev);
372 int ret;
374 down(&priv->wx_sem);
376 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
378 up(&priv->wx_sem);
380 return ret;
384 static int r8192_wx_set_crcmon(struct net_device *dev,
385 struct iw_request_info *info,
386 union iwreq_data *wrqu, char *extra)
388 struct r8192_priv *priv = ieee80211_priv(dev);
389 int *parms = (int *)extra;
390 int enable = (parms[0] > 0);
391 short prev = priv->crcmon;
393 down(&priv->wx_sem);
395 if(enable)
396 priv->crcmon=1;
397 else
398 priv->crcmon=0;
400 DMESG("bad CRC in monitor mode are %s",
401 priv->crcmon ? "accepted" : "rejected");
403 if(prev != priv->crcmon && priv->up){
404 //rtl8180_down(dev);
405 //rtl8180_up(dev);
408 up(&priv->wx_sem);
410 return 0;
413 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
414 union iwreq_data *wrqu, char *b)
416 struct r8192_priv *priv = ieee80211_priv(dev);
417 int ret;
418 down(&priv->wx_sem);
420 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
422 rtl8192_set_rxconf(dev);
424 up(&priv->wx_sem);
425 return ret;
428 struct iw_range_with_scan_capa
430 /* Informative stuff (to choose between different interface) */
431 __u32 throughput; /* To give an idea... */
432 /* In theory this value should be the maximum benchmarked
433 * TCP/IP throughput, because with most of these devices the
434 * bit rate is meaningless (overhead an co) to estimate how
435 * fast the connection will go and pick the fastest one.
436 * I suggest people to play with Netperf or any benchmark...
439 /* NWID (or domain id) */
440 __u32 min_nwid; /* Minimal NWID we are able to set */
441 __u32 max_nwid; /* Maximal NWID we are able to set */
443 /* Old Frequency (backward compat - moved lower ) */
444 __u16 old_num_channels;
445 __u8 old_num_frequency;
447 /* Scan capabilities */
448 __u8 scan_capa;
450 static int rtl8180_wx_get_range(struct net_device *dev,
451 struct iw_request_info *info,
452 union iwreq_data *wrqu, char *extra)
454 struct iw_range *range = (struct iw_range *)extra;
455 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
456 struct r8192_priv *priv = ieee80211_priv(dev);
457 u16 val;
458 int i;
460 wrqu->data.length = sizeof(*range);
461 memset(range, 0, sizeof(*range));
463 /* Let's try to keep this struct in the same order as in
464 * linux/include/wireless.h
467 /* TODO: See what values we can set, and remove the ones we can't
468 * set, or fill them with some default data.
471 /* ~5 Mb/s real (802.11b) */
472 range->throughput = 5 * 1000 * 1000;
474 // TODO: Not used in 802.11b?
475 // range->min_nwid; /* Minimal NWID we are able to set */
476 // TODO: Not used in 802.11b?
477 // range->max_nwid; /* Maximal NWID we are able to set */
479 /* Old Frequency (backward compat - moved lower ) */
480 // range->old_num_channels;
481 // range->old_num_frequency;
482 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
483 if(priv->rf_set_sens != NULL)
484 range->sensitivity = priv->max_sens; /* signal level threshold range */
486 range->max_qual.qual = 100;
487 /* TODO: Find real max RSSI and stick here */
488 range->max_qual.level = 0;
489 range->max_qual.noise = -98;
490 range->max_qual.updated = 7; /* Updated all three */
492 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
493 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
494 range->avg_qual.level = 20 + -98;
495 range->avg_qual.noise = 0;
496 range->avg_qual.updated = 7; /* Updated all three */
498 range->num_bitrates = RATE_COUNT;
500 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
501 range->bitrate[i] = rtl8180_rates[i];
504 range->min_frag = MIN_FRAG_THRESHOLD;
505 range->max_frag = MAX_FRAG_THRESHOLD;
507 range->min_pmp=0;
508 range->max_pmp = 5000000;
509 range->min_pmt = 0;
510 range->max_pmt = 65535*1000;
511 range->pmp_flags = IW_POWER_PERIOD;
512 range->pmt_flags = IW_POWER_TIMEOUT;
513 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
515 range->we_version_compiled = WIRELESS_EXT;
516 range->we_version_source = 16;
518 // range->retry_capa; /* What retry options are supported */
519 // range->retry_flags; /* How to decode max/min retry limit */
520 // range->r_time_flags; /* How to decode max/min retry life */
521 // range->min_retry; /* Minimal number of retries */
522 // range->max_retry; /* Maximal number of retries */
523 // range->min_r_time; /* Minimal retry lifetime */
524 // range->max_r_time; /* Maximal retry lifetime */
527 for (i = 0, val = 0; i < 14; i++) {
529 // Include only legal frequencies for some countries
530 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
531 range->freq[val].i = i + 1;
532 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
533 range->freq[val].e = 1;
534 val++;
535 } else {
536 // FIXME: do we need to set anything for channels
537 // we don't use ?
540 if (val == IW_MAX_FREQUENCIES)
541 break;
543 range->num_frequency = val;
544 range->num_channels = val;
545 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
546 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
547 tmp->scan_capa = 0x01;
548 return 0;
552 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
553 union iwreq_data *wrqu, char *b)
555 struct r8192_priv *priv = ieee80211_priv(dev);
556 struct ieee80211_device* ieee = priv->ieee80211;
557 int ret = 0;
559 if(!priv->up) return -ENETDOWN;
561 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
562 return -EAGAIN;
564 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
566 struct iw_scan_req* req = (struct iw_scan_req*)b;
567 if (req->essid_len)
569 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
570 ieee->current_network.ssid_len = req->essid_len;
571 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
572 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
576 down(&priv->wx_sem);
577 if(priv->ieee80211->state != IEEE80211_LINKED){
578 priv->ieee80211->scanning = 0;
579 ieee80211_softmac_scan_syncro(priv->ieee80211);
580 ret = 0;
582 else
583 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
584 up(&priv->wx_sem);
585 return ret;
589 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
590 union iwreq_data *wrqu, char *b)
593 int ret;
594 struct r8192_priv *priv = ieee80211_priv(dev);
596 if(!priv->up) return -ENETDOWN;
598 down(&priv->wx_sem);
600 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
602 up(&priv->wx_sem);
604 return ret;
607 static int r8192_wx_set_essid(struct net_device *dev,
608 struct iw_request_info *a,
609 union iwreq_data *wrqu, char *b)
611 struct r8192_priv *priv = ieee80211_priv(dev);
612 int ret;
613 down(&priv->wx_sem);
615 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
617 up(&priv->wx_sem);
619 return ret;
625 static int r8192_wx_get_essid(struct net_device *dev,
626 struct iw_request_info *a,
627 union iwreq_data *wrqu, char *b)
629 int ret;
630 struct r8192_priv *priv = ieee80211_priv(dev);
632 down(&priv->wx_sem);
634 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
636 up(&priv->wx_sem);
638 return ret;
642 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
643 union iwreq_data *wrqu, char *b)
645 int ret;
646 struct r8192_priv *priv = ieee80211_priv(dev);
648 down(&priv->wx_sem);
650 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
652 up(&priv->wx_sem);
653 return ret;
656 static int r8192_wx_get_name(struct net_device *dev,
657 struct iw_request_info *info,
658 union iwreq_data *wrqu, char *extra)
660 struct r8192_priv *priv = ieee80211_priv(dev);
661 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
665 static int r8192_wx_set_frag(struct net_device *dev,
666 struct iw_request_info *info,
667 union iwreq_data *wrqu, char *extra)
669 struct r8192_priv *priv = ieee80211_priv(dev);
671 if (wrqu->frag.disabled)
672 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
673 else {
674 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
675 wrqu->frag.value > MAX_FRAG_THRESHOLD)
676 return -EINVAL;
678 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
681 return 0;
685 static int r8192_wx_get_frag(struct net_device *dev,
686 struct iw_request_info *info,
687 union iwreq_data *wrqu, char *extra)
689 struct r8192_priv *priv = ieee80211_priv(dev);
691 wrqu->frag.value = priv->ieee80211->fts;
692 wrqu->frag.fixed = 0; /* no auto select */
693 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
695 return 0;
699 static int r8192_wx_set_wap(struct net_device *dev,
700 struct iw_request_info *info,
701 union iwreq_data *awrq,
702 char *extra)
705 int ret;
706 struct r8192_priv *priv = ieee80211_priv(dev);
707 // struct sockaddr *temp = (struct sockaddr *)awrq;
708 down(&priv->wx_sem);
710 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
712 up(&priv->wx_sem);
714 return ret;
719 static int r8192_wx_get_wap(struct net_device *dev,
720 struct iw_request_info *info,
721 union iwreq_data *wrqu, char *extra)
723 struct r8192_priv *priv = ieee80211_priv(dev);
725 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
729 static int r8192_wx_get_enc(struct net_device *dev,
730 struct iw_request_info *info,
731 union iwreq_data *wrqu, char *key)
733 struct r8192_priv *priv = ieee80211_priv(dev);
735 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
738 static int r8192_wx_set_enc(struct net_device *dev,
739 struct iw_request_info *info,
740 union iwreq_data *wrqu, char *key)
742 struct r8192_priv *priv = ieee80211_priv(dev);
743 struct ieee80211_device *ieee = priv->ieee80211;
744 int ret;
746 //u32 TargetContent;
747 u32 hwkey[4]={0,0,0,0};
748 u8 mask=0xff;
749 u32 key_idx=0;
750 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
751 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
752 {0x00,0x00,0x00,0x00,0x00,0x01},
753 {0x00,0x00,0x00,0x00,0x00,0x02},
754 {0x00,0x00,0x00,0x00,0x00,0x03} };
755 int i;
757 if(!priv->up) return -ENETDOWN;
759 down(&priv->wx_sem);
761 RT_TRACE(COMP_SEC, "Setting SW wep key");
762 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
764 up(&priv->wx_sem);
768 //sometimes, the length is zero while we do not type key value
769 if(wrqu->encoding.length!=0){
771 for(i=0 ; i<4 ; i++){
772 hwkey[i] |= key[4*i+0]&mask;
773 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
774 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
775 hwkey[i] |= (key[4*i+1]&mask)<<8;
776 hwkey[i] |= (key[4*i+2]&mask)<<16;
777 hwkey[i] |= (key[4*i+3]&mask)<<24;
780 #define CONF_WEP40 0x4
781 #define CONF_WEP104 0x14
783 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
784 case 0: key_idx = ieee->tx_keyidx; break;
785 case 1: key_idx = 0; break;
786 case 2: key_idx = 1; break;
787 case 3: key_idx = 2; break;
788 case 4: key_idx = 3; break;
789 default: break;
792 if(wrqu->encoding.length==0x5){
793 ieee->pairwise_key_type = KEY_TYPE_WEP40;
794 EnableHWSecurityConfig8192(dev);
796 setKey( dev,
797 key_idx, //EntryNo
798 key_idx, //KeyIndex
799 KEY_TYPE_WEP40, //KeyType
800 zero_addr[key_idx],
801 0, //DefaultKey
802 hwkey); //KeyContent
806 else if(wrqu->encoding.length==0xd){
807 ieee->pairwise_key_type = KEY_TYPE_WEP104;
808 EnableHWSecurityConfig8192(dev);
810 setKey( dev,
811 key_idx, //EntryNo
812 key_idx, //KeyIndex
813 KEY_TYPE_WEP104, //KeyType
814 zero_addr[key_idx],
815 0, //DefaultKey
816 hwkey); //KeyContent
819 else printk("wrong type in WEP, not WEP40 and WEP104\n");
823 return ret;
827 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
828 iwreq_data *wrqu, char *p){
830 struct r8192_priv *priv = ieee80211_priv(dev);
831 int *parms=(int*)p;
832 int mode=parms[0];
834 priv->ieee80211->active_scan = mode;
836 return 1;
841 static int r8192_wx_set_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);
846 int err = 0;
848 down(&priv->wx_sem);
850 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
851 wrqu->retry.disabled){
852 err = -EINVAL;
853 goto exit;
855 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
856 err = -EINVAL;
857 goto exit;
860 if(wrqu->retry.value > R8180_MAX_RETRY){
861 err= -EINVAL;
862 goto exit;
864 if (wrqu->retry.flags & IW_RETRY_MAX) {
865 priv->retry_rts = wrqu->retry.value;
866 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
868 }else {
869 priv->retry_data = wrqu->retry.value;
870 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
873 /* FIXME !
874 * We might try to write directly the TX config register
875 * or to restart just the (R)TX process.
876 * I'm unsure if whole reset is really needed
879 rtl8192_commit(dev);
881 if(priv->up){
882 rtl8180_rtx_disable(dev);
883 rtl8180_rx_enable(dev);
884 rtl8180_tx_enable(dev);
888 exit:
889 up(&priv->wx_sem);
891 return err;
894 static int r8192_wx_get_retry(struct net_device *dev,
895 struct iw_request_info *info,
896 union iwreq_data *wrqu, char *extra)
898 struct r8192_priv *priv = ieee80211_priv(dev);
901 wrqu->retry.disabled = 0; /* can't be disabled */
903 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
904 IW_RETRY_LIFETIME)
905 return -EINVAL;
907 if (wrqu->retry.flags & IW_RETRY_MAX) {
908 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
909 wrqu->retry.value = priv->retry_rts;
910 } else {
911 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
912 wrqu->retry.value = priv->retry_data;
914 //printk("returning %d",wrqu->retry.value);
917 return 0;
920 static int r8192_wx_get_sens(struct net_device *dev,
921 struct iw_request_info *info,
922 union iwreq_data *wrqu, char *extra)
924 struct r8192_priv *priv = ieee80211_priv(dev);
925 if(priv->rf_set_sens == NULL)
926 return -1; /* we have not this support for this radio */
927 wrqu->sens.value = priv->sens;
928 return 0;
932 static int r8192_wx_set_sens(struct net_device *dev,
933 struct iw_request_info *info,
934 union iwreq_data *wrqu, char *extra)
937 struct r8192_priv *priv = ieee80211_priv(dev);
939 short err = 0;
940 down(&priv->wx_sem);
941 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
942 if(priv->rf_set_sens == NULL) {
943 err= -1; /* we have not this support for this radio */
944 goto exit;
946 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
947 priv->sens = wrqu->sens.value;
948 else
949 err= -EINVAL;
951 exit:
952 up(&priv->wx_sem);
954 return err;
957 #if 0
958 static int r8192_wx_get_enc_ext(struct net_device *dev,
959 struct iw_request_info *info,
960 union iwreq_data *wrqu, char *extra)
962 struct r8192_priv *priv = ieee80211_priv(dev);
963 int ret = 0;
964 ret = ieee80211_wx_get_encode_ext(priv->ieee80211, info, wrqu, extra);
965 return ret;
967 #endif
968 //hw security need to reorganized.
969 static int r8192_wx_set_enc_ext(struct net_device *dev,
970 struct iw_request_info *info,
971 union iwreq_data *wrqu, char *extra)
973 int ret=0;
974 struct r8192_priv *priv = ieee80211_priv(dev);
975 struct ieee80211_device* ieee = priv->ieee80211;
976 //printk("===>%s()\n", __FUNCTION__);
979 down(&priv->wx_sem);
980 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
983 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
984 u8 zero[6] = {0};
985 u32 key[4] = {0};
986 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
987 struct iw_point *encoding = &wrqu->encoding;
988 #if 0
989 static u8 CAM_CONST_ADDR[4][6] = {
990 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
991 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
992 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
993 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
994 #endif
995 u8 idx = 0, alg = 0, group = 0;
996 if ((encoding->flags & IW_ENCODE_DISABLED) ||
997 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
999 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1000 CamResetAllEntry(dev);
1001 goto end_hw_sec;
1003 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;
1004 idx = encoding->flags & IW_ENCODE_INDEX;
1005 if (idx)
1006 idx --;
1007 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1009 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
1011 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1012 alg = KEY_TYPE_WEP104;
1013 ieee->pairwise_key_type = alg;
1014 EnableHWSecurityConfig8192(dev);
1016 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1018 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1021 setKey( dev,
1022 idx,//EntryNo
1023 idx, //KeyIndex
1024 alg, //KeyType
1025 zero, //MacAddr
1026 0, //DefaultKey
1027 key); //KeyContent
1029 else if (group)
1031 ieee->group_key_type = alg;
1032 setKey( dev,
1033 idx,//EntryNo
1034 idx, //KeyIndex
1035 alg, //KeyType
1036 broadcast_addr, //MacAddr
1037 0, //DefaultKey
1038 key); //KeyContent
1040 else //pairwise key
1042 setKey( dev,
1043 4,//EntryNo
1044 idx, //KeyIndex
1045 alg, //KeyType
1046 (u8*)ieee->ap_mac_addr, //MacAddr
1047 0, //DefaultKey
1048 key); //KeyContent
1054 end_hw_sec:
1056 up(&priv->wx_sem);
1057 return ret;
1059 static int r8192_wx_set_auth(struct net_device *dev,
1060 struct iw_request_info *info,
1061 union iwreq_data *data, char *extra)
1063 int ret=0;
1065 //printk("====>%s()\n", __FUNCTION__);
1066 struct r8192_priv *priv = ieee80211_priv(dev);
1067 down(&priv->wx_sem);
1068 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1069 up(&priv->wx_sem);
1070 return ret;
1073 static int r8192_wx_set_mlme(struct net_device *dev,
1074 struct iw_request_info *info,
1075 union iwreq_data *wrqu, char *extra)
1077 //printk("====>%s()\n", __FUNCTION__);
1079 int ret=0;
1080 struct r8192_priv *priv = ieee80211_priv(dev);
1081 down(&priv->wx_sem);
1082 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1083 up(&priv->wx_sem);
1084 return ret;
1087 static int r8192_wx_set_gen_ie(struct net_device *dev,
1088 struct iw_request_info *info,
1089 union iwreq_data *data, char *extra)
1091 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1092 int ret=0;
1093 struct r8192_priv *priv = ieee80211_priv(dev);
1094 down(&priv->wx_sem);
1095 #if 1
1096 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1097 #endif
1098 up(&priv->wx_sem);
1099 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1100 return ret;
1105 static int dummy(struct net_device *dev, struct iw_request_info *a,
1106 union iwreq_data *wrqu,char *b)
1108 return -1;
1112 static iw_handler r8192_wx_handlers[] =
1114 NULL, /* SIOCSIWCOMMIT */
1115 r8192_wx_get_name, /* SIOCGIWNAME */
1116 dummy, /* SIOCSIWNWID */
1117 dummy, /* SIOCGIWNWID */
1118 r8192_wx_set_freq, /* SIOCSIWFREQ */
1119 r8192_wx_get_freq, /* SIOCGIWFREQ */
1120 r8192_wx_set_mode, /* SIOCSIWMODE */
1121 r8192_wx_get_mode, /* SIOCGIWMODE */
1122 r8192_wx_set_sens, /* SIOCSIWSENS */
1123 r8192_wx_get_sens, /* SIOCGIWSENS */
1124 NULL, /* SIOCSIWRANGE */
1125 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1126 NULL, /* SIOCSIWPRIV */
1127 NULL, /* SIOCGIWPRIV */
1128 NULL, /* SIOCSIWSTATS */
1129 NULL, /* SIOCGIWSTATS */
1130 dummy, /* SIOCSIWSPY */
1131 dummy, /* SIOCGIWSPY */
1132 NULL, /* SIOCGIWTHRSPY */
1133 NULL, /* SIOCWIWTHRSPY */
1134 r8192_wx_set_wap, /* SIOCSIWAP */
1135 r8192_wx_get_wap, /* SIOCGIWAP */
1136 r8192_wx_set_mlme, /* MLME-- */
1137 dummy, /* SIOCGIWAPLIST -- depricated */
1138 r8192_wx_set_scan, /* SIOCSIWSCAN */
1139 r8192_wx_get_scan, /* SIOCGIWSCAN */
1140 r8192_wx_set_essid, /* SIOCSIWESSID */
1141 r8192_wx_get_essid, /* SIOCGIWESSID */
1142 dummy, /* SIOCSIWNICKN */
1143 dummy, /* SIOCGIWNICKN */
1144 NULL, /* -- hole -- */
1145 NULL, /* -- hole -- */
1146 r8192_wx_set_rate, /* SIOCSIWRATE */
1147 r8192_wx_get_rate, /* SIOCGIWRATE */
1148 r8192_wx_set_rts, /* SIOCSIWRTS */
1149 r8192_wx_get_rts, /* SIOCGIWRTS */
1150 r8192_wx_set_frag, /* SIOCSIWFRAG */
1151 r8192_wx_get_frag, /* SIOCGIWFRAG */
1152 dummy, /* SIOCSIWTXPOW */
1153 dummy, /* SIOCGIWTXPOW */
1154 r8192_wx_set_retry, /* SIOCSIWRETRY */
1155 r8192_wx_get_retry, /* SIOCGIWRETRY */
1156 r8192_wx_set_enc, /* SIOCSIWENCODE */
1157 r8192_wx_get_enc, /* SIOCGIWENCODE */
1158 r8192_wx_set_power, /* SIOCSIWPOWER */
1159 r8192_wx_get_power, /* SIOCGIWPOWER */
1160 NULL, /*---hole---*/
1161 NULL, /*---hole---*/
1162 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1163 NULL, /* SIOCSIWGENIE */
1165 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1166 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1167 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1168 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1169 NULL, /* SIOCSIWPMKSA */
1170 NULL, /*---hole---*/
1175 static const struct iw_priv_args r8192_private_args[] = {
1178 SIOCIWFIRSTPRIV + 0x0,
1179 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1183 SIOCIWFIRSTPRIV + 0x1,
1184 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1188 SIOCIWFIRSTPRIV + 0x2,
1189 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1191 #ifdef JOHN_IOCTL
1194 SIOCIWFIRSTPRIV + 0x3,
1195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1199 SIOCIWFIRSTPRIV + 0x4,
1200 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1204 SIOCIWFIRSTPRIV + 0x5,
1205 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1209 SIOCIWFIRSTPRIV + 0x6,
1210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1214 SIOCIWFIRSTPRIV + 0x7,
1215 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1219 SIOCIWFIRSTPRIV + 0x8,
1220 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1224 SIOCIWFIRSTPRIV + 0x9,
1225 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1228 #endif
1231 SIOCIWFIRSTPRIV + 0x3,
1232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1235 #ifdef RTL8192SU
1238 SIOCIWFIRSTPRIV + 0x5,
1239 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
1240 "firm_ver"
1242 #endif
1246 static iw_handler r8192_private_handler[] = {
1247 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1248 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1249 // r8192_wx_set_forceassociate,
1250 // r8192_wx_set_beaconinterval,
1251 // r8192_wx_set_monitor_type,
1252 r8192_wx_set_scan_type,
1253 r8192_wx_set_rawtx,
1254 #ifdef JOHN_IOCTL
1255 r8192_wx_read_regs,
1256 r8192_wx_write_regs,
1257 r8192_wx_read_bb,
1258 r8192_wx_write_bb,
1259 r8192_wx_read_nicb,
1260 r8192_wx_write_nicb,
1261 r8192_wx_get_ap_status,
1262 #endif
1263 r8192_wx_force_reset,
1264 (iw_handler)NULL,
1265 #ifdef RTL8192SU
1266 (iw_handler)r8191su_wx_get_firm_version,
1267 #endif
1270 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1272 struct r8192_priv *priv = ieee80211_priv(dev);
1273 struct ieee80211_device* ieee = priv->ieee80211;
1274 struct iw_statistics* wstats = &priv->wstats;
1275 int tmp_level = 0;
1276 int tmp_qual = 0;
1277 int tmp_noise = 0;
1278 if(ieee->state < IEEE80211_LINKED)
1280 wstats->qual.qual = 0;
1281 wstats->qual.level = 0;
1282 wstats->qual.noise = 0;
1283 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1284 return wstats;
1287 tmp_level = (&ieee->current_network)->stats.rssi;
1288 tmp_qual = (&ieee->current_network)->stats.signal;
1289 tmp_noise = (&ieee->current_network)->stats.noise;
1290 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1292 wstats->qual.level = tmp_level;
1293 wstats->qual.qual = tmp_qual;
1294 wstats->qual.noise = tmp_noise;
1295 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1296 return wstats;
1299 struct iw_handler_def r8192_wx_handlers_def={
1300 .standard = r8192_wx_handlers,
1301 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1302 .private = r8192_private_handler,
1303 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1304 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1305 .get_wireless_stats = r8192_get_wireless_stats,
1306 .private_args = (struct iw_priv_args *)r8192_private_args,