1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
29static 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
36static 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
46static 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
56static 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
66static 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
86static 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
105static 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
113static 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
132static 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
140static 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
160static 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
176static 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
200
201 }
202
203 up(&priv->wx_sem);
204
205 return 0;
206}
207
208static 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(priv);
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
244
245 up(&priv->wx_sem);
246 return ret;
247}
248
249struct iw_range_with_scan_capa
250{
251
252 __u32 throughput;
253
254
255
256
257
258
259
260
261 __u32 min_nwid;
262 __u32 max_nwid;
263
264
265 __u16 old_num_channels;
266 __u8 old_num_frequency;
267
268
269 __u8 scan_capa;
270};
271static 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
285
286
287
288
289
290
291
292
293 range->throughput = 130 * 1000 * 1000;
294
295
296
297
298
299
300
301
302
303
304
305 range->max_qual.qual = 100;
306
307 range->max_qual.level = 0;
308 range->max_qual.noise = -98;
309 range->max_qual.updated = 7;
310
311 range->avg_qual.qual = 92;
312
313 range->avg_qual.level = 20 + -98;
314 range->avg_qual.noise = 0;
315 range->avg_qual.updated = 7;
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
337
338
339
340
341
342
343
344
345 for (i = 0, val = 0; i < 14; i++) {
346
347
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
359
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
376static 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
399 ieee->current_network.ssid_len = req->essid_len;
400 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
401
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
419 down(&priv->ieee80211->ips_sem);
420 IPSLeave(priv);
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
446static 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
467static 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(priv);
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
496static 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
513static 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
530static 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
539static 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
562static 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;
570 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
571
572 return 0;
573}
574
575
576static 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
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(priv);
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
605static 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
615static 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
624static 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
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(priv);
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
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
686 if(wrqu->encoding.length==0x5){
687 ieee->pairwise_key_type = KEY_TYPE_WEP40;
688 EnableHWSecurityConfig8192(priv);
689 setKey(priv, key_idx, key_idx, KEY_TYPE_WEP40,
690 zero_addr[key_idx], 0, hwkey);
691 }
692
693 else if(wrqu->encoding.length==0xd){
694 ieee->pairwise_key_type = KEY_TYPE_WEP104;
695 EnableHWSecurityConfig8192(priv);
696 setKey(priv, key_idx, key_idx, KEY_TYPE_WEP104,
697 zero_addr[key_idx], 0, hwkey);
698 }
699 else printk("wrong type in WEP, not WEP40 and WEP104\n");
700 }
701
702 priv->ieee80211->wx_set_enc = 0;
703
704 return ret;
705}
706
707
708static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
709 iwreq_data *wrqu, char *p){
710
711 struct r8192_priv *priv = ieee80211_priv(dev);
712 int *parms=(int*)p;
713 int mode=parms[0];
714
715 priv->ieee80211->active_scan = mode;
716
717 return 1;
718}
719
720
721
722static int r8192_wx_set_retry(struct net_device *dev,
723 struct iw_request_info *info,
724 union iwreq_data *wrqu, char *extra)
725{
726 struct r8192_priv *priv = ieee80211_priv(dev);
727 int err = 0;
728
729 if (priv->bHwRadioOff)
730 return 0;
731
732 down(&priv->wx_sem);
733
734 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
735 wrqu->retry.disabled){
736 err = -EINVAL;
737 goto exit;
738 }
739 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
740 err = -EINVAL;
741 goto exit;
742 }
743
744 if(wrqu->retry.value > R8180_MAX_RETRY){
745 err= -EINVAL;
746 goto exit;
747 }
748 if (wrqu->retry.flags & IW_RETRY_MAX) {
749 priv->retry_rts = wrqu->retry.value;
750 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
751
752 }else {
753 priv->retry_data = wrqu->retry.value;
754 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
755 }
756
757
758
759
760
761
762
763 rtl8192_commit(priv);
764
765
766
767
768
769
770
771
772exit:
773 up(&priv->wx_sem);
774
775 return err;
776}
777
778static int r8192_wx_get_retry(struct net_device *dev,
779 struct iw_request_info *info,
780 union iwreq_data *wrqu, char *extra)
781{
782 struct r8192_priv *priv = ieee80211_priv(dev);
783
784
785 wrqu->retry.disabled = 0;
786
787 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
788 IW_RETRY_LIFETIME)
789 return -EINVAL;
790
791 if (wrqu->retry.flags & IW_RETRY_MAX) {
792 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
793 wrqu->retry.value = priv->retry_rts;
794 } else {
795 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
796 wrqu->retry.value = priv->retry_data;
797 }
798
799
800
801 return 0;
802}
803
804static int r8192_wx_get_sens(struct net_device *dev,
805 struct iw_request_info *info,
806 union iwreq_data *wrqu, char *extra)
807{
808 struct r8192_priv *priv = ieee80211_priv(dev);
809 if(priv->rf_set_sens == NULL)
810 return -1;
811 wrqu->sens.value = priv->sens;
812 return 0;
813}
814
815
816static int r8192_wx_set_sens(struct net_device *dev,
817 struct iw_request_info *info,
818 union iwreq_data *wrqu, char *extra)
819{
820
821 struct r8192_priv *priv = ieee80211_priv(dev);
822
823 short err = 0;
824
825 if (priv->bHwRadioOff)
826 return 0;
827
828 down(&priv->wx_sem);
829
830 if(priv->rf_set_sens == NULL) {
831 err= -1;
832 goto exit;
833 }
834 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
835 priv->sens = wrqu->sens.value;
836 else
837 err= -EINVAL;
838
839exit:
840 up(&priv->wx_sem);
841
842 return err;
843}
844
845static int r8192_wx_set_enc_ext(struct net_device *dev,
846 struct iw_request_info *info,
847 union iwreq_data *wrqu, char *extra)
848{
849 int ret=0;
850 struct r8192_priv *priv = ieee80211_priv(dev);
851 struct ieee80211_device* ieee = priv->ieee80211;
852
853 if (priv->bHwRadioOff)
854 return 0;
855
856 down(&priv->wx_sem);
857
858 priv->ieee80211->wx_set_enc = 1;
859
860#ifdef ENABLE_IPS
861 down(&priv->ieee80211->ips_sem);
862 IPSLeave(priv);
863 up(&priv->ieee80211->ips_sem);
864#endif
865
866 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
867
868 {
869 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
870 u8 zero[6] = {0};
871 u32 key[4] = {0};
872 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
873 struct iw_point *encoding = &wrqu->encoding;
874 u8 idx = 0, alg = 0, group = 0;
875
876 if ((encoding->flags & IW_ENCODE_DISABLED) ||
877 ext->alg == IW_ENCODE_ALG_NONE)
878 {
879 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
880 CamResetAllEntry(priv);
881 goto end_hw_sec;
882 }
883 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
884 idx = encoding->flags & IW_ENCODE_INDEX;
885 if (idx)
886 idx --;
887 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
888
889 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
890 {
891 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
892 alg = KEY_TYPE_WEP104;
893 ieee->pairwise_key_type = alg;
894 EnableHWSecurityConfig8192(priv);
895 }
896 memcpy((u8*)key, ext->key, 16);
897
898 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
899 {
900 if (ext->key_len == 13)
901 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
902 setKey(priv, idx, idx, alg, zero, 0, key);
903 }
904 else if (group)
905 {
906 ieee->group_key_type = alg;
907 setKey(priv, idx, idx, alg, broadcast_addr, 0, key);
908 }
909 else
910 {
911 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
912 write_nic_byte(priv, 0x173, 1);
913 }
914 setKey(priv, 4, idx, alg,
915 (u8*)ieee->ap_mac_addr, 0, key);
916 }
917
918
919 }
920
921end_hw_sec:
922 priv->ieee80211->wx_set_enc = 0;
923 up(&priv->wx_sem);
924 return ret;
925
926}
927static int r8192_wx_set_auth(struct net_device *dev,
928 struct iw_request_info *info,
929 union iwreq_data *data, char *extra)
930{
931 int ret=0;
932
933 struct r8192_priv *priv = ieee80211_priv(dev);
934
935 if (priv->bHwRadioOff)
936 return 0;
937
938 down(&priv->wx_sem);
939 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
940 up(&priv->wx_sem);
941 return ret;
942}
943
944static int r8192_wx_set_mlme(struct net_device *dev,
945 struct iw_request_info *info,
946 union iwreq_data *wrqu, char *extra)
947{
948
949
950 int ret=0;
951 struct r8192_priv *priv = ieee80211_priv(dev);
952
953 if (priv->bHwRadioOff)
954 return 0;
955
956 down(&priv->wx_sem);
957 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
958 up(&priv->wx_sem);
959 return ret;
960}
961
962static int r8192_wx_set_gen_ie(struct net_device *dev,
963 struct iw_request_info *info,
964 union iwreq_data *data, char *extra)
965{
966
967 int ret=0;
968 struct r8192_priv *priv = ieee80211_priv(dev);
969
970 if (priv->bHwRadioOff)
971 return 0;
972
973 down(&priv->wx_sem);
974 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
975 up(&priv->wx_sem);
976
977 return ret;
978}
979
980static int dummy(struct net_device *dev, struct iw_request_info *a,
981 union iwreq_data *wrqu,char *b)
982{
983 return -1;
984}
985
986
987static int r8192_wx_adapter_power_status(struct net_device *dev,
988 struct iw_request_info *info,
989 union iwreq_data *wrqu, char *extra)
990{
991 struct r8192_priv *priv = ieee80211_priv(dev);
992#ifdef ENABLE_LPS
993 PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl;
994 struct ieee80211_device* ieee = priv->ieee80211;
995#endif
996 down(&priv->wx_sem);
997
998#ifdef ENABLE_LPS
999 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1000
1001
1002
1003 if(*extra || priv->force_lps) {
1004 priv->ps_force = false;
1005 pPSC->bLeisurePs = true;
1006 } else {
1007
1008 if(priv->ieee80211->state == IEEE80211_LINKED)
1009 LeisurePSLeave(priv->ieee80211);
1010
1011 priv->ps_force = true;
1012 pPSC->bLeisurePs = false;
1013 ieee->ps = *extra;
1014 }
1015
1016#endif
1017 up(&priv->wx_sem);
1018 return 0;
1019
1020}
1021
1022
1023static iw_handler r8192_wx_handlers[] =
1024{
1025 NULL,
1026 r8192_wx_get_name,
1027 dummy,
1028 dummy,
1029 r8192_wx_set_freq,
1030 r8192_wx_get_freq,
1031 r8192_wx_set_mode,
1032 r8192_wx_get_mode,
1033 r8192_wx_set_sens,
1034 r8192_wx_get_sens,
1035 NULL,
1036 rtl8180_wx_get_range,
1037 NULL,
1038 NULL,
1039 NULL,
1040 NULL,
1041 dummy,
1042 dummy,
1043 NULL,
1044 NULL,
1045 r8192_wx_set_wap,
1046 r8192_wx_get_wap,
1047 r8192_wx_set_mlme,
1048 dummy,
1049 r8192_wx_set_scan,
1050 r8192_wx_get_scan,
1051 r8192_wx_set_essid,
1052 r8192_wx_get_essid,
1053 dummy,
1054 dummy,
1055 NULL,
1056 NULL,
1057 r8192_wx_set_rate,
1058 r8192_wx_get_rate,
1059 r8192_wx_set_rts,
1060 r8192_wx_get_rts,
1061 r8192_wx_set_frag,
1062 r8192_wx_get_frag,
1063 dummy,
1064 dummy,
1065 r8192_wx_set_retry,
1066 r8192_wx_get_retry,
1067 r8192_wx_set_enc,
1068 r8192_wx_get_enc,
1069 r8192_wx_set_power,
1070 r8192_wx_get_power,
1071 NULL,
1072 NULL,
1073 r8192_wx_set_gen_ie,
1074 NULL,
1075 r8192_wx_set_auth,
1076 NULL,
1077 r8192_wx_set_enc_ext,
1078 NULL,
1079 NULL,
1080 NULL,
1081
1082};
1083
1084
1085static const struct iw_priv_args r8192_private_args[] = {
1086
1087 {
1088 SIOCIWFIRSTPRIV + 0x0,
1089 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1090 },
1091
1092 {
1093 SIOCIWFIRSTPRIV + 0x1,
1094 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1095
1096 },
1097 {
1098 SIOCIWFIRSTPRIV + 0x2,
1099 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1100 }
1101 ,
1102 {
1103 SIOCIWFIRSTPRIV + 0x3,
1104 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1105
1106 }
1107 ,
1108 {
1109 SIOCIWFIRSTPRIV + 0x4,
1110 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1111 "set_power"
1112 }
1113
1114};
1115
1116
1117static iw_handler r8192_private_handler[] = {
1118 r8192_wx_set_crcmon,
1119 r8192_wx_set_scan_type,
1120 r8192_wx_set_rawtx,
1121 r8192_wx_force_reset,
1122 r8192_wx_adapter_power_status,
1123};
1124
1125static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1126{
1127 struct r8192_priv *priv = ieee80211_priv(dev);
1128 struct ieee80211_device* ieee = priv->ieee80211;
1129 struct iw_statistics* wstats = &priv->wstats;
1130 int tmp_level = 0;
1131 int tmp_qual = 0;
1132 int tmp_noise = 0;
1133 if(ieee->state < IEEE80211_LINKED)
1134 {
1135 wstats->qual.qual = 0;
1136 wstats->qual.level = 0;
1137 wstats->qual.noise = 0;
1138 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1139 return wstats;
1140 }
1141
1142 tmp_level = (&ieee->current_network)->stats.rssi;
1143 tmp_qual = (&ieee->current_network)->stats.signal;
1144 tmp_noise = (&ieee->current_network)->stats.noise;
1145
1146
1147 wstats->qual.level = tmp_level;
1148 wstats->qual.qual = tmp_qual;
1149 wstats->qual.noise = tmp_noise;
1150 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1151 return wstats;
1152}
1153
1154
1155struct iw_handler_def r8192_wx_handlers_def={
1156 .standard = r8192_wx_handlers,
1157 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1158 .private = r8192_private_handler,
1159 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1160 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1161 .get_wireless_stats = r8192_get_wireless_stats,
1162 .private_args = (struct iw_priv_args *)r8192_private_args,
1163};
1164