staging: rtl8192e: Pass priv to TranslateRxSignalStuff819xpci
[deliverable/linux.git] / drivers / staging / rtl8192e / r8192E_wx.c
1 /*
2 This file contains wireless extension handlers.
3
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)
7
8 Parts of this driver are based on the GPL part
9 of the official realtek driver.
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon.
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 We want to tanks the Authors of those projects and the Ndiswrapper
17 project Authors.
18 */
19
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 "ieee80211/dot11d.h"
26 #endif
27
28 #define RATE_COUNT 12
29 static const u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
30 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31
32
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)
39 {
40 struct r8192_priv *priv = ieee80211_priv(dev);
41
42 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
43 }
44
45
46 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
47 union iwreq_data *wrqu, char *b)
48 {
49 struct r8192_priv *priv=ieee80211_priv(dev);
50
51 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
52 }
53
54
55
56 static int r8192_wx_get_rate(struct net_device *dev,
57 struct iw_request_info *info,
58 union iwreq_data *wrqu, char *extra)
59 {
60 struct r8192_priv *priv = ieee80211_priv(dev);
61 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
62 }
63
64
65
66 static int r8192_wx_set_rate(struct net_device *dev,
67 struct iw_request_info *info,
68 union iwreq_data *wrqu, char *extra)
69 {
70 int ret;
71 struct r8192_priv *priv = ieee80211_priv(dev);
72
73 if (priv->bHwRadioOff)
74 return 0;
75
76 down(&priv->wx_sem);
77
78 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
79
80 up(&priv->wx_sem);
81
82 return ret;
83 }
84
85
86 static int r8192_wx_set_rts(struct net_device *dev,
87 struct iw_request_info *info,
88 union iwreq_data *wrqu, char *extra)
89 {
90 int ret;
91 struct r8192_priv *priv = ieee80211_priv(dev);
92
93 if (priv->bHwRadioOff)
94 return 0;
95
96 down(&priv->wx_sem);
97
98 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
99
100 up(&priv->wx_sem);
101
102 return ret;
103 }
104
105 static int r8192_wx_get_rts(struct net_device *dev,
106 struct iw_request_info *info,
107 union iwreq_data *wrqu, char *extra)
108 {
109 struct r8192_priv *priv = ieee80211_priv(dev);
110 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
111 }
112
113 static int r8192_wx_set_power(struct net_device *dev,
114 struct iw_request_info *info,
115 union iwreq_data *wrqu, char *extra)
116 {
117 int ret;
118 struct r8192_priv *priv = ieee80211_priv(dev);
119
120 if (priv->bHwRadioOff)
121 return 0;
122
123 down(&priv->wx_sem);
124
125 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
126
127 up(&priv->wx_sem);
128
129 return ret;
130 }
131
132 static int r8192_wx_get_power(struct net_device *dev,
133 struct iw_request_info *info,
134 union iwreq_data *wrqu, char *extra)
135 {
136 struct r8192_priv *priv = ieee80211_priv(dev);
137 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
138 }
139
140 static int r8192_wx_set_rawtx(struct net_device *dev,
141 struct iw_request_info *info,
142 union iwreq_data *wrqu, char *extra)
143 {
144 struct r8192_priv *priv = ieee80211_priv(dev);
145 int ret;
146
147 if (priv->bHwRadioOff)
148 return 0;
149
150 down(&priv->wx_sem);
151
152 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
153
154 up(&priv->wx_sem);
155
156 return ret;
157
158 }
159
160 static int r8192_wx_force_reset(struct net_device *dev,
161 struct iw_request_info *info,
162 union iwreq_data *wrqu, char *extra)
163 {
164 struct r8192_priv *priv = ieee80211_priv(dev);
165
166 down(&priv->wx_sem);
167
168 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
169 priv->force_reset = *extra;
170 up(&priv->wx_sem);
171 return 0;
172
173 }
174
175
176 static int r8192_wx_set_crcmon(struct net_device *dev,
177 struct iw_request_info *info,
178 union iwreq_data *wrqu, char *extra)
179 {
180 struct r8192_priv *priv = ieee80211_priv(dev);
181 int *parms = (int *)extra;
182 int enable = (parms[0] > 0);
183 short prev = priv->crcmon;
184
185 if (priv->bHwRadioOff)
186 return 0;
187
188 down(&priv->wx_sem);
189
190 if(enable)
191 priv->crcmon=1;
192 else
193 priv->crcmon=0;
194
195 DMESG("bad CRC in monitor mode are %s",
196 priv->crcmon ? "accepted" : "rejected");
197
198 if(prev != priv->crcmon && priv->up){
199 //rtl8180_down(dev);
200 //rtl8180_up(dev);
201 }
202
203 up(&priv->wx_sem);
204
205 return 0;
206 }
207
208 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
209 union iwreq_data *wrqu, char *b)
210 {
211 struct r8192_priv *priv = ieee80211_priv(dev);
212 RT_RF_POWER_STATE rtState;
213 int ret;
214
215 if (priv->bHwRadioOff)
216 return 0;
217
218 rtState = priv->eRFPowerState;
219 down(&priv->wx_sem);
220 #ifdef ENABLE_IPS
221 if(wrqu->mode == IW_MODE_ADHOC){
222
223 if (priv->PowerSaveControl.bInactivePs) {
224 if(rtState == eRfOff){
225 if(priv->RfOffReason > RF_CHANGE_BY_IPS)
226 {
227 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
228 up(&priv->wx_sem);
229 return -1;
230 }
231 else{
232 RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
233 down(&priv->ieee80211->ips_sem);
234 IPSLeave(dev);
235 up(&priv->ieee80211->ips_sem);
236 }
237 }
238 }
239 }
240 #endif
241 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
242
243 //rtl8187_set_rxconf(dev);
244
245 up(&priv->wx_sem);
246 return ret;
247 }
248
249 struct iw_range_with_scan_capa
250 {
251 /* Informative stuff (to choose between different interface) */
252 __u32 throughput; /* To give an idea... */
253 /* In theory this value should be the maximum benchmarked
254 * TCP/IP throughput, because with most of these devices the
255 * bit rate is meaningless (overhead an co) to estimate how
256 * fast the connection will go and pick the fastest one.
257 * I suggest people to play with Netperf or any benchmark...
258 */
259
260 /* NWID (or domain id) */
261 __u32 min_nwid; /* Minimal NWID we are able to set */
262 __u32 max_nwid; /* Maximal NWID we are able to set */
263
264 /* Old Frequency (backward compat - moved lower ) */
265 __u16 old_num_channels;
266 __u8 old_num_frequency;
267
268 /* Scan capabilities */
269 __u8 scan_capa;
270 };
271 static int rtl8180_wx_get_range(struct net_device *dev,
272 struct iw_request_info *info,
273 union iwreq_data *wrqu, char *extra)
274 {
275 struct iw_range *range = (struct iw_range *)extra;
276 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
277 struct r8192_priv *priv = ieee80211_priv(dev);
278 u16 val;
279 int i;
280
281 wrqu->data.length = sizeof(*range);
282 memset(range, 0, sizeof(*range));
283
284 /* Let's try to keep this struct in the same order as in
285 * linux/include/wireless.h
286 */
287
288 /* TODO: See what values we can set, and remove the ones we can't
289 * set, or fill them with some default data.
290 */
291
292 /* ~5 Mb/s real (802.11b) */
293 range->throughput = 130 * 1000 * 1000;
294
295 // TODO: Not used in 802.11b?
296 // range->min_nwid; /* Minimal NWID we are able to set */
297 // TODO: Not used in 802.11b?
298 // range->max_nwid; /* Maximal NWID we are able to set */
299
300 /* Old Frequency (backward compat - moved lower ) */
301 // range->old_num_channels;
302 // range->old_num_frequency;
303 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
304
305 range->max_qual.qual = 100;
306 /* TODO: Find real max RSSI and stick here */
307 range->max_qual.level = 0;
308 range->max_qual.noise = -98;
309 range->max_qual.updated = 7; /* Updated all three */
310
311 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
312 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
313 range->avg_qual.level = 20 + -98;
314 range->avg_qual.noise = 0;
315 range->avg_qual.updated = 7; /* Updated all three */
316
317 range->num_bitrates = RATE_COUNT;
318
319 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
320 range->bitrate[i] = rtl8180_rates[i];
321 }
322
323 range->min_frag = MIN_FRAG_THRESHOLD;
324 range->max_frag = MAX_FRAG_THRESHOLD;
325
326 range->min_pmp=0;
327 range->max_pmp = 5000000;
328 range->min_pmt = 0;
329 range->max_pmt = 65535*1000;
330 range->pmp_flags = IW_POWER_PERIOD;
331 range->pmt_flags = IW_POWER_TIMEOUT;
332 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
333 range->we_version_compiled = WIRELESS_EXT;
334 range->we_version_source = 18;
335
336 // range->retry_capa; /* What retry options are supported */
337 // range->retry_flags; /* How to decode max/min retry limit */
338 // range->r_time_flags; /* How to decode max/min retry life */
339 // range->min_retry; /* Minimal number of retries */
340 // range->max_retry; /* Maximal number of retries */
341 // range->min_r_time; /* Minimal retry lifetime */
342 // range->max_r_time; /* Maximal retry lifetime */
343
344
345 for (i = 0, val = 0; i < 14; i++) {
346
347 // Include only legal frequencies for some countries
348 #ifdef ENABLE_DOT11D
349 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
350 #else
351 if ((priv->ieee80211->channel_map)[i+1]) {
352 #endif
353 range->freq[val].i = i + 1;
354 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
355 range->freq[val].e = 1;
356 val++;
357 } else {
358 // FIXME: do we need to set anything for channels
359 // we don't use ?
360 }
361
362 if (val == IW_MAX_FREQUENCIES)
363 break;
364 }
365 range->num_frequency = val;
366 range->num_channels = val;
367
368 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
369 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
370
371 tmp->scan_capa = 0x01;
372 return 0;
373 }
374
375
376 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
377 union iwreq_data *wrqu, char *b)
378 {
379 struct r8192_priv *priv = ieee80211_priv(dev);
380 struct ieee80211_device* ieee = priv->ieee80211;
381 RT_RF_POWER_STATE rtState;
382 int ret;
383
384 if (priv->bHwRadioOff)
385 return 0;
386
387 rtState = priv->eRFPowerState;
388
389 if(!priv->up) return -ENETDOWN;
390 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
391 return -EAGAIN;
392
393 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
394 {
395 struct iw_scan_req* req = (struct iw_scan_req*)b;
396 if (req->essid_len)
397 {
398 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
399 ieee->current_network.ssid_len = req->essid_len;
400 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
401 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
402 }
403 }
404
405 down(&priv->wx_sem);
406 #ifdef ENABLE_IPS
407 priv->ieee80211->actscanning = true;
408 if(priv->ieee80211->state != IEEE80211_LINKED){
409 if (priv->PowerSaveControl.bInactivePs) {
410 if(rtState == eRfOff){
411 if(priv->RfOffReason > RF_CHANGE_BY_IPS)
412 {
413 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
414 up(&priv->wx_sem);
415 return -1;
416 }
417 else{
418 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
419 down(&priv->ieee80211->ips_sem);
420 IPSLeave(dev);
421 up(&priv->ieee80211->ips_sem);
422 }
423 }
424 }
425 priv->ieee80211->scanning = 0;
426 ieee80211_softmac_scan_syncro(priv->ieee80211);
427 ret = 0;
428 }
429 else
430 #else
431
432 if(priv->ieee80211->state != IEEE80211_LINKED){
433 priv->ieee80211->scanning = 0;
434 ieee80211_softmac_scan_syncro(priv->ieee80211);
435 ret = 0;
436 }
437 else
438 #endif
439 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
440
441 up(&priv->wx_sem);
442 return ret;
443 }
444
445
446 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
447 union iwreq_data *wrqu, char *b)
448 {
449
450 int ret;
451 struct r8192_priv *priv = ieee80211_priv(dev);
452
453 if (priv->bHwRadioOff)
454 return 0;
455
456 if(!priv->up) return -ENETDOWN;
457
458 down(&priv->wx_sem);
459
460 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
461
462 up(&priv->wx_sem);
463
464 return ret;
465 }
466
467 static int r8192_wx_set_essid(struct net_device *dev,
468 struct iw_request_info *a,
469 union iwreq_data *wrqu, char *b)
470 {
471 struct r8192_priv *priv = ieee80211_priv(dev);
472 RT_RF_POWER_STATE rtState;
473 int ret;
474
475 if (priv->bHwRadioOff)
476 return 0;
477
478 rtState = priv->eRFPowerState;
479 down(&priv->wx_sem);
480
481 #ifdef ENABLE_IPS
482 down(&priv->ieee80211->ips_sem);
483 IPSLeave(dev);
484 up(&priv->ieee80211->ips_sem);
485 #endif
486 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
487
488 up(&priv->wx_sem);
489
490 return ret;
491 }
492
493
494
495
496 static int r8192_wx_get_essid(struct net_device *dev,
497 struct iw_request_info *a,
498 union iwreq_data *wrqu, char *b)
499 {
500 int ret;
501 struct r8192_priv *priv = ieee80211_priv(dev);
502
503 down(&priv->wx_sem);
504
505 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
506
507 up(&priv->wx_sem);
508
509 return ret;
510 }
511
512
513 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
514 union iwreq_data *wrqu, char *b)
515 {
516 int ret;
517 struct r8192_priv *priv = ieee80211_priv(dev);
518
519 if (priv->bHwRadioOff)
520 return 0;
521
522 down(&priv->wx_sem);
523
524 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
525
526 up(&priv->wx_sem);
527 return ret;
528 }
529
530 static int r8192_wx_get_name(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *extra)
533 {
534 struct r8192_priv *priv = ieee80211_priv(dev);
535 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
536 }
537
538
539 static int r8192_wx_set_frag(struct net_device *dev,
540 struct iw_request_info *info,
541 union iwreq_data *wrqu, char *extra)
542 {
543 struct r8192_priv *priv = ieee80211_priv(dev);
544
545 if (priv->bHwRadioOff)
546 return 0;
547
548 if (wrqu->frag.disabled)
549 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
550 else {
551 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
552 wrqu->frag.value > MAX_FRAG_THRESHOLD)
553 return -EINVAL;
554
555 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
556 }
557
558 return 0;
559 }
560
561
562 static int r8192_wx_get_frag(struct net_device *dev,
563 struct iw_request_info *info,
564 union iwreq_data *wrqu, char *extra)
565 {
566 struct r8192_priv *priv = ieee80211_priv(dev);
567
568 wrqu->frag.value = priv->ieee80211->fts;
569 wrqu->frag.fixed = 0; /* no auto select */
570 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
571
572 return 0;
573 }
574
575
576 static int r8192_wx_set_wap(struct net_device *dev,
577 struct iw_request_info *info,
578 union iwreq_data *awrq,
579 char *extra)
580 {
581
582 int ret;
583 struct r8192_priv *priv = ieee80211_priv(dev);
584 // struct sockaddr *temp = (struct sockaddr *)awrq;
585
586 if (priv->bHwRadioOff)
587 return 0;
588
589 down(&priv->wx_sem);
590
591 #ifdef ENABLE_IPS
592 down(&priv->ieee80211->ips_sem);
593 IPSLeave(dev);
594 up(&priv->ieee80211->ips_sem);
595 #endif
596 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
597
598 up(&priv->wx_sem);
599
600 return ret;
601
602 }
603
604
605 static int r8192_wx_get_wap(struct net_device *dev,
606 struct iw_request_info *info,
607 union iwreq_data *wrqu, char *extra)
608 {
609 struct r8192_priv *priv = ieee80211_priv(dev);
610
611 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
612 }
613
614
615 static int r8192_wx_get_enc(struct net_device *dev,
616 struct iw_request_info *info,
617 union iwreq_data *wrqu, char *key)
618 {
619 struct r8192_priv *priv = ieee80211_priv(dev);
620
621 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
622 }
623
624 static int r8192_wx_set_enc(struct net_device *dev,
625 struct iw_request_info *info,
626 union iwreq_data *wrqu, char *key)
627 {
628 struct r8192_priv *priv = ieee80211_priv(dev);
629 int ret;
630
631 struct ieee80211_device *ieee = priv->ieee80211;
632 //u32 TargetContent;
633 u32 hwkey[4]={0,0,0,0};
634 u8 mask=0xff;
635 u32 key_idx=0;
636 u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
637 {0x00,0x00,0x00,0x00,0x00,0x01},
638 {0x00,0x00,0x00,0x00,0x00,0x02},
639 {0x00,0x00,0x00,0x00,0x00,0x03} };
640 int i;
641
642 if (priv->bHwRadioOff)
643 return 0;
644
645 if(!priv->up) return -ENETDOWN;
646
647 priv->ieee80211->wx_set_enc = 1;
648 #ifdef ENABLE_IPS
649 down(&priv->ieee80211->ips_sem);
650 IPSLeave(dev);
651 up(&priv->ieee80211->ips_sem);
652 #endif
653
654 down(&priv->wx_sem);
655
656 RT_TRACE(COMP_SEC, "Setting SW wep key\n");
657 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
658
659 up(&priv->wx_sem);
660
661 //sometimes, the length is zero while we do not type key value
662 if(wrqu->encoding.length!=0){
663
664 for(i=0 ; i<4 ; i++){
665 hwkey[i] |= key[4*i+0]&mask;
666 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
667 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
668 hwkey[i] |= (key[4*i+1]&mask)<<8;
669 hwkey[i] |= (key[4*i+2]&mask)<<16;
670 hwkey[i] |= (key[4*i+3]&mask)<<24;
671 }
672
673 #define CONF_WEP40 0x4
674 #define CONF_WEP104 0x14
675
676 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
677 case 0: key_idx = ieee->tx_keyidx; break;
678 case 1: key_idx = 0; break;
679 case 2: key_idx = 1; break;
680 case 3: key_idx = 2; break;
681 case 4: key_idx = 3; break;
682 default: break;
683 }
684
685 //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
686 if(wrqu->encoding.length==0x5){
687 ieee->pairwise_key_type = KEY_TYPE_WEP40;
688 EnableHWSecurityConfig8192(dev);
689 setKey( dev,
690 key_idx, //EntryNo
691 key_idx, //KeyIndex
692 KEY_TYPE_WEP40, //KeyType
693 zero_addr[key_idx],
694 0, //DefaultKey
695 hwkey); //KeyContent
696 }
697
698 else if(wrqu->encoding.length==0xd){
699 ieee->pairwise_key_type = KEY_TYPE_WEP104;
700 EnableHWSecurityConfig8192(dev);
701 setKey( dev,
702 key_idx, //EntryNo
703 key_idx, //KeyIndex
704 KEY_TYPE_WEP104, //KeyType
705 zero_addr[key_idx],
706 0, //DefaultKey
707 hwkey); //KeyContent
708 }
709 else printk("wrong type in WEP, not WEP40 and WEP104\n");
710 }
711
712 priv->ieee80211->wx_set_enc = 0;
713
714 return ret;
715 }
716
717
718 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
719 iwreq_data *wrqu, char *p){
720
721 struct r8192_priv *priv = ieee80211_priv(dev);
722 int *parms=(int*)p;
723 int mode=parms[0];
724
725 priv->ieee80211->active_scan = mode;
726
727 return 1;
728 }
729
730
731
732 static int r8192_wx_set_retry(struct net_device *dev,
733 struct iw_request_info *info,
734 union iwreq_data *wrqu, char *extra)
735 {
736 struct r8192_priv *priv = ieee80211_priv(dev);
737 int err = 0;
738
739 if (priv->bHwRadioOff)
740 return 0;
741
742 down(&priv->wx_sem);
743
744 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
745 wrqu->retry.disabled){
746 err = -EINVAL;
747 goto exit;
748 }
749 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
750 err = -EINVAL;
751 goto exit;
752 }
753
754 if(wrqu->retry.value > R8180_MAX_RETRY){
755 err= -EINVAL;
756 goto exit;
757 }
758 if (wrqu->retry.flags & IW_RETRY_MAX) {
759 priv->retry_rts = wrqu->retry.value;
760 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
761
762 }else {
763 priv->retry_data = wrqu->retry.value;
764 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
765 }
766
767 /* FIXME !
768 * We might try to write directly the TX config register
769 * or to restart just the (R)TX process.
770 * I'm unsure if whole reset is really needed
771 */
772
773 rtl8192_commit(priv);
774 /*
775 if(priv->up){
776 rtl8180_rtx_disable(dev);
777 rtl8180_rx_enable(dev);
778 rtl8180_tx_enable(dev);
779
780 }
781 */
782 exit:
783 up(&priv->wx_sem);
784
785 return err;
786 }
787
788 static int r8192_wx_get_retry(struct net_device *dev,
789 struct iw_request_info *info,
790 union iwreq_data *wrqu, char *extra)
791 {
792 struct r8192_priv *priv = ieee80211_priv(dev);
793
794
795 wrqu->retry.disabled = 0; /* can't be disabled */
796
797 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
798 IW_RETRY_LIFETIME)
799 return -EINVAL;
800
801 if (wrqu->retry.flags & IW_RETRY_MAX) {
802 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
803 wrqu->retry.value = priv->retry_rts;
804 } else {
805 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
806 wrqu->retry.value = priv->retry_data;
807 }
808 //DMESG("returning %d",wrqu->retry.value);
809
810
811 return 0;
812 }
813
814 static int r8192_wx_get_sens(struct net_device *dev,
815 struct iw_request_info *info,
816 union iwreq_data *wrqu, char *extra)
817 {
818 struct r8192_priv *priv = ieee80211_priv(dev);
819 if(priv->rf_set_sens == NULL)
820 return -1; /* we have not this support for this radio */
821 wrqu->sens.value = priv->sens;
822 return 0;
823 }
824
825
826 static int r8192_wx_set_sens(struct net_device *dev,
827 struct iw_request_info *info,
828 union iwreq_data *wrqu, char *extra)
829 {
830
831 struct r8192_priv *priv = ieee80211_priv(dev);
832
833 short err = 0;
834
835 if (priv->bHwRadioOff)
836 return 0;
837
838 down(&priv->wx_sem);
839 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
840 if(priv->rf_set_sens == NULL) {
841 err= -1; /* we have not this support for this radio */
842 goto exit;
843 }
844 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
845 priv->sens = wrqu->sens.value;
846 else
847 err= -EINVAL;
848
849 exit:
850 up(&priv->wx_sem);
851
852 return err;
853 }
854
855 static int r8192_wx_set_enc_ext(struct net_device *dev,
856 struct iw_request_info *info,
857 union iwreq_data *wrqu, char *extra)
858 {
859 int ret=0;
860 struct r8192_priv *priv = ieee80211_priv(dev);
861 struct ieee80211_device* ieee = priv->ieee80211;
862
863 if (priv->bHwRadioOff)
864 return 0;
865
866 down(&priv->wx_sem);
867
868 priv->ieee80211->wx_set_enc = 1;
869
870 #ifdef ENABLE_IPS
871 down(&priv->ieee80211->ips_sem);
872 IPSLeave(dev);
873 up(&priv->ieee80211->ips_sem);
874 #endif
875
876 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
877
878 {
879 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
880 u8 zero[6] = {0};
881 u32 key[4] = {0};
882 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
883 struct iw_point *encoding = &wrqu->encoding;
884 u8 idx = 0, alg = 0, group = 0;
885
886 if ((encoding->flags & IW_ENCODE_DISABLED) ||
887 ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
888 {
889 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
890 CamResetAllEntry(priv);
891 goto end_hw_sec;
892 }
893 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;
894 idx = encoding->flags & IW_ENCODE_INDEX;
895 if (idx)
896 idx --;
897 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
898
899 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
900 {
901 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
902 alg = KEY_TYPE_WEP104;
903 ieee->pairwise_key_type = alg;
904 EnableHWSecurityConfig8192(dev);
905 }
906 memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
907
908 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
909 {
910 if (ext->key_len == 13)
911 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
912 setKey( dev,
913 idx,//EntryNo
914 idx, //KeyIndex
915 alg, //KeyType
916 zero, //MacAddr
917 0, //DefaultKey
918 key); //KeyContent
919 }
920 else if (group)
921 {
922 ieee->group_key_type = alg;
923 setKey( dev,
924 idx,//EntryNo
925 idx, //KeyIndex
926 alg, //KeyType
927 broadcast_addr, //MacAddr
928 0, //DefaultKey
929 key); //KeyContent
930 }
931 else //pairwise key
932 {
933 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
934 write_nic_byte(priv, 0x173, 1); //fix aes bug
935 }
936 setKey( dev,
937 4,//EntryNo
938 idx, //KeyIndex
939 alg, //KeyType
940 (u8*)ieee->ap_mac_addr, //MacAddr
941 0, //DefaultKey
942 key); //KeyContent
943 }
944
945
946 }
947
948 end_hw_sec:
949 priv->ieee80211->wx_set_enc = 0;
950 up(&priv->wx_sem);
951 return ret;
952
953 }
954 static int r8192_wx_set_auth(struct net_device *dev,
955 struct iw_request_info *info,
956 union iwreq_data *data, char *extra)
957 {
958 int ret=0;
959 //printk("====>%s()\n", __FUNCTION__);
960 struct r8192_priv *priv = ieee80211_priv(dev);
961
962 if (priv->bHwRadioOff)
963 return 0;
964
965 down(&priv->wx_sem);
966 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
967 up(&priv->wx_sem);
968 return ret;
969 }
970
971 static int r8192_wx_set_mlme(struct net_device *dev,
972 struct iw_request_info *info,
973 union iwreq_data *wrqu, char *extra)
974 {
975 //printk("====>%s()\n", __FUNCTION__);
976
977 int ret=0;
978 struct r8192_priv *priv = ieee80211_priv(dev);
979
980 if (priv->bHwRadioOff)
981 return 0;
982
983 down(&priv->wx_sem);
984 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
985 up(&priv->wx_sem);
986 return ret;
987 }
988
989 static int r8192_wx_set_gen_ie(struct net_device *dev,
990 struct iw_request_info *info,
991 union iwreq_data *data, char *extra)
992 {
993 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
994 int ret=0;
995 struct r8192_priv *priv = ieee80211_priv(dev);
996
997 if (priv->bHwRadioOff)
998 return 0;
999
1000 down(&priv->wx_sem);
1001 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1002 up(&priv->wx_sem);
1003 //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1004 return ret;
1005 }
1006
1007 static int dummy(struct net_device *dev, struct iw_request_info *a,
1008 union iwreq_data *wrqu,char *b)
1009 {
1010 return -1;
1011 }
1012
1013 // check ac/dc status with the help of user space application */
1014 static int r8192_wx_adapter_power_status(struct net_device *dev,
1015 struct iw_request_info *info,
1016 union iwreq_data *wrqu, char *extra)
1017 {
1018 struct r8192_priv *priv = ieee80211_priv(dev);
1019 #ifdef ENABLE_LPS
1020 PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl;
1021 struct ieee80211_device* ieee = priv->ieee80211;
1022 #endif
1023 down(&priv->wx_sem);
1024
1025 #ifdef ENABLE_LPS
1026 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1027 // ieee->ps shall not be set under DC mode, otherwise it conflict
1028 // with Leisure power save mode setting.
1029 //
1030 if(*extra || priv->force_lps) {
1031 priv->ps_force = false;
1032 pPSC->bLeisurePs = true;
1033 } else {
1034 //LZM for PS-Poll AID issue. 090429
1035 if(priv->ieee80211->state == IEEE80211_LINKED)
1036 LeisurePSLeave(dev);
1037
1038 priv->ps_force = true;
1039 pPSC->bLeisurePs = false;
1040 ieee->ps = *extra;
1041 }
1042
1043 #endif
1044 up(&priv->wx_sem);
1045 return 0;
1046
1047 }
1048
1049
1050 static iw_handler r8192_wx_handlers[] =
1051 {
1052 NULL, /* SIOCSIWCOMMIT */
1053 r8192_wx_get_name, /* SIOCGIWNAME */
1054 dummy, /* SIOCSIWNWID */
1055 dummy, /* SIOCGIWNWID */
1056 r8192_wx_set_freq, /* SIOCSIWFREQ */
1057 r8192_wx_get_freq, /* SIOCGIWFREQ */
1058 r8192_wx_set_mode, /* SIOCSIWMODE */
1059 r8192_wx_get_mode, /* SIOCGIWMODE */
1060 r8192_wx_set_sens, /* SIOCSIWSENS */
1061 r8192_wx_get_sens, /* SIOCGIWSENS */
1062 NULL, /* SIOCSIWRANGE */
1063 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1064 NULL, /* SIOCSIWPRIV */
1065 NULL, /* SIOCGIWPRIV */
1066 NULL, /* SIOCSIWSTATS */
1067 NULL, /* SIOCGIWSTATS */
1068 dummy, /* SIOCSIWSPY */
1069 dummy, /* SIOCGIWSPY */
1070 NULL, /* SIOCGIWTHRSPY */
1071 NULL, /* SIOCWIWTHRSPY */
1072 r8192_wx_set_wap, /* SIOCSIWAP */
1073 r8192_wx_get_wap, /* SIOCGIWAP */
1074 r8192_wx_set_mlme, /* MLME-- */
1075 dummy, /* SIOCGIWAPLIST -- depricated */
1076 r8192_wx_set_scan, /* SIOCSIWSCAN */
1077 r8192_wx_get_scan, /* SIOCGIWSCAN */
1078 r8192_wx_set_essid, /* SIOCSIWESSID */
1079 r8192_wx_get_essid, /* SIOCGIWESSID */
1080 dummy, /* SIOCSIWNICKN */
1081 dummy, /* SIOCGIWNICKN */
1082 NULL, /* -- hole -- */
1083 NULL, /* -- hole -- */
1084 r8192_wx_set_rate, /* SIOCSIWRATE */
1085 r8192_wx_get_rate, /* SIOCGIWRATE */
1086 r8192_wx_set_rts, /* SIOCSIWRTS */
1087 r8192_wx_get_rts, /* SIOCGIWRTS */
1088 r8192_wx_set_frag, /* SIOCSIWFRAG */
1089 r8192_wx_get_frag, /* SIOCGIWFRAG */
1090 dummy, /* SIOCSIWTXPOW */
1091 dummy, /* SIOCGIWTXPOW */
1092 r8192_wx_set_retry, /* SIOCSIWRETRY */
1093 r8192_wx_get_retry, /* SIOCGIWRETRY */
1094 r8192_wx_set_enc, /* SIOCSIWENCODE */
1095 r8192_wx_get_enc, /* SIOCGIWENCODE */
1096 r8192_wx_set_power, /* SIOCSIWPOWER */
1097 r8192_wx_get_power, /* SIOCGIWPOWER */
1098 NULL, /*---hole---*/
1099 NULL, /*---hole---*/
1100 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1101 NULL, /* SIOCSIWGENIE */
1102 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1103 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1104 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1105 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1106 NULL, /* SIOCSIWPMKSA */
1107 NULL, /*---hole---*/
1108
1109 };
1110
1111
1112 static const struct iw_priv_args r8192_private_args[] = {
1113
1114 {
1115 SIOCIWFIRSTPRIV + 0x0,
1116 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1117 },
1118
1119 {
1120 SIOCIWFIRSTPRIV + 0x1,
1121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1122
1123 },
1124 {
1125 SIOCIWFIRSTPRIV + 0x2,
1126 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1127 }
1128 ,
1129 {
1130 SIOCIWFIRSTPRIV + 0x3,
1131 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1132
1133 }
1134 ,
1135 {
1136 SIOCIWFIRSTPRIV + 0x4,
1137 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1138 "set_power"
1139 }
1140
1141 };
1142
1143
1144 static iw_handler r8192_private_handler[] = {
1145 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1146 r8192_wx_set_scan_type,
1147 r8192_wx_set_rawtx,
1148 r8192_wx_force_reset,
1149 r8192_wx_adapter_power_status,
1150 };
1151
1152 static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1153 {
1154 struct r8192_priv *priv = ieee80211_priv(dev);
1155 struct ieee80211_device* ieee = priv->ieee80211;
1156 struct iw_statistics* wstats = &priv->wstats;
1157 int tmp_level = 0;
1158 int tmp_qual = 0;
1159 int tmp_noise = 0;
1160 if(ieee->state < IEEE80211_LINKED)
1161 {
1162 wstats->qual.qual = 0;
1163 wstats->qual.level = 0;
1164 wstats->qual.noise = 0;
1165 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1166 return wstats;
1167 }
1168
1169 tmp_level = (&ieee->current_network)->stats.rssi;
1170 tmp_qual = (&ieee->current_network)->stats.signal;
1171 tmp_noise = (&ieee->current_network)->stats.noise;
1172 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1173
1174 wstats->qual.level = tmp_level;
1175 wstats->qual.qual = tmp_qual;
1176 wstats->qual.noise = tmp_noise;
1177 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1178 return wstats;
1179 }
1180
1181
1182 struct iw_handler_def r8192_wx_handlers_def={
1183 .standard = r8192_wx_handlers,
1184 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1185 .private = r8192_private_handler,
1186 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1187 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1188 .get_wireless_stats = r8192_get_wireless_stats,
1189 .private_args = (struct iw_priv_args *)r8192_private_args,
1190 };
This page took 0.056396 seconds and 5 git commands to generate.