x86: Fix false positive section mismatch in es7000_32.c
[linux-2.6/mini2440.git] / drivers / staging / rtl8192su / r8192U_wx.c
blobf9eafb16dbb7fcd542fe2dc8d98afaa9ce64a468
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 #ifdef ENABLE_DOT11D
31 #include "dot11d.h"
32 #endif
34 #define RATE_COUNT 12
35 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
36 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
39 #ifndef ENETDOWN
40 #define ENETDOWN 1
41 #endif
43 static int r8192_wx_get_freq(struct net_device *dev,
44 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_freq(priv->ieee80211,a,wrqu,b);
53 #if 0
55 static int r8192_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
56 union iwreq_data *wrqu, char *b)
58 int *parms = (int *)b;
59 int bi = parms[0];
61 struct r8192_priv *priv = ieee80211_priv(dev);
63 down(&priv->wx_sem);
64 DMESG("setting beacon interval to %x",bi);
66 priv->ieee80211->beacon_interval=bi;
67 rtl8180_commit(dev);
68 up(&priv->wx_sem);
70 return 0;
74 static int r8192_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
75 union iwreq_data *wrqu, char *extra)
77 struct r8192_priv *priv=ieee80211_priv(dev);
78 int *parms = (int *)extra;
80 priv->ieee80211->force_associate = (parms[0] > 0);
83 return 0;
86 #endif
87 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
88 union iwreq_data *wrqu, char *b)
90 struct r8192_priv *priv=ieee80211_priv(dev);
92 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
97 static int r8192_wx_get_rate(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_rate(priv->ieee80211,info,wrqu,extra);
107 static int r8192_wx_set_rate(struct net_device *dev,
108 struct iw_request_info *info,
109 union iwreq_data *wrqu, char *extra)
111 int ret;
112 struct r8192_priv *priv = ieee80211_priv(dev);
114 down(&priv->wx_sem);
116 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
118 up(&priv->wx_sem);
120 return ret;
124 static int r8192_wx_set_rts(struct net_device *dev,
125 struct iw_request_info *info,
126 union iwreq_data *wrqu, char *extra)
128 int ret;
129 struct r8192_priv *priv = ieee80211_priv(dev);
131 down(&priv->wx_sem);
133 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
135 up(&priv->wx_sem);
137 return ret;
140 static int r8192_wx_get_rts(struct net_device *dev,
141 struct iw_request_info *info,
142 union iwreq_data *wrqu, char *extra)
144 struct r8192_priv *priv = ieee80211_priv(dev);
145 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
148 static int r8192_wx_set_power(struct net_device *dev,
149 struct iw_request_info *info,
150 union iwreq_data *wrqu, char *extra)
152 int ret;
153 struct r8192_priv *priv = ieee80211_priv(dev);
155 down(&priv->wx_sem);
157 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
159 up(&priv->wx_sem);
161 return ret;
164 static int r8192_wx_get_power(struct net_device *dev,
165 struct iw_request_info *info,
166 union iwreq_data *wrqu, char *extra)
168 struct r8192_priv *priv = ieee80211_priv(dev);
169 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
172 #ifdef JOHN_IOCTL
173 u16 read_rtl8225(struct net_device *dev, u8 addr);
174 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
175 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
176 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
178 static int r8192_wx_read_regs(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);
183 u8 addr;
184 u16 data1;
186 down(&priv->wx_sem);
189 get_user(addr,(u8*)wrqu->data.pointer);
190 data1 = read_rtl8225(dev, addr);
191 wrqu->data.length = data1;
193 up(&priv->wx_sem);
194 return 0;
198 static int r8192_wx_write_regs(struct net_device *dev,
199 struct iw_request_info *info,
200 union iwreq_data *wrqu, char *extra)
202 struct r8192_priv *priv = ieee80211_priv(dev);
203 u8 addr;
205 down(&priv->wx_sem);
207 get_user(addr, (u8*)wrqu->data.pointer);
208 write_rtl8225(dev, addr, wrqu->data.length);
210 up(&priv->wx_sem);
211 return 0;
215 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
216 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
218 static int r8192_wx_read_bb(struct net_device *dev,
219 struct iw_request_info *info,
220 union iwreq_data *wrqu, char *extra)
222 struct r8192_priv *priv = ieee80211_priv(dev);
223 u8 databb;
224 #if 0
225 int i;
226 for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
227 #endif
229 down(&priv->wx_sem);
231 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
232 wrqu->data.length = databb;
234 up(&priv->wx_sem);
235 return 0;
238 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
239 static int r8192_wx_write_bb(struct net_device *dev,
240 struct iw_request_info *info,
241 union iwreq_data *wrqu, char *extra)
243 struct r8192_priv *priv = ieee80211_priv(dev);
244 u8 databb;
246 down(&priv->wx_sem);
248 get_user(databb, (u8*)wrqu->data.pointer);
249 rtl8187_write_phy(dev, wrqu->data.length, databb);
251 up(&priv->wx_sem);
252 return 0;
257 static int r8192_wx_write_nicb(struct net_device *dev,
258 struct iw_request_info *info,
259 union iwreq_data *wrqu, char *extra)
261 struct r8192_priv *priv = ieee80211_priv(dev);
262 u32 addr;
264 down(&priv->wx_sem);
266 get_user(addr, (u32*)wrqu->data.pointer);
267 write_nic_byte(dev, addr, wrqu->data.length);
269 up(&priv->wx_sem);
270 return 0;
273 static int r8192_wx_read_nicb(struct net_device *dev,
274 struct iw_request_info *info,
275 union iwreq_data *wrqu, char *extra)
277 struct r8192_priv *priv = ieee80211_priv(dev);
278 u32 addr;
279 u16 data1;
281 down(&priv->wx_sem);
283 get_user(addr,(u32*)wrqu->data.pointer);
284 data1 = read_nic_byte(dev, addr);
285 wrqu->data.length = data1;
287 up(&priv->wx_sem);
288 return 0;
291 static int r8192_wx_get_ap_status(struct net_device *dev,
292 struct iw_request_info *info,
293 union iwreq_data *wrqu, char *extra)
295 struct r8192_priv *priv = ieee80211_priv(dev);
296 struct ieee80211_device *ieee = priv->ieee80211;
297 struct ieee80211_network *target;
298 int name_len;
300 down(&priv->wx_sem);
302 //count the length of input ssid
303 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
305 //search for the correspoding info which is received
306 list_for_each_entry(target, &ieee->network_list, list) {
307 if ( (target->ssid_len == name_len) &&
308 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
309 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
310 //set flags=1 to indicate this ap is WPA
311 wrqu->data.flags = 1;
312 else wrqu->data.flags = 0;
315 break;
319 up(&priv->wx_sem);
320 return 0;
325 #endif
326 #if 0
327 static int r8192_wx_null(struct net_device *dev,
328 struct iw_request_info *info,
329 union iwreq_data *wrqu, char *extra)
331 return 0;
333 #endif
334 static int r8192_wx_force_reset(struct net_device *dev,
335 struct iw_request_info *info,
336 union iwreq_data *wrqu, char *extra)
338 struct r8192_priv *priv = ieee80211_priv(dev);
340 down(&priv->wx_sem);
342 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
343 priv->force_reset = *extra;
344 up(&priv->wx_sem);
345 return 0;
349 #ifdef RTL8192SU
350 static int r8191su_wx_get_firm_version(struct net_device *dev,
351 struct iw_request_info *info,
352 struct iw_param *wrqu, char *extra)
354 struct r8192_priv *priv = ieee80211_priv(dev);
355 u16 firmware_version;
357 down(&priv->wx_sem);
358 firmware_version = priv->pFirmware->FirmwareVersion;
359 wrqu->value = firmware_version;
360 wrqu->fixed = 1;
362 up(&priv->wx_sem);
363 return 0;
365 #endif
369 static int r8192_wx_set_rawtx(struct net_device *dev,
370 struct iw_request_info *info,
371 union iwreq_data *wrqu, char *extra)
373 struct r8192_priv *priv = ieee80211_priv(dev);
374 int ret;
376 down(&priv->wx_sem);
378 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
380 up(&priv->wx_sem);
382 return ret;
386 static int r8192_wx_set_crcmon(struct net_device *dev,
387 struct iw_request_info *info,
388 union iwreq_data *wrqu, char *extra)
390 struct r8192_priv *priv = ieee80211_priv(dev);
391 int *parms = (int *)extra;
392 int enable = (parms[0] > 0);
393 short prev = priv->crcmon;
395 down(&priv->wx_sem);
397 if(enable)
398 priv->crcmon=1;
399 else
400 priv->crcmon=0;
402 DMESG("bad CRC in monitor mode are %s",
403 priv->crcmon ? "accepted" : "rejected");
405 if(prev != priv->crcmon && priv->up){
406 //rtl8180_down(dev);
407 //rtl8180_up(dev);
410 up(&priv->wx_sem);
412 return 0;
415 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
416 union iwreq_data *wrqu, char *b)
418 struct r8192_priv *priv = ieee80211_priv(dev);
419 int ret;
420 down(&priv->wx_sem);
422 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
424 rtl8192_set_rxconf(dev);
426 up(&priv->wx_sem);
427 return ret;
430 struct iw_range_with_scan_capa
432 /* Informative stuff (to choose between different interface) */
433 __u32 throughput; /* To give an idea... */
434 /* In theory this value should be the maximum benchmarked
435 * TCP/IP throughput, because with most of these devices the
436 * bit rate is meaningless (overhead an co) to estimate how
437 * fast the connection will go and pick the fastest one.
438 * I suggest people to play with Netperf or any benchmark...
441 /* NWID (or domain id) */
442 __u32 min_nwid; /* Minimal NWID we are able to set */
443 __u32 max_nwid; /* Maximal NWID we are able to set */
445 /* Old Frequency (backward compat - moved lower ) */
446 __u16 old_num_channels;
447 __u8 old_num_frequency;
449 /* Scan capabilities */
450 __u8 scan_capa;
452 static int rtl8180_wx_get_range(struct net_device *dev,
453 struct iw_request_info *info,
454 union iwreq_data *wrqu, char *extra)
456 struct iw_range *range = (struct iw_range *)extra;
457 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
458 struct r8192_priv *priv = ieee80211_priv(dev);
459 u16 val;
460 int i;
462 wrqu->data.length = sizeof(*range);
463 memset(range, 0, sizeof(*range));
465 /* Let's try to keep this struct in the same order as in
466 * linux/include/wireless.h
469 /* TODO: See what values we can set, and remove the ones we can't
470 * set, or fill them with some default data.
473 /* ~5 Mb/s real (802.11b) */
474 range->throughput = 5 * 1000 * 1000;
476 // TODO: Not used in 802.11b?
477 // range->min_nwid; /* Minimal NWID we are able to set */
478 // TODO: Not used in 802.11b?
479 // range->max_nwid; /* Maximal NWID we are able to set */
481 /* Old Frequency (backward compat - moved lower ) */
482 // range->old_num_channels;
483 // range->old_num_frequency;
484 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
485 if(priv->rf_set_sens != NULL)
486 range->sensitivity = priv->max_sens; /* signal level threshold range */
488 range->max_qual.qual = 100;
489 /* TODO: Find real max RSSI and stick here */
490 range->max_qual.level = 0;
491 range->max_qual.noise = -98;
492 range->max_qual.updated = 7; /* Updated all three */
494 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
495 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
496 range->avg_qual.level = 20 + -98;
497 range->avg_qual.noise = 0;
498 range->avg_qual.updated = 7; /* Updated all three */
500 range->num_bitrates = RATE_COUNT;
502 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
503 range->bitrate[i] = rtl8180_rates[i];
506 range->min_frag = MIN_FRAG_THRESHOLD;
507 range->max_frag = MAX_FRAG_THRESHOLD;
509 range->min_pmp=0;
510 range->max_pmp = 5000000;
511 range->min_pmt = 0;
512 range->max_pmt = 65535*1000;
513 range->pmp_flags = IW_POWER_PERIOD;
514 range->pmt_flags = IW_POWER_TIMEOUT;
515 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
517 range->we_version_compiled = WIRELESS_EXT;
518 range->we_version_source = 16;
520 // range->retry_capa; /* What retry options are supported */
521 // range->retry_flags; /* How to decode max/min retry limit */
522 // range->r_time_flags; /* How to decode max/min retry life */
523 // range->min_retry; /* Minimal number of retries */
524 // range->max_retry; /* Maximal number of retries */
525 // range->min_r_time; /* Minimal retry lifetime */
526 // range->max_r_time; /* Maximal retry lifetime */
529 for (i = 0, val = 0; i < 14; i++) {
531 // Include only legal frequencies for some countries
532 #ifdef ENABLE_DOT11D
533 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
534 #else
535 if ((priv->ieee80211->channel_map)[i+1]) {
536 #endif
537 range->freq[val].i = i + 1;
538 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
539 range->freq[val].e = 1;
540 val++;
541 } else {
542 // FIXME: do we need to set anything for channels
543 // we don't use ?
546 if (val == IW_MAX_FREQUENCIES)
547 break;
549 range->num_frequency = val;
550 range->num_channels = val;
551 #if WIRELESS_EXT > 17
552 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
553 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
554 #endif
555 tmp->scan_capa = 0x01;
556 return 0;
560 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
561 union iwreq_data *wrqu, char *b)
563 struct r8192_priv *priv = ieee80211_priv(dev);
564 struct ieee80211_device* ieee = priv->ieee80211;
565 int ret = 0;
567 if(!priv->up) return -ENETDOWN;
569 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
570 return -EAGAIN;
571 #if WIRELESS_EXT > 17
572 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
574 struct iw_scan_req* req = (struct iw_scan_req*)b;
575 if (req->essid_len)
577 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
578 ieee->current_network.ssid_len = req->essid_len;
579 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
580 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
583 #endif
585 down(&priv->wx_sem);
586 if(priv->ieee80211->state != IEEE80211_LINKED){
587 priv->ieee80211->scanning = 0;
588 ieee80211_softmac_scan_syncro(priv->ieee80211);
589 ret = 0;
591 else
592 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
593 up(&priv->wx_sem);
594 return ret;
598 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
599 union iwreq_data *wrqu, char *b)
602 int ret;
603 struct r8192_priv *priv = ieee80211_priv(dev);
605 if(!priv->up) return -ENETDOWN;
607 down(&priv->wx_sem);
609 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
611 up(&priv->wx_sem);
613 return ret;
616 static int r8192_wx_set_essid(struct net_device *dev,
617 struct iw_request_info *a,
618 union iwreq_data *wrqu, char *b)
620 struct r8192_priv *priv = ieee80211_priv(dev);
621 int ret;
622 down(&priv->wx_sem);
624 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
626 up(&priv->wx_sem);
628 return ret;
634 static int r8192_wx_get_essid(struct net_device *dev,
635 struct iw_request_info *a,
636 union iwreq_data *wrqu, char *b)
638 int ret;
639 struct r8192_priv *priv = ieee80211_priv(dev);
641 down(&priv->wx_sem);
643 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
645 up(&priv->wx_sem);
647 return ret;
651 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
652 union iwreq_data *wrqu, char *b)
654 int ret;
655 struct r8192_priv *priv = ieee80211_priv(dev);
657 down(&priv->wx_sem);
659 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
661 up(&priv->wx_sem);
662 return ret;
665 static int r8192_wx_get_name(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);
670 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
674 static int r8192_wx_set_frag(struct net_device *dev,
675 struct iw_request_info *info,
676 union iwreq_data *wrqu, char *extra)
678 struct r8192_priv *priv = ieee80211_priv(dev);
680 if (wrqu->frag.disabled)
681 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
682 else {
683 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
684 wrqu->frag.value > MAX_FRAG_THRESHOLD)
685 return -EINVAL;
687 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
690 return 0;
694 static int r8192_wx_get_frag(struct net_device *dev,
695 struct iw_request_info *info,
696 union iwreq_data *wrqu, char *extra)
698 struct r8192_priv *priv = ieee80211_priv(dev);
700 wrqu->frag.value = priv->ieee80211->fts;
701 wrqu->frag.fixed = 0; /* no auto select */
702 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
704 return 0;
708 static int r8192_wx_set_wap(struct net_device *dev,
709 struct iw_request_info *info,
710 union iwreq_data *awrq,
711 char *extra)
714 int ret;
715 struct r8192_priv *priv = ieee80211_priv(dev);
716 // struct sockaddr *temp = (struct sockaddr *)awrq;
717 down(&priv->wx_sem);
719 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
721 up(&priv->wx_sem);
723 return ret;
728 static int r8192_wx_get_wap(struct net_device *dev,
729 struct iw_request_info *info,
730 union iwreq_data *wrqu, char *extra)
732 struct r8192_priv *priv = ieee80211_priv(dev);
734 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
738 static int r8192_wx_get_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);
744 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
747 static int r8192_wx_set_enc(struct net_device *dev,
748 struct iw_request_info *info,
749 union iwreq_data *wrqu, char *key)
751 struct r8192_priv *priv = ieee80211_priv(dev);
752 struct ieee80211_device *ieee = priv->ieee80211;
753 int ret;
755 //u32 TargetContent;
756 u32 hwkey[4]={0,0,0,0};
757 u8 mask=0xff;
758 u32 key_idx=0;
759 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
760 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
761 {0x00,0x00,0x00,0x00,0x00,0x01},
762 {0x00,0x00,0x00,0x00,0x00,0x02},
763 {0x00,0x00,0x00,0x00,0x00,0x03} };
764 int i;
766 if(!priv->up) return -ENETDOWN;
768 down(&priv->wx_sem);
770 RT_TRACE(COMP_SEC, "Setting SW wep key");
771 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
773 up(&priv->wx_sem);
777 //sometimes, the length is zero while we do not type key value
778 if(wrqu->encoding.length!=0){
780 for(i=0 ; i<4 ; i++){
781 hwkey[i] |= key[4*i+0]&mask;
782 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
783 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
784 hwkey[i] |= (key[4*i+1]&mask)<<8;
785 hwkey[i] |= (key[4*i+2]&mask)<<16;
786 hwkey[i] |= (key[4*i+3]&mask)<<24;
789 #define CONF_WEP40 0x4
790 #define CONF_WEP104 0x14
792 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
793 case 0: key_idx = ieee->tx_keyidx; break;
794 case 1: key_idx = 0; break;
795 case 2: key_idx = 1; break;
796 case 3: key_idx = 2; break;
797 case 4: key_idx = 3; break;
798 default: break;
801 if(wrqu->encoding.length==0x5){
802 ieee->pairwise_key_type = KEY_TYPE_WEP40;
803 EnableHWSecurityConfig8192(dev);
805 setKey( dev,
806 key_idx, //EntryNo
807 key_idx, //KeyIndex
808 KEY_TYPE_WEP40, //KeyType
809 zero_addr[key_idx],
810 0, //DefaultKey
811 hwkey); //KeyContent
815 else if(wrqu->encoding.length==0xd){
816 ieee->pairwise_key_type = KEY_TYPE_WEP104;
817 EnableHWSecurityConfig8192(dev);
819 setKey( dev,
820 key_idx, //EntryNo
821 key_idx, //KeyIndex
822 KEY_TYPE_WEP104, //KeyType
823 zero_addr[key_idx],
824 0, //DefaultKey
825 hwkey); //KeyContent
828 else printk("wrong type in WEP, not WEP40 and WEP104\n");
832 return ret;
836 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
837 iwreq_data *wrqu, char *p){
839 struct r8192_priv *priv = ieee80211_priv(dev);
840 int *parms=(int*)p;
841 int mode=parms[0];
843 priv->ieee80211->active_scan = mode;
845 return 1;
850 static int r8192_wx_set_retry(struct net_device *dev,
851 struct iw_request_info *info,
852 union iwreq_data *wrqu, char *extra)
854 struct r8192_priv *priv = ieee80211_priv(dev);
855 int err = 0;
857 down(&priv->wx_sem);
859 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
860 wrqu->retry.disabled){
861 err = -EINVAL;
862 goto exit;
864 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
865 err = -EINVAL;
866 goto exit;
869 if(wrqu->retry.value > R8180_MAX_RETRY){
870 err= -EINVAL;
871 goto exit;
873 if (wrqu->retry.flags & IW_RETRY_MAX) {
874 priv->retry_rts = wrqu->retry.value;
875 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
877 }else {
878 priv->retry_data = wrqu->retry.value;
879 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
882 /* FIXME !
883 * We might try to write directly the TX config register
884 * or to restart just the (R)TX process.
885 * I'm unsure if whole reset is really needed
888 rtl8192_commit(dev);
890 if(priv->up){
891 rtl8180_rtx_disable(dev);
892 rtl8180_rx_enable(dev);
893 rtl8180_tx_enable(dev);
897 exit:
898 up(&priv->wx_sem);
900 return err;
903 static int r8192_wx_get_retry(struct net_device *dev,
904 struct iw_request_info *info,
905 union iwreq_data *wrqu, char *extra)
907 struct r8192_priv *priv = ieee80211_priv(dev);
910 wrqu->retry.disabled = 0; /* can't be disabled */
912 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
913 IW_RETRY_LIFETIME)
914 return -EINVAL;
916 if (wrqu->retry.flags & IW_RETRY_MAX) {
917 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
918 wrqu->retry.value = priv->retry_rts;
919 } else {
920 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
921 wrqu->retry.value = priv->retry_data;
923 //printk("returning %d",wrqu->retry.value);
926 return 0;
929 static int r8192_wx_get_sens(struct net_device *dev,
930 struct iw_request_info *info,
931 union iwreq_data *wrqu, char *extra)
933 struct r8192_priv *priv = ieee80211_priv(dev);
934 if(priv->rf_set_sens == NULL)
935 return -1; /* we have not this support for this radio */
936 wrqu->sens.value = priv->sens;
937 return 0;
941 static int r8192_wx_set_sens(struct net_device *dev,
942 struct iw_request_info *info,
943 union iwreq_data *wrqu, char *extra)
946 struct r8192_priv *priv = ieee80211_priv(dev);
948 short err = 0;
949 down(&priv->wx_sem);
950 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
951 if(priv->rf_set_sens == NULL) {
952 err= -1; /* we have not this support for this radio */
953 goto exit;
955 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
956 priv->sens = wrqu->sens.value;
957 else
958 err= -EINVAL;
960 exit:
961 up(&priv->wx_sem);
963 return err;
966 #if (WIRELESS_EXT >= 18)
967 #if 0
968 static int r8192_wx_get_enc_ext(struct net_device *dev,
969 struct iw_request_info *info,
970 union iwreq_data *wrqu, char *extra)
972 struct r8192_priv *priv = ieee80211_priv(dev);
973 int ret = 0;
974 ret = ieee80211_wx_get_encode_ext(priv->ieee80211, info, wrqu, extra);
975 return ret;
977 #endif
978 //hw security need to reorganized.
979 static int r8192_wx_set_enc_ext(struct net_device *dev,
980 struct iw_request_info *info,
981 union iwreq_data *wrqu, char *extra)
983 int ret=0;
984 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
985 struct r8192_priv *priv = ieee80211_priv(dev);
986 struct ieee80211_device* ieee = priv->ieee80211;
987 //printk("===>%s()\n", __FUNCTION__);
990 down(&priv->wx_sem);
991 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
994 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
995 u8 zero[6] = {0};
996 u32 key[4] = {0};
997 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
998 struct iw_point *encoding = &wrqu->encoding;
999 #if 0
1000 static u8 CAM_CONST_ADDR[4][6] = {
1001 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1002 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1003 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1004 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1005 #endif
1006 u8 idx = 0, alg = 0, group = 0;
1007 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1008 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
1010 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1011 CamResetAllEntry(dev);
1012 goto end_hw_sec;
1014 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;
1015 idx = encoding->flags & IW_ENCODE_INDEX;
1016 if (idx)
1017 idx --;
1018 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1020 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
1022 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1023 alg = KEY_TYPE_WEP104;
1024 ieee->pairwise_key_type = alg;
1025 EnableHWSecurityConfig8192(dev);
1027 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1029 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1032 setKey( dev,
1033 idx,//EntryNo
1034 idx, //KeyIndex
1035 alg, //KeyType
1036 zero, //MacAddr
1037 0, //DefaultKey
1038 key); //KeyContent
1040 else if (group)
1042 ieee->group_key_type = alg;
1043 setKey( dev,
1044 idx,//EntryNo
1045 idx, //KeyIndex
1046 alg, //KeyType
1047 broadcast_addr, //MacAddr
1048 0, //DefaultKey
1049 key); //KeyContent
1051 else //pairwise key
1053 setKey( dev,
1054 4,//EntryNo
1055 idx, //KeyIndex
1056 alg, //KeyType
1057 (u8*)ieee->ap_mac_addr, //MacAddr
1058 0, //DefaultKey
1059 key); //KeyContent
1065 end_hw_sec:
1067 up(&priv->wx_sem);
1068 #endif
1069 return ret;
1072 static int r8192_wx_set_auth(struct net_device *dev,
1073 struct iw_request_info *info,
1074 union iwreq_data *data, char *extra)
1076 int ret=0;
1077 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1078 //printk("====>%s()\n", __FUNCTION__);
1079 struct r8192_priv *priv = ieee80211_priv(dev);
1080 down(&priv->wx_sem);
1081 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1082 up(&priv->wx_sem);
1083 #endif
1084 return ret;
1087 static int r8192_wx_set_mlme(struct net_device *dev,
1088 struct iw_request_info *info,
1089 union iwreq_data *wrqu, char *extra)
1091 //printk("====>%s()\n", __FUNCTION__);
1093 int ret=0;
1094 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1095 struct r8192_priv *priv = ieee80211_priv(dev);
1096 down(&priv->wx_sem);
1097 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1099 up(&priv->wx_sem);
1100 #endif
1101 return ret;
1103 #endif
1104 static int r8192_wx_set_gen_ie(struct net_device *dev,
1105 struct iw_request_info *info,
1106 union iwreq_data *data, char *extra)
1108 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1109 int ret=0;
1110 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1111 struct r8192_priv *priv = ieee80211_priv(dev);
1112 down(&priv->wx_sem);
1113 #if 1
1114 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1115 #endif
1116 up(&priv->wx_sem);
1117 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1118 #endif
1119 return ret;
1124 static int dummy(struct net_device *dev, struct iw_request_info *a,
1125 union iwreq_data *wrqu,char *b)
1127 return -1;
1131 static iw_handler r8192_wx_handlers[] =
1133 NULL, /* SIOCSIWCOMMIT */
1134 r8192_wx_get_name, /* SIOCGIWNAME */
1135 dummy, /* SIOCSIWNWID */
1136 dummy, /* SIOCGIWNWID */
1137 r8192_wx_set_freq, /* SIOCSIWFREQ */
1138 r8192_wx_get_freq, /* SIOCGIWFREQ */
1139 r8192_wx_set_mode, /* SIOCSIWMODE */
1140 r8192_wx_get_mode, /* SIOCGIWMODE */
1141 r8192_wx_set_sens, /* SIOCSIWSENS */
1142 r8192_wx_get_sens, /* SIOCGIWSENS */
1143 NULL, /* SIOCSIWRANGE */
1144 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1145 NULL, /* SIOCSIWPRIV */
1146 NULL, /* SIOCGIWPRIV */
1147 NULL, /* SIOCSIWSTATS */
1148 NULL, /* SIOCGIWSTATS */
1149 dummy, /* SIOCSIWSPY */
1150 dummy, /* SIOCGIWSPY */
1151 NULL, /* SIOCGIWTHRSPY */
1152 NULL, /* SIOCWIWTHRSPY */
1153 r8192_wx_set_wap, /* SIOCSIWAP */
1154 r8192_wx_get_wap, /* SIOCGIWAP */
1155 #if (WIRELESS_EXT >= 18)
1156 r8192_wx_set_mlme, /* MLME-- */
1157 #else
1158 NULL,
1159 #endif
1160 dummy, /* SIOCGIWAPLIST -- depricated */
1161 r8192_wx_set_scan, /* SIOCSIWSCAN */
1162 r8192_wx_get_scan, /* SIOCGIWSCAN */
1163 r8192_wx_set_essid, /* SIOCSIWESSID */
1164 r8192_wx_get_essid, /* SIOCGIWESSID */
1165 dummy, /* SIOCSIWNICKN */
1166 dummy, /* SIOCGIWNICKN */
1167 NULL, /* -- hole -- */
1168 NULL, /* -- hole -- */
1169 r8192_wx_set_rate, /* SIOCSIWRATE */
1170 r8192_wx_get_rate, /* SIOCGIWRATE */
1171 r8192_wx_set_rts, /* SIOCSIWRTS */
1172 r8192_wx_get_rts, /* SIOCGIWRTS */
1173 r8192_wx_set_frag, /* SIOCSIWFRAG */
1174 r8192_wx_get_frag, /* SIOCGIWFRAG */
1175 dummy, /* SIOCSIWTXPOW */
1176 dummy, /* SIOCGIWTXPOW */
1177 r8192_wx_set_retry, /* SIOCSIWRETRY */
1178 r8192_wx_get_retry, /* SIOCGIWRETRY */
1179 r8192_wx_set_enc, /* SIOCSIWENCODE */
1180 r8192_wx_get_enc, /* SIOCGIWENCODE */
1181 r8192_wx_set_power, /* SIOCSIWPOWER */
1182 r8192_wx_get_power, /* SIOCGIWPOWER */
1183 NULL, /*---hole---*/
1184 NULL, /*---hole---*/
1185 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1186 NULL, /* SIOCSIWGENIE */
1188 #if (WIRELESS_EXT >= 18)
1189 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1190 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1191 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1192 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1193 #else
1194 NULL,
1195 NULL,
1196 NULL,
1197 NULL,
1198 #endif
1199 NULL, /* SIOCSIWPMKSA */
1200 NULL, /*---hole---*/
1205 static const struct iw_priv_args r8192_private_args[] = {
1208 SIOCIWFIRSTPRIV + 0x0,
1209 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1213 SIOCIWFIRSTPRIV + 0x1,
1214 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1218 SIOCIWFIRSTPRIV + 0x2,
1219 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1221 #ifdef JOHN_IOCTL
1224 SIOCIWFIRSTPRIV + 0x3,
1225 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1229 SIOCIWFIRSTPRIV + 0x4,
1230 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1234 SIOCIWFIRSTPRIV + 0x5,
1235 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1239 SIOCIWFIRSTPRIV + 0x6,
1240 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1244 SIOCIWFIRSTPRIV + 0x7,
1245 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1249 SIOCIWFIRSTPRIV + 0x8,
1250 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1254 SIOCIWFIRSTPRIV + 0x9,
1255 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1258 #endif
1261 SIOCIWFIRSTPRIV + 0x3,
1262 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1265 #ifdef RTL8192SU
1268 SIOCIWFIRSTPRIV + 0x5,
1269 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
1270 "firm_ver"
1272 #endif
1276 static iw_handler r8192_private_handler[] = {
1277 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1278 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1279 // r8192_wx_set_forceassociate,
1280 // r8192_wx_set_beaconinterval,
1281 // r8192_wx_set_monitor_type,
1282 r8192_wx_set_scan_type,
1283 r8192_wx_set_rawtx,
1284 #ifdef JOHN_IOCTL
1285 r8192_wx_read_regs,
1286 r8192_wx_write_regs,
1287 r8192_wx_read_bb,
1288 r8192_wx_write_bb,
1289 r8192_wx_read_nicb,
1290 r8192_wx_write_nicb,
1291 r8192_wx_get_ap_status,
1292 #endif
1293 r8192_wx_force_reset,
1294 (iw_handler)NULL,
1295 #ifdef RTL8192SU
1296 (iw_handler)r8191su_wx_get_firm_version,
1297 #endif
1300 //#if WIRELESS_EXT >= 17
1301 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1303 struct r8192_priv *priv = ieee80211_priv(dev);
1304 struct ieee80211_device* ieee = priv->ieee80211;
1305 struct iw_statistics* wstats = &priv->wstats;
1306 int tmp_level = 0;
1307 int tmp_qual = 0;
1308 int tmp_noise = 0;
1309 if(ieee->state < IEEE80211_LINKED)
1311 wstats->qual.qual = 0;
1312 wstats->qual.level = 0;
1313 wstats->qual.noise = 0;
1314 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1315 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1316 #else
1317 wstats->qual.updated = 0x0f;
1318 #endif
1319 return wstats;
1322 tmp_level = (&ieee->current_network)->stats.rssi;
1323 tmp_qual = (&ieee->current_network)->stats.signal;
1324 tmp_noise = (&ieee->current_network)->stats.noise;
1325 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1327 wstats->qual.level = tmp_level;
1328 wstats->qual.qual = tmp_qual;
1329 wstats->qual.noise = tmp_noise;
1330 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
1331 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1332 #else
1333 wstats->qual.updated = 0x0f;
1334 #endif
1335 return wstats;
1337 //#endif
1340 struct iw_handler_def r8192_wx_handlers_def={
1341 .standard = r8192_wx_handlers,
1342 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1343 .private = r8192_private_handler,
1344 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1345 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1346 #if WIRELESS_EXT >= 17
1347 .get_wireless_stats = r8192_get_wireless_stats,
1348 #endif
1349 .private_args = (struct iw_priv_args *)r8192_private_args,