Linux 2.6.33.13
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8192e / r8192E_wx.c
blobd1eb89229cdf43119d0c00078bc31ab34ed327ad
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 "r8192E.h"
22 #include "r8192E_hw.h"
23 #include "r8192E_wx.h"
24 #ifdef ENABLE_DOT11D
25 #include "dot11d.h"
26 #endif
28 #define RATE_COUNT 12
29 static u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
30 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
33 #ifndef ENETDOWN
34 #define ENETDOWN 1
35 #endif
36 static int r8192_wx_get_freq(struct net_device *dev,
37 struct iw_request_info *a,
38 union iwreq_data *wrqu, char *b)
40 struct r8192_priv *priv = ieee80211_priv(dev);
42 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47 union iwreq_data *wrqu, char *b)
49 struct r8192_priv *priv=ieee80211_priv(dev);
51 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
56 static int r8192_wx_get_rate(struct net_device *dev,
57 struct iw_request_info *info,
58 union iwreq_data *wrqu, char *extra)
60 struct r8192_priv *priv = ieee80211_priv(dev);
61 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
66 static int r8192_wx_set_rate(struct net_device *dev,
67 struct iw_request_info *info,
68 union iwreq_data *wrqu, char *extra)
70 int ret;
71 struct r8192_priv *priv = ieee80211_priv(dev);
73 down(&priv->wx_sem);
75 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
77 up(&priv->wx_sem);
79 return ret;
83 static int r8192_wx_set_rts(struct net_device *dev,
84 struct iw_request_info *info,
85 union iwreq_data *wrqu, char *extra)
87 int ret;
88 struct r8192_priv *priv = ieee80211_priv(dev);
90 down(&priv->wx_sem);
92 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
94 up(&priv->wx_sem);
96 return ret;
99 static int r8192_wx_get_rts(struct net_device *dev,
100 struct iw_request_info *info,
101 union iwreq_data *wrqu, char *extra)
103 struct r8192_priv *priv = ieee80211_priv(dev);
104 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
107 static int r8192_wx_set_power(struct net_device *dev,
108 struct iw_request_info *info,
109 union iwreq_data *wrqu, char *extra)
111 int ret;
112 struct r8192_priv *priv = ieee80211_priv(dev);
114 down(&priv->wx_sem);
116 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
118 up(&priv->wx_sem);
120 return ret;
123 static int r8192_wx_get_power(struct net_device *dev,
124 struct iw_request_info *info,
125 union iwreq_data *wrqu, char *extra)
127 struct r8192_priv *priv = ieee80211_priv(dev);
128 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
131 #ifdef JOHN_IOCTL
132 u16 read_rtl8225(struct net_device *dev, u8 addr);
133 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
134 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
135 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
137 static int r8192_wx_read_regs(struct net_device *dev,
138 struct iw_request_info *info,
139 union iwreq_data *wrqu, char *extra)
141 struct r8192_priv *priv = ieee80211_priv(dev);
142 u8 addr;
143 u16 data1;
145 down(&priv->wx_sem);
148 get_user(addr,(u8*)wrqu->data.pointer);
149 data1 = read_rtl8225(dev, addr);
150 wrqu->data.length = data1;
152 up(&priv->wx_sem);
153 return 0;
157 static int r8192_wx_write_regs(struct net_device *dev,
158 struct iw_request_info *info,
159 union iwreq_data *wrqu, char *extra)
161 struct r8192_priv *priv = ieee80211_priv(dev);
162 u8 addr;
164 down(&priv->wx_sem);
166 get_user(addr, (u8*)wrqu->data.pointer);
167 write_rtl8225(dev, addr, wrqu->data.length);
169 up(&priv->wx_sem);
170 return 0;
174 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
175 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
177 static int r8192_wx_read_bb(struct net_device *dev,
178 struct iw_request_info *info,
179 union iwreq_data *wrqu, char *extra)
181 struct r8192_priv *priv = ieee80211_priv(dev);
182 u8 databb;
183 #if 0
184 int i;
185 for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
186 #endif
188 down(&priv->wx_sem);
190 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
191 wrqu->data.length = databb;
193 up(&priv->wx_sem);
194 return 0;
197 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
198 static int r8192_wx_write_bb(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 databb;
205 down(&priv->wx_sem);
207 get_user(databb, (u8*)wrqu->data.pointer);
208 rtl8187_write_phy(dev, wrqu->data.length, databb);
210 up(&priv->wx_sem);
211 return 0;
216 static int r8192_wx_write_nicb(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 u32 addr;
223 down(&priv->wx_sem);
225 get_user(addr, (u32*)wrqu->data.pointer);
226 write_nic_byte(dev, addr, wrqu->data.length);
228 up(&priv->wx_sem);
229 return 0;
232 static int r8192_wx_read_nicb(struct net_device *dev,
233 struct iw_request_info *info,
234 union iwreq_data *wrqu, char *extra)
236 struct r8192_priv *priv = ieee80211_priv(dev);
237 u32 addr;
238 u16 data1;
240 down(&priv->wx_sem);
242 get_user(addr,(u32*)wrqu->data.pointer);
243 data1 = read_nic_byte(dev, addr);
244 wrqu->data.length = data1;
246 up(&priv->wx_sem);
247 return 0;
250 static int r8192_wx_get_ap_status(struct net_device *dev,
251 struct iw_request_info *info,
252 union iwreq_data *wrqu, char *extra)
254 struct r8192_priv *priv = ieee80211_priv(dev);
255 struct ieee80211_device *ieee = priv->ieee80211;
256 struct ieee80211_network *target;
257 int name_len;
259 down(&priv->wx_sem);
261 //count the length of input ssid
262 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
264 //search for the correspoding info which is received
265 list_for_each_entry(target, &ieee->network_list, list) {
266 if ( (target->ssid_len == name_len) &&
267 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
268 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
269 //set flags=1 to indicate this ap is WPA
270 wrqu->data.flags = 1;
271 else wrqu->data.flags = 0;
274 break;
278 up(&priv->wx_sem);
279 return 0;
284 #endif
286 static int r8192_wx_set_rawtx(struct net_device *dev,
287 struct iw_request_info *info,
288 union iwreq_data *wrqu, char *extra)
290 struct r8192_priv *priv = ieee80211_priv(dev);
291 int ret;
293 down(&priv->wx_sem);
295 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
297 up(&priv->wx_sem);
299 return ret;
303 static int r8192_wx_force_reset(struct net_device *dev,
304 struct iw_request_info *info,
305 union iwreq_data *wrqu, char *extra)
307 struct r8192_priv *priv = ieee80211_priv(dev);
309 down(&priv->wx_sem);
311 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
312 priv->force_reset = *extra;
313 up(&priv->wx_sem);
314 return 0;
319 static int r8192_wx_set_crcmon(struct net_device *dev,
320 struct iw_request_info *info,
321 union iwreq_data *wrqu, char *extra)
323 struct r8192_priv *priv = ieee80211_priv(dev);
324 int *parms = (int *)extra;
325 int enable = (parms[0] > 0);
326 short prev = priv->crcmon;
328 down(&priv->wx_sem);
330 if(enable)
331 priv->crcmon=1;
332 else
333 priv->crcmon=0;
335 DMESG("bad CRC in monitor mode are %s",
336 priv->crcmon ? "accepted" : "rejected");
338 if(prev != priv->crcmon && priv->up){
339 //rtl8180_down(dev);
340 //rtl8180_up(dev);
343 up(&priv->wx_sem);
345 return 0;
348 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
349 union iwreq_data *wrqu, char *b)
351 struct r8192_priv *priv = ieee80211_priv(dev);
352 RT_RF_POWER_STATE rtState;
353 int ret;
355 rtState = priv->ieee80211->eRFPowerState;
356 down(&priv->wx_sem);
357 #ifdef ENABLE_IPS
358 if(wrqu->mode == IW_MODE_ADHOC){
360 if(priv->ieee80211->PowerSaveControl.bInactivePs){
361 if(rtState == eRfOff){
362 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
364 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
365 up(&priv->wx_sem);
366 return -1;
368 else{
369 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
370 IPSLeave(dev);
375 #endif
376 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
378 //rtl8187_set_rxconf(dev);
380 up(&priv->wx_sem);
381 return ret;
384 struct iw_range_with_scan_capa
386 /* Informative stuff (to choose between different interface) */
387 __u32 throughput; /* To give an idea... */
388 /* In theory this value should be the maximum benchmarked
389 * TCP/IP throughput, because with most of these devices the
390 * bit rate is meaningless (overhead an co) to estimate how
391 * fast the connection will go and pick the fastest one.
392 * I suggest people to play with Netperf or any benchmark...
395 /* NWID (or domain id) */
396 __u32 min_nwid; /* Minimal NWID we are able to set */
397 __u32 max_nwid; /* Maximal NWID we are able to set */
399 /* Old Frequency (backward compat - moved lower ) */
400 __u16 old_num_channels;
401 __u8 old_num_frequency;
403 /* Scan capabilities */
404 __u8 scan_capa;
406 static int rtl8180_wx_get_range(struct net_device *dev,
407 struct iw_request_info *info,
408 union iwreq_data *wrqu, char *extra)
410 struct iw_range *range = (struct iw_range *)extra;
411 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
412 struct r8192_priv *priv = ieee80211_priv(dev);
413 u16 val;
414 int i;
416 wrqu->data.length = sizeof(*range);
417 memset(range, 0, sizeof(*range));
419 /* Let's try to keep this struct in the same order as in
420 * linux/include/wireless.h
423 /* TODO: See what values we can set, and remove the ones we can't
424 * set, or fill them with some default data.
427 /* ~5 Mb/s real (802.11b) */
428 range->throughput = 5 * 1000 * 1000;
430 // TODO: Not used in 802.11b?
431 // range->min_nwid; /* Minimal NWID we are able to set */
432 // TODO: Not used in 802.11b?
433 // range->max_nwid; /* Maximal NWID we are able to set */
435 /* Old Frequency (backward compat - moved lower ) */
436 // range->old_num_channels;
437 // range->old_num_frequency;
438 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
439 if(priv->rf_set_sens != NULL)
440 range->sensitivity = priv->max_sens; /* signal level threshold range */
442 range->max_qual.qual = 100;
443 /* TODO: Find real max RSSI and stick here */
444 range->max_qual.level = 0;
445 range->max_qual.noise = -98;
446 range->max_qual.updated = 7; /* Updated all three */
448 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
449 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
450 range->avg_qual.level = 20 + -98;
451 range->avg_qual.noise = 0;
452 range->avg_qual.updated = 7; /* Updated all three */
454 range->num_bitrates = RATE_COUNT;
456 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
457 range->bitrate[i] = rtl8180_rates[i];
460 range->min_frag = MIN_FRAG_THRESHOLD;
461 range->max_frag = MAX_FRAG_THRESHOLD;
463 range->min_pmp=0;
464 range->max_pmp = 5000000;
465 range->min_pmt = 0;
466 range->max_pmt = 65535*1000;
467 range->pmp_flags = IW_POWER_PERIOD;
468 range->pmt_flags = IW_POWER_TIMEOUT;
469 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
470 range->we_version_compiled = WIRELESS_EXT;
471 range->we_version_source = 16;
473 // range->retry_capa; /* What retry options are supported */
474 // range->retry_flags; /* How to decode max/min retry limit */
475 // range->r_time_flags; /* How to decode max/min retry life */
476 // range->min_retry; /* Minimal number of retries */
477 // range->max_retry; /* Maximal number of retries */
478 // range->min_r_time; /* Minimal retry lifetime */
479 // range->max_r_time; /* Maximal retry lifetime */
482 for (i = 0, val = 0; i < 14; i++) {
484 // Include only legal frequencies for some countries
485 #ifdef ENABLE_DOT11D
486 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
487 #else
488 if ((priv->ieee80211->channel_map)[i+1]) {
489 #endif
490 range->freq[val].i = i + 1;
491 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
492 range->freq[val].e = 1;
493 val++;
494 } else {
495 // FIXME: do we need to set anything for channels
496 // we don't use ?
499 if (val == IW_MAX_FREQUENCIES)
500 break;
502 range->num_frequency = val;
503 range->num_channels = val;
504 #if WIRELESS_EXT > 17
505 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
506 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
507 #endif
508 tmp->scan_capa = 0x01;
509 return 0;
513 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
514 union iwreq_data *wrqu, char *b)
516 struct r8192_priv *priv = ieee80211_priv(dev);
517 struct ieee80211_device* ieee = priv->ieee80211;
518 RT_RF_POWER_STATE rtState;
519 int ret;
520 rtState = priv->ieee80211->eRFPowerState;
521 if(!priv->up) return -ENETDOWN;
522 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
523 return -EAGAIN;
525 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
527 struct iw_scan_req* req = (struct iw_scan_req*)b;
528 if (req->essid_len)
530 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
531 ieee->current_network.ssid_len = req->essid_len;
532 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
533 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
537 down(&priv->wx_sem);
538 #ifdef ENABLE_IPS
539 priv->ieee80211->actscanning = true;
540 if(priv->ieee80211->state != IEEE80211_LINKED){
541 if(priv->ieee80211->PowerSaveControl.bInactivePs){
542 if(rtState == eRfOff){
543 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
545 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
546 up(&priv->wx_sem);
547 return -1;
549 else{
550 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
551 IPSLeave(dev);
555 priv->ieee80211->scanning = 0;
556 ieee80211_softmac_scan_syncro(priv->ieee80211);
557 ret = 0;
559 else
560 #else
562 if(priv->ieee80211->state != IEEE80211_LINKED){
563 priv->ieee80211->scanning = 0;
564 ieee80211_softmac_scan_syncro(priv->ieee80211);
565 ret = 0;
567 else
568 #endif
569 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
571 up(&priv->wx_sem);
572 return ret;
576 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
577 union iwreq_data *wrqu, char *b)
580 int ret;
581 struct r8192_priv *priv = ieee80211_priv(dev);
583 if(!priv->up) return -ENETDOWN;
585 down(&priv->wx_sem);
587 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
589 up(&priv->wx_sem);
591 return ret;
594 static int r8192_wx_set_essid(struct net_device *dev,
595 struct iw_request_info *a,
596 union iwreq_data *wrqu, char *b)
598 struct r8192_priv *priv = ieee80211_priv(dev);
599 RT_RF_POWER_STATE rtState;
600 int ret;
602 rtState = priv->ieee80211->eRFPowerState;
603 down(&priv->wx_sem);
604 #ifdef ENABLE_IPS
605 if(priv->ieee80211->PowerSaveControl.bInactivePs){
606 if(rtState == eRfOff){
607 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
609 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
610 up(&priv->wx_sem);
611 return -1;
613 else{
614 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
615 IPSLeave(dev);
619 #endif
620 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
622 up(&priv->wx_sem);
624 return ret;
630 static int r8192_wx_get_essid(struct net_device *dev,
631 struct iw_request_info *a,
632 union iwreq_data *wrqu, char *b)
634 int ret;
635 struct r8192_priv *priv = ieee80211_priv(dev);
637 down(&priv->wx_sem);
639 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
641 up(&priv->wx_sem);
643 return ret;
647 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
648 union iwreq_data *wrqu, char *b)
650 int ret;
651 struct r8192_priv *priv = ieee80211_priv(dev);
653 down(&priv->wx_sem);
655 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
657 up(&priv->wx_sem);
658 return ret;
661 static int r8192_wx_get_name(struct net_device *dev,
662 struct iw_request_info *info,
663 union iwreq_data *wrqu, char *extra)
665 struct r8192_priv *priv = ieee80211_priv(dev);
666 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
670 static int r8192_wx_set_frag(struct net_device *dev,
671 struct iw_request_info *info,
672 union iwreq_data *wrqu, char *extra)
674 struct r8192_priv *priv = ieee80211_priv(dev);
676 if (wrqu->frag.disabled)
677 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
678 else {
679 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
680 wrqu->frag.value > MAX_FRAG_THRESHOLD)
681 return -EINVAL;
683 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
686 return 0;
690 static int r8192_wx_get_frag(struct net_device *dev,
691 struct iw_request_info *info,
692 union iwreq_data *wrqu, char *extra)
694 struct r8192_priv *priv = ieee80211_priv(dev);
696 wrqu->frag.value = priv->ieee80211->fts;
697 wrqu->frag.fixed = 0; /* no auto select */
698 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
700 return 0;
704 static int r8192_wx_set_wap(struct net_device *dev,
705 struct iw_request_info *info,
706 union iwreq_data *awrq,
707 char *extra)
710 int ret;
711 struct r8192_priv *priv = ieee80211_priv(dev);
712 // struct sockaddr *temp = (struct sockaddr *)awrq;
714 down(&priv->wx_sem);
716 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
718 up(&priv->wx_sem);
720 return ret;
725 static int r8192_wx_get_wap(struct net_device *dev,
726 struct iw_request_info *info,
727 union iwreq_data *wrqu, char *extra)
729 struct r8192_priv *priv = ieee80211_priv(dev);
731 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
735 static int r8192_wx_get_enc(struct net_device *dev,
736 struct iw_request_info *info,
737 union iwreq_data *wrqu, char *key)
739 struct r8192_priv *priv = ieee80211_priv(dev);
741 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
744 static int r8192_wx_set_enc(struct net_device *dev,
745 struct iw_request_info *info,
746 union iwreq_data *wrqu, char *key)
748 struct r8192_priv *priv = ieee80211_priv(dev);
749 int ret;
751 struct ieee80211_device *ieee = priv->ieee80211;
752 //u32 TargetContent;
753 u32 hwkey[4]={0,0,0,0};
754 u8 mask=0xff;
755 u32 key_idx=0;
756 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
757 {0x00,0x00,0x00,0x00,0x00,0x01},
758 {0x00,0x00,0x00,0x00,0x00,0x02},
759 {0x00,0x00,0x00,0x00,0x00,0x03} };
760 int i;
762 if(!priv->up) return -ENETDOWN;
764 down(&priv->wx_sem);
766 RT_TRACE(COMP_SEC, "Setting SW wep key");
767 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
769 up(&priv->wx_sem);
772 //sometimes, the length is zero while we do not type key value
773 if(wrqu->encoding.length!=0){
775 for(i=0 ; i<4 ; i++){
776 hwkey[i] |= key[4*i+0]&mask;
777 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
778 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
779 hwkey[i] |= (key[4*i+1]&mask)<<8;
780 hwkey[i] |= (key[4*i+2]&mask)<<16;
781 hwkey[i] |= (key[4*i+3]&mask)<<24;
784 #define CONF_WEP40 0x4
785 #define CONF_WEP104 0x14
787 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
788 case 0: key_idx = ieee->tx_keyidx; break;
789 case 1: key_idx = 0; break;
790 case 2: key_idx = 1; break;
791 case 3: key_idx = 2; break;
792 case 4: key_idx = 3; break;
793 default: break;
796 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
797 if(wrqu->encoding.length==0x5){
798 ieee->pairwise_key_type = KEY_TYPE_WEP40;
799 EnableHWSecurityConfig8192(dev);
800 setKey( dev,
801 key_idx, //EntryNo
802 key_idx, //KeyIndex
803 KEY_TYPE_WEP40, //KeyType
804 zero_addr[key_idx],
805 0, //DefaultKey
806 hwkey); //KeyContent
808 #if 0
809 if(key_idx == 0){
811 //write_nic_byte(dev, SECR, 7);
812 setKey( dev,
813 4, //EntryNo
814 key_idx, //KeyIndex
815 KEY_TYPE_WEP40, //KeyType
816 broadcast_addr, //addr
817 0, //DefaultKey
818 hwkey); //KeyContent
820 #endif
823 else if(wrqu->encoding.length==0xd){
824 ieee->pairwise_key_type = KEY_TYPE_WEP104;
825 EnableHWSecurityConfig8192(dev);
826 setKey( dev,
827 key_idx, //EntryNo
828 key_idx, //KeyIndex
829 KEY_TYPE_WEP104, //KeyType
830 zero_addr[key_idx],
831 0, //DefaultKey
832 hwkey); //KeyContent
833 #if 0
834 if(key_idx == 0){
836 //write_nic_byte(dev, SECR, 7);
837 setKey( dev,
838 4, //EntryNo
839 key_idx, //KeyIndex
840 KEY_TYPE_WEP104, //KeyType
841 broadcast_addr, //addr
842 0, //DefaultKey
843 hwkey); //KeyContent
845 #endif
847 else printk("wrong type in WEP, not WEP40 and WEP104\n");
852 #if 0
853 //consider the setting different key index situation
854 //wrqu->encoding.flags = 801 means that we set key with index "1"
855 if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
856 printk("===>1\n");
857 //write_nic_byte(dev, SECR, 7);
858 EnableHWSecurityConfig8192(dev);
859 //copy wpa config from default key(key0~key3) to broadcast key(key5)
861 key_idx = (wrqu->encoding.flags & 0xf)-1 ;
862 write_cam(dev, (4*6), 0xffff0000|read_cam(dev, key_idx*6) );
863 write_cam(dev, (4*6)+1, 0xffffffff);
864 write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
865 write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
866 write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
867 write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
869 #endif
871 return ret;
875 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
876 iwreq_data *wrqu, char *p){
878 struct r8192_priv *priv = ieee80211_priv(dev);
879 int *parms=(int*)p;
880 int mode=parms[0];
882 priv->ieee80211->active_scan = mode;
884 return 1;
889 static int r8192_wx_set_retry(struct net_device *dev,
890 struct iw_request_info *info,
891 union iwreq_data *wrqu, char *extra)
893 struct r8192_priv *priv = ieee80211_priv(dev);
894 int err = 0;
896 down(&priv->wx_sem);
898 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
899 wrqu->retry.disabled){
900 err = -EINVAL;
901 goto exit;
903 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
904 err = -EINVAL;
905 goto exit;
908 if(wrqu->retry.value > R8180_MAX_RETRY){
909 err= -EINVAL;
910 goto exit;
912 if (wrqu->retry.flags & IW_RETRY_MAX) {
913 priv->retry_rts = wrqu->retry.value;
914 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
916 }else {
917 priv->retry_data = wrqu->retry.value;
918 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
921 /* FIXME !
922 * We might try to write directly the TX config register
923 * or to restart just the (R)TX process.
924 * I'm unsure if whole reset is really needed
927 rtl8192_commit(dev);
929 if(priv->up){
930 rtl8180_rtx_disable(dev);
931 rtl8180_rx_enable(dev);
932 rtl8180_tx_enable(dev);
936 exit:
937 up(&priv->wx_sem);
939 return err;
942 static int r8192_wx_get_retry(struct net_device *dev,
943 struct iw_request_info *info,
944 union iwreq_data *wrqu, char *extra)
946 struct r8192_priv *priv = ieee80211_priv(dev);
949 wrqu->retry.disabled = 0; /* can't be disabled */
951 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
952 IW_RETRY_LIFETIME)
953 return -EINVAL;
955 if (wrqu->retry.flags & IW_RETRY_MAX) {
956 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
957 wrqu->retry.value = priv->retry_rts;
958 } else {
959 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
960 wrqu->retry.value = priv->retry_data;
962 //DMESG("returning %d",wrqu->retry.value);
965 return 0;
968 static int r8192_wx_get_sens(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 if(priv->rf_set_sens == NULL)
974 return -1; /* we have not this support for this radio */
975 wrqu->sens.value = priv->sens;
976 return 0;
980 static int r8192_wx_set_sens(struct net_device *dev,
981 struct iw_request_info *info,
982 union iwreq_data *wrqu, char *extra)
985 struct r8192_priv *priv = ieee80211_priv(dev);
987 short err = 0;
988 down(&priv->wx_sem);
989 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
990 if(priv->rf_set_sens == NULL) {
991 err= -1; /* we have not this support for this radio */
992 goto exit;
994 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
995 priv->sens = wrqu->sens.value;
996 else
997 err= -EINVAL;
999 exit:
1000 up(&priv->wx_sem);
1002 return err;
1005 #if (WIRELESS_EXT >= 18)
1006 static int r8192_wx_set_enc_ext(struct net_device *dev,
1007 struct iw_request_info *info,
1008 union iwreq_data *wrqu, char *extra)
1010 int ret=0;
1011 struct r8192_priv *priv = ieee80211_priv(dev);
1012 struct ieee80211_device* ieee = priv->ieee80211;
1014 down(&priv->wx_sem);
1015 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
1018 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
1019 u8 zero[6] = {0};
1020 u32 key[4] = {0};
1021 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1022 struct iw_point *encoding = &wrqu->encoding;
1023 #if 0
1024 static u8 CAM_CONST_ADDR[4][6] = {
1025 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1026 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
1027 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
1028 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
1029 #endif
1030 u8 idx = 0, alg = 0, group = 0;
1031 if ((encoding->flags & IW_ENCODE_DISABLED) ||
1032 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
1034 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
1035 CamResetAllEntry(dev);
1036 goto end_hw_sec;
1038 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;
1039 idx = encoding->flags & IW_ENCODE_INDEX;
1040 if (idx)
1041 idx --;
1042 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1044 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
1046 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
1047 alg = KEY_TYPE_WEP104;
1048 ieee->pairwise_key_type = alg;
1049 EnableHWSecurityConfig8192(dev);
1051 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
1053 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
1055 if (ext->key_len == 13)
1056 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1057 setKey( dev,
1058 idx,//EntryNo
1059 idx, //KeyIndex
1060 alg, //KeyType
1061 zero, //MacAddr
1062 0, //DefaultKey
1063 key); //KeyContent
1065 else if (group)
1067 ieee->group_key_type = alg;
1068 setKey( dev,
1069 idx,//EntryNo
1070 idx, //KeyIndex
1071 alg, //KeyType
1072 broadcast_addr, //MacAddr
1073 0, //DefaultKey
1074 key); //KeyContent
1076 else //pairwise key
1078 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
1079 write_nic_byte(dev, 0x173, 1); //fix aes bug
1081 setKey( dev,
1082 4,//EntryNo
1083 idx, //KeyIndex
1084 alg, //KeyType
1085 (u8*)ieee->ap_mac_addr, //MacAddr
1086 0, //DefaultKey
1087 key); //KeyContent
1093 end_hw_sec:
1094 up(&priv->wx_sem);
1095 return ret;
1098 static int r8192_wx_set_auth(struct net_device *dev,
1099 struct iw_request_info *info,
1100 union iwreq_data *data, char *extra)
1102 int ret=0;
1103 //printk("====>%s()\n", __FUNCTION__);
1104 struct r8192_priv *priv = ieee80211_priv(dev);
1105 down(&priv->wx_sem);
1106 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1107 up(&priv->wx_sem);
1108 return ret;
1111 static int r8192_wx_set_mlme(struct net_device *dev,
1112 struct iw_request_info *info,
1113 union iwreq_data *wrqu, char *extra)
1115 //printk("====>%s()\n", __FUNCTION__);
1117 int ret=0;
1118 struct r8192_priv *priv = ieee80211_priv(dev);
1119 down(&priv->wx_sem);
1120 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1121 up(&priv->wx_sem);
1122 return ret;
1124 #endif
1125 static int r8192_wx_set_gen_ie(struct net_device *dev,
1126 struct iw_request_info *info,
1127 union iwreq_data *data, char *extra)
1129 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1130 int ret=0;
1131 struct r8192_priv *priv = ieee80211_priv(dev);
1132 down(&priv->wx_sem);
1133 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1134 up(&priv->wx_sem);
1135 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1136 return ret;
1139 static int dummy(struct net_device *dev, struct iw_request_info *a,
1140 union iwreq_data *wrqu,char *b)
1142 return -1;
1146 static iw_handler r8192_wx_handlers[] =
1148 NULL, /* SIOCSIWCOMMIT */
1149 r8192_wx_get_name, /* SIOCGIWNAME */
1150 dummy, /* SIOCSIWNWID */
1151 dummy, /* SIOCGIWNWID */
1152 r8192_wx_set_freq, /* SIOCSIWFREQ */
1153 r8192_wx_get_freq, /* SIOCGIWFREQ */
1154 r8192_wx_set_mode, /* SIOCSIWMODE */
1155 r8192_wx_get_mode, /* SIOCGIWMODE */
1156 r8192_wx_set_sens, /* SIOCSIWSENS */
1157 r8192_wx_get_sens, /* SIOCGIWSENS */
1158 NULL, /* SIOCSIWRANGE */
1159 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1160 NULL, /* SIOCSIWPRIV */
1161 NULL, /* SIOCGIWPRIV */
1162 NULL, /* SIOCSIWSTATS */
1163 NULL, /* SIOCGIWSTATS */
1164 dummy, /* SIOCSIWSPY */
1165 dummy, /* SIOCGIWSPY */
1166 NULL, /* SIOCGIWTHRSPY */
1167 NULL, /* SIOCWIWTHRSPY */
1168 r8192_wx_set_wap, /* SIOCSIWAP */
1169 r8192_wx_get_wap, /* SIOCGIWAP */
1170 #if (WIRELESS_EXT >= 18)
1171 r8192_wx_set_mlme, /* MLME-- */
1172 #else
1173 NULL,
1174 #endif
1175 dummy, /* SIOCGIWAPLIST -- depricated */
1176 r8192_wx_set_scan, /* SIOCSIWSCAN */
1177 r8192_wx_get_scan, /* SIOCGIWSCAN */
1178 r8192_wx_set_essid, /* SIOCSIWESSID */
1179 r8192_wx_get_essid, /* SIOCGIWESSID */
1180 dummy, /* SIOCSIWNICKN */
1181 dummy, /* SIOCGIWNICKN */
1182 NULL, /* -- hole -- */
1183 NULL, /* -- hole -- */
1184 r8192_wx_set_rate, /* SIOCSIWRATE */
1185 r8192_wx_get_rate, /* SIOCGIWRATE */
1186 r8192_wx_set_rts, /* SIOCSIWRTS */
1187 r8192_wx_get_rts, /* SIOCGIWRTS */
1188 r8192_wx_set_frag, /* SIOCSIWFRAG */
1189 r8192_wx_get_frag, /* SIOCGIWFRAG */
1190 dummy, /* SIOCSIWTXPOW */
1191 dummy, /* SIOCGIWTXPOW */
1192 r8192_wx_set_retry, /* SIOCSIWRETRY */
1193 r8192_wx_get_retry, /* SIOCGIWRETRY */
1194 r8192_wx_set_enc, /* SIOCSIWENCODE */
1195 r8192_wx_get_enc, /* SIOCGIWENCODE */
1196 r8192_wx_set_power, /* SIOCSIWPOWER */
1197 r8192_wx_get_power, /* SIOCGIWPOWER */
1198 NULL, /*---hole---*/
1199 NULL, /*---hole---*/
1200 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1201 NULL, /* SIOCSIWGENIE */
1202 #if (WIRELESS_EXT >= 18)
1203 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1204 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1205 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1206 #else
1207 NULL,
1208 NULL,
1209 NULL,
1210 #endif
1211 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1212 NULL, /* SIOCSIWPMKSA */
1213 NULL, /*---hole---*/
1218 static const struct iw_priv_args r8192_private_args[] = {
1221 SIOCIWFIRSTPRIV + 0x0,
1222 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1226 SIOCIWFIRSTPRIV + 0x1,
1227 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1231 SIOCIWFIRSTPRIV + 0x2,
1232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1234 #ifdef JOHN_IOCTL
1237 SIOCIWFIRSTPRIV + 0x3,
1238 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1242 SIOCIWFIRSTPRIV + 0x4,
1243 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1247 SIOCIWFIRSTPRIV + 0x5,
1248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1252 SIOCIWFIRSTPRIV + 0x6,
1253 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1257 SIOCIWFIRSTPRIV + 0x7,
1258 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1262 SIOCIWFIRSTPRIV + 0x8,
1263 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1267 SIOCIWFIRSTPRIV + 0x9,
1268 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1271 #endif
1274 SIOCIWFIRSTPRIV + 0x3,
1275 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1282 static iw_handler r8192_private_handler[] = {
1283 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1284 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1285 // r8192_wx_set_forceassociate,
1286 // r8192_wx_set_beaconinterval,
1287 // r8192_wx_set_monitor_type,
1288 r8192_wx_set_scan_type,
1289 r8192_wx_set_rawtx,
1290 #ifdef JOHN_IOCTL
1291 r8192_wx_read_regs,
1292 r8192_wx_write_regs,
1293 r8192_wx_read_bb,
1294 r8192_wx_write_bb,
1295 r8192_wx_read_nicb,
1296 r8192_wx_write_nicb,
1297 r8192_wx_get_ap_status
1298 #endif
1299 r8192_wx_force_reset,
1302 //#if WIRELESS_EXT >= 17
1303 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1305 struct r8192_priv *priv = ieee80211_priv(dev);
1306 struct ieee80211_device* ieee = priv->ieee80211;
1307 struct iw_statistics* wstats = &priv->wstats;
1308 int tmp_level = 0;
1309 int tmp_qual = 0;
1310 int tmp_noise = 0;
1311 if(ieee->state < IEEE80211_LINKED)
1313 wstats->qual.qual = 0;
1314 wstats->qual.level = 0;
1315 wstats->qual.noise = 0;
1316 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1317 return wstats;
1320 tmp_level = (&ieee->current_network)->stats.rssi;
1321 tmp_qual = (&ieee->current_network)->stats.signal;
1322 tmp_noise = (&ieee->current_network)->stats.noise;
1323 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1325 wstats->qual.level = tmp_level;
1326 wstats->qual.qual = tmp_qual;
1327 wstats->qual.noise = tmp_noise;
1328 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1329 return wstats;
1331 //#endif
1334 struct iw_handler_def r8192_wx_handlers_def={
1335 .standard = r8192_wx_handlers,
1336 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1337 .private = r8192_private_handler,
1338 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1339 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1340 #if WIRELESS_EXT >= 17
1341 .get_wireless_stats = r8192_get_wireless_stats,
1342 #endif
1343 .private_args = (struct iw_priv_args *)r8192_private_args,