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 "r8192U.h"
22#include "r8192U_hw.h"
23
24#include "dot11d.h"
25
26#define RATE_COUNT 12
27u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
28 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
29
30
31#ifndef ENETDOWN
32#define ENETDOWN 1
33#endif
34
35static int r8192_wx_get_freq(struct net_device *dev,
36 struct iw_request_info *a,
37 union iwreq_data *wrqu, char *b)
38{
39 struct r8192_priv *priv = ieee80211_priv(dev);
40
41 return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
42}
43
44
45static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
46 union iwreq_data *wrqu, char *b)
47{
48 struct r8192_priv *priv=ieee80211_priv(dev);
49
50 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
51}
52
53
54
55static int r8192_wx_get_rate(struct net_device *dev,
56 struct iw_request_info *info,
57 union iwreq_data *wrqu, char *extra)
58{
59 struct r8192_priv *priv = ieee80211_priv(dev);
60 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
61}
62
63
64
65static int r8192_wx_set_rate(struct net_device *dev,
66 struct iw_request_info *info,
67 union iwreq_data *wrqu, char *extra)
68{
69 int ret;
70 struct r8192_priv *priv = ieee80211_priv(dev);
71
72 down(&priv->wx_sem);
73
74 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
75
76 up(&priv->wx_sem);
77
78 return ret;
79}
80
81
82static int r8192_wx_set_rts(struct net_device *dev,
83 struct iw_request_info *info,
84 union iwreq_data *wrqu, char *extra)
85{
86 int ret;
87 struct r8192_priv *priv = ieee80211_priv(dev);
88
89 down(&priv->wx_sem);
90
91 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
92
93 up(&priv->wx_sem);
94
95 return ret;
96}
97
98static int r8192_wx_get_rts(struct net_device *dev,
99 struct iw_request_info *info,
100 union iwreq_data *wrqu, char *extra)
101{
102 struct r8192_priv *priv = ieee80211_priv(dev);
103 return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
104}
105
106static int r8192_wx_set_power(struct net_device *dev,
107 struct iw_request_info *info,
108 union iwreq_data *wrqu, char *extra)
109{
110 int ret;
111 struct r8192_priv *priv = ieee80211_priv(dev);
112
113 down(&priv->wx_sem);
114
115 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
116
117 up(&priv->wx_sem);
118
119 return ret;
120}
121
122static int r8192_wx_get_power(struct net_device *dev,
123 struct iw_request_info *info,
124 union iwreq_data *wrqu, char *extra)
125{
126 struct r8192_priv *priv = ieee80211_priv(dev);
127 return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
128}
129
130#ifdef JOHN_IOCTL
131u16 read_rtl8225(struct net_device *dev, u8 addr);
132void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
133u32 john_read_rtl8225(struct net_device *dev, u8 adr);
134void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
135
136static int r8192_wx_read_regs(struct net_device *dev,
137 struct iw_request_info *info,
138 union iwreq_data *wrqu, char *extra)
139{
140 struct r8192_priv *priv = ieee80211_priv(dev);
141 u8 addr;
142 u16 data1;
143
144 down(&priv->wx_sem);
145
146
147 get_user(addr,(u8*)wrqu->data.pointer);
148 data1 = read_rtl8225(dev, addr);
149 wrqu->data.length = data1;
150
151 up(&priv->wx_sem);
152 return 0;
153
154}
155
156static int r8192_wx_write_regs(struct net_device *dev,
157 struct iw_request_info *info,
158 union iwreq_data *wrqu, char *extra)
159{
160 struct r8192_priv *priv = ieee80211_priv(dev);
161 u8 addr;
162
163 down(&priv->wx_sem);
164
165 get_user(addr, (u8*)wrqu->data.pointer);
166 write_rtl8225(dev, addr, wrqu->data.length);
167
168 up(&priv->wx_sem);
169 return 0;
170
171}
172
173void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
174u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
175
176static int r8192_wx_read_bb(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 u8 databb;
182
183 down(&priv->wx_sem);
184
185 databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
186 wrqu->data.length = databb;
187
188 up(&priv->wx_sem);
189 return 0;
190}
191
192void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
193static int r8192_wx_write_bb(struct net_device *dev,
194 struct iw_request_info *info,
195 union iwreq_data *wrqu, char *extra)
196{
197 struct r8192_priv *priv = ieee80211_priv(dev);
198 u8 databb;
199
200 down(&priv->wx_sem);
201
202 get_user(databb, (u8*)wrqu->data.pointer);
203 rtl8187_write_phy(dev, wrqu->data.length, databb);
204
205 up(&priv->wx_sem);
206 return 0;
207
208}
209
210
211static int r8192_wx_write_nicb(struct net_device *dev,
212 struct iw_request_info *info,
213 union iwreq_data *wrqu, char *extra)
214{
215 struct r8192_priv *priv = ieee80211_priv(dev);
216 u32 addr;
217
218 down(&priv->wx_sem);
219
220 get_user(addr, (u32*)wrqu->data.pointer);
221 write_nic_byte(dev, addr, wrqu->data.length);
222
223 up(&priv->wx_sem);
224 return 0;
225
226}
227static int r8192_wx_read_nicb(struct net_device *dev,
228 struct iw_request_info *info,
229 union iwreq_data *wrqu, char *extra)
230{
231 struct r8192_priv *priv = ieee80211_priv(dev);
232 u32 addr;
233 u16 data1;
234
235 down(&priv->wx_sem);
236
237 get_user(addr,(u32*)wrqu->data.pointer);
238 data1 = read_nic_byte(dev, addr);
239 wrqu->data.length = data1;
240
241 up(&priv->wx_sem);
242 return 0;
243}
244
245static int r8192_wx_get_ap_status(struct net_device *dev,
246 struct iw_request_info *info,
247 union iwreq_data *wrqu, char *extra)
248{
249 struct r8192_priv *priv = ieee80211_priv(dev);
250 struct ieee80211_device *ieee = priv->ieee80211;
251 struct ieee80211_network *target;
252 int name_len;
253
254 down(&priv->wx_sem);
255
256
257 for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
258
259
260 list_for_each_entry(target, &ieee->network_list, list) {
261 if ( (target->ssid_len == name_len) &&
262 (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
263 if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
264
265 wrqu->data.flags = 1;
266 else wrqu->data.flags = 0;
267
268
269 break;
270 }
271 }
272
273 up(&priv->wx_sem);
274 return 0;
275}
276
277
278
279#endif
280static int r8192_wx_force_reset(struct net_device *dev,
281 struct iw_request_info *info,
282 union iwreq_data *wrqu, char *extra)
283{
284 struct r8192_priv *priv = ieee80211_priv(dev);
285
286 down(&priv->wx_sem);
287
288 printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
289 priv->force_reset = *extra;
290 up(&priv->wx_sem);
291 return 0;
292
293}
294
295
296static int r8192_wx_set_rawtx(struct net_device *dev,
297 struct iw_request_info *info,
298 union iwreq_data *wrqu, char *extra)
299{
300 struct r8192_priv *priv = ieee80211_priv(dev);
301 int ret;
302
303 down(&priv->wx_sem);
304
305 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
306
307 up(&priv->wx_sem);
308
309 return ret;
310
311}
312
313static int r8192_wx_set_crcmon(struct net_device *dev,
314 struct iw_request_info *info,
315 union iwreq_data *wrqu, char *extra)
316{
317 struct r8192_priv *priv = ieee80211_priv(dev);
318 int *parms = (int *)extra;
319 int enable = (parms[0] > 0);
320 short prev = priv->crcmon;
321
322 down(&priv->wx_sem);
323
324 if(enable)
325 priv->crcmon=1;
326 else
327 priv->crcmon=0;
328
329 DMESG("bad CRC in monitor mode are %s",
330 priv->crcmon ? "accepted" : "rejected");
331
332 if(prev != priv->crcmon && priv->up){
333
334
335 }
336
337 up(&priv->wx_sem);
338
339 return 0;
340}
341
342static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
343 union iwreq_data *wrqu, char *b)
344{
345 struct r8192_priv *priv = ieee80211_priv(dev);
346 int ret;
347 down(&priv->wx_sem);
348
349 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
350
351 rtl8192_set_rxconf(dev);
352
353 up(&priv->wx_sem);
354 return ret;
355}
356
357struct iw_range_with_scan_capa
358{
359
360 __u32 throughput;
361
362
363
364
365
366
367
368
369 __u32 min_nwid;
370 __u32 max_nwid;
371
372
373 __u16 old_num_channels;
374 __u8 old_num_frequency;
375
376
377 __u8 scan_capa;
378};
379static int rtl8180_wx_get_range(struct net_device *dev,
380 struct iw_request_info *info,
381 union iwreq_data *wrqu, char *extra)
382{
383 struct iw_range *range = (struct iw_range *)extra;
384 struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
385 struct r8192_priv *priv = ieee80211_priv(dev);
386 u16 val;
387 int i;
388
389 wrqu->data.length = sizeof(*range);
390 memset(range, 0, sizeof(*range));
391
392
393
394
395
396
397
398
399
400
401 range->throughput = 5 * 1000 * 1000;
402
403
404
405
406
407
408
409
410
411
412 if(priv->rf_set_sens != NULL)
413 range->sensitivity = priv->max_sens;
414
415 range->max_qual.qual = 100;
416
417 range->max_qual.level = 0;
418 range->max_qual.noise = -98;
419 range->max_qual.updated = 7;
420
421 range->avg_qual.qual = 92;
422
423 range->avg_qual.level = 20 + -98;
424 range->avg_qual.noise = 0;
425 range->avg_qual.updated = 7;
426
427 range->num_bitrates = RATE_COUNT;
428
429 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
430 range->bitrate[i] = rtl8180_rates[i];
431 }
432
433 range->min_frag = MIN_FRAG_THRESHOLD;
434 range->max_frag = MAX_FRAG_THRESHOLD;
435
436 range->min_pmp=0;
437 range->max_pmp = 5000000;
438 range->min_pmt = 0;
439 range->max_pmt = 65535*1000;
440 range->pmp_flags = IW_POWER_PERIOD;
441 range->pmt_flags = IW_POWER_TIMEOUT;
442 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
443
444 range->we_version_compiled = WIRELESS_EXT;
445 range->we_version_source = 16;
446
447
448
449
450
451
452
453
454
455
456 for (i = 0, val = 0; i < 14; i++) {
457
458
459 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
460 range->freq[val].i = i + 1;
461 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
462 range->freq[val].e = 1;
463 val++;
464 } else {
465
466
467 }
468
469 if (val == IW_MAX_FREQUENCIES)
470 break;
471 }
472 range->num_frequency = val;
473 range->num_channels = val;
474#if WIRELESS_EXT > 17
475 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
476 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
477#endif
478 tmp->scan_capa = 0x01;
479 return 0;
480}
481
482
483static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
484 union iwreq_data *wrqu, char *b)
485{
486 struct r8192_priv *priv = ieee80211_priv(dev);
487 struct ieee80211_device* ieee = priv->ieee80211;
488 int ret = 0;
489
490 if(!priv->up) return -ENETDOWN;
491
492 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
493 return -EAGAIN;
494 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
495 {
496 struct iw_scan_req* req = (struct iw_scan_req*)b;
497 if (req->essid_len)
498 {
499
500 ieee->current_network.ssid_len = req->essid_len;
501 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
502
503 }
504 }
505
506 down(&priv->wx_sem);
507 if(priv->ieee80211->state != IEEE80211_LINKED){
508 priv->ieee80211->scanning = 0;
509 ieee80211_softmac_scan_syncro(priv->ieee80211);
510 ret = 0;
511 }
512 else
513 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
514 up(&priv->wx_sem);
515 return ret;
516}
517
518
519static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
520 union iwreq_data *wrqu, char *b)
521{
522
523 int ret;
524 struct r8192_priv *priv = ieee80211_priv(dev);
525
526 if(!priv->up) return -ENETDOWN;
527
528 down(&priv->wx_sem);
529
530 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
531
532 up(&priv->wx_sem);
533
534 return ret;
535}
536
537static int r8192_wx_set_essid(struct net_device *dev,
538 struct iw_request_info *a,
539 union iwreq_data *wrqu, char *b)
540{
541 struct r8192_priv *priv = ieee80211_priv(dev);
542 int ret;
543 down(&priv->wx_sem);
544
545 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
546
547 up(&priv->wx_sem);
548
549 return ret;
550}
551
552
553
554
555static int r8192_wx_get_essid(struct net_device *dev,
556 struct iw_request_info *a,
557 union iwreq_data *wrqu, char *b)
558{
559 int ret;
560 struct r8192_priv *priv = ieee80211_priv(dev);
561
562 down(&priv->wx_sem);
563
564 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
565
566 up(&priv->wx_sem);
567
568 return ret;
569}
570
571
572static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
573 union iwreq_data *wrqu, char *b)
574{
575 int ret;
576 struct r8192_priv *priv = ieee80211_priv(dev);
577
578 down(&priv->wx_sem);
579
580 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
581
582 up(&priv->wx_sem);
583 return ret;
584}
585
586static int r8192_wx_get_name(struct net_device *dev,
587 struct iw_request_info *info,
588 union iwreq_data *wrqu, char *extra)
589{
590 struct r8192_priv *priv = ieee80211_priv(dev);
591 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
592}
593
594
595static int r8192_wx_set_frag(struct net_device *dev,
596 struct iw_request_info *info,
597 union iwreq_data *wrqu, char *extra)
598{
599 struct r8192_priv *priv = ieee80211_priv(dev);
600
601 if (wrqu->frag.disabled)
602 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
603 else {
604 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
605 wrqu->frag.value > MAX_FRAG_THRESHOLD)
606 return -EINVAL;
607
608 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
609 }
610
611 return 0;
612}
613
614
615static int r8192_wx_get_frag(struct net_device *dev,
616 struct iw_request_info *info,
617 union iwreq_data *wrqu, char *extra)
618{
619 struct r8192_priv *priv = ieee80211_priv(dev);
620
621 wrqu->frag.value = priv->ieee80211->fts;
622 wrqu->frag.fixed = 0;
623 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
624
625 return 0;
626}
627
628
629static int r8192_wx_set_wap(struct net_device *dev,
630 struct iw_request_info *info,
631 union iwreq_data *awrq,
632 char *extra)
633{
634
635 int ret;
636 struct r8192_priv *priv = ieee80211_priv(dev);
637
638 down(&priv->wx_sem);
639
640 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
641
642 up(&priv->wx_sem);
643
644 return ret;
645
646}
647
648
649static int r8192_wx_get_wap(struct net_device *dev,
650 struct iw_request_info *info,
651 union iwreq_data *wrqu, char *extra)
652{
653 struct r8192_priv *priv = ieee80211_priv(dev);
654
655 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
656}
657
658
659static int r8192_wx_get_enc(struct net_device *dev,
660 struct iw_request_info *info,
661 union iwreq_data *wrqu, char *key)
662{
663 struct r8192_priv *priv = ieee80211_priv(dev);
664
665 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
666}
667
668static int r8192_wx_set_enc(struct net_device *dev,
669 struct iw_request_info *info,
670 union iwreq_data *wrqu, char *key)
671{
672 struct r8192_priv *priv = ieee80211_priv(dev);
673 struct ieee80211_device *ieee = priv->ieee80211;
674 int ret;
675
676
677 u32 hwkey[4]={0,0,0,0};
678 u8 mask=0xff;
679 u32 key_idx=0;
680
681 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
682 {0x00,0x00,0x00,0x00,0x00,0x01},
683 {0x00,0x00,0x00,0x00,0x00,0x02},
684 {0x00,0x00,0x00,0x00,0x00,0x03} };
685 int i;
686
687 if(!priv->up) return -ENETDOWN;
688
689 down(&priv->wx_sem);
690
691 RT_TRACE(COMP_SEC, "Setting SW wep key");
692 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
693
694 up(&priv->wx_sem);
695
696
697
698
699 if(wrqu->encoding.length!=0){
700
701 for(i=0 ; i<4 ; i++){
702 hwkey[i] |= key[4*i+0]&mask;
703 if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
704 if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
705 hwkey[i] |= (key[4*i+1]&mask)<<8;
706 hwkey[i] |= (key[4*i+2]&mask)<<16;
707 hwkey[i] |= (key[4*i+3]&mask)<<24;
708 }
709
710 #define CONF_WEP40 0x4
711 #define CONF_WEP104 0x14
712
713 switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
714 case 0: key_idx = ieee->tx_keyidx; break;
715 case 1: key_idx = 0; break;
716 case 2: key_idx = 1; break;
717 case 3: key_idx = 2; break;
718 case 4: key_idx = 3; break;
719 default: break;
720 }
721
722 if(wrqu->encoding.length==0x5){
723 ieee->pairwise_key_type = KEY_TYPE_WEP40;
724 EnableHWSecurityConfig8192(dev);
725
726 setKey( dev,
727 key_idx,
728 key_idx,
729 KEY_TYPE_WEP40,
730 zero_addr[key_idx],
731 0,
732 hwkey);
733
734 }
735
736 else if(wrqu->encoding.length==0xd){
737 ieee->pairwise_key_type = KEY_TYPE_WEP104;
738 EnableHWSecurityConfig8192(dev);
739
740 setKey( dev,
741 key_idx,
742 key_idx,
743 KEY_TYPE_WEP104,
744 zero_addr[key_idx],
745 0,
746 hwkey);
747
748 }
749 else printk("wrong type in WEP, not WEP40 and WEP104\n");
750
751 }
752
753 return ret;
754}
755
756
757static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
758 iwreq_data *wrqu, char *p){
759
760 struct r8192_priv *priv = ieee80211_priv(dev);
761 int *parms=(int*)p;
762 int mode=parms[0];
763
764 priv->ieee80211->active_scan = mode;
765
766 return 1;
767}
768
769
770
771static int r8192_wx_set_retry(struct net_device *dev,
772 struct iw_request_info *info,
773 union iwreq_data *wrqu, char *extra)
774{
775 struct r8192_priv *priv = ieee80211_priv(dev);
776 int err = 0;
777
778 down(&priv->wx_sem);
779
780 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
781 wrqu->retry.disabled){
782 err = -EINVAL;
783 goto exit;
784 }
785 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
786 err = -EINVAL;
787 goto exit;
788 }
789
790 if(wrqu->retry.value > R8180_MAX_RETRY){
791 err= -EINVAL;
792 goto exit;
793 }
794 if (wrqu->retry.flags & IW_RETRY_MAX) {
795 priv->retry_rts = wrqu->retry.value;
796 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
797
798 }else {
799 priv->retry_data = wrqu->retry.value;
800 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
801 }
802
803
804
805
806
807
808
809 rtl8192_commit(dev);
810
811
812
813
814
815
816
817
818exit:
819 up(&priv->wx_sem);
820
821 return err;
822}
823
824static int r8192_wx_get_retry(struct net_device *dev,
825 struct iw_request_info *info,
826 union iwreq_data *wrqu, char *extra)
827{
828 struct r8192_priv *priv = ieee80211_priv(dev);
829
830
831 wrqu->retry.disabled = 0;
832
833 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
834 IW_RETRY_LIFETIME)
835 return -EINVAL;
836
837 if (wrqu->retry.flags & IW_RETRY_MAX) {
838 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
839 wrqu->retry.value = priv->retry_rts;
840 } else {
841 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
842 wrqu->retry.value = priv->retry_data;
843 }
844
845
846
847 return 0;
848}
849
850static int r8192_wx_get_sens(struct net_device *dev,
851 struct iw_request_info *info,
852 union iwreq_data *wrqu, char *extra)
853{
854 struct r8192_priv *priv = ieee80211_priv(dev);
855 if(priv->rf_set_sens == NULL)
856 return -1;
857 wrqu->sens.value = priv->sens;
858 return 0;
859}
860
861
862static int r8192_wx_set_sens(struct net_device *dev,
863 struct iw_request_info *info,
864 union iwreq_data *wrqu, char *extra)
865{
866
867 struct r8192_priv *priv = ieee80211_priv(dev);
868
869 short err = 0;
870 down(&priv->wx_sem);
871
872 if(priv->rf_set_sens == NULL) {
873 err= -1;
874 goto exit;
875 }
876 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
877 priv->sens = wrqu->sens.value;
878 else
879 err= -EINVAL;
880
881exit:
882 up(&priv->wx_sem);
883
884 return err;
885}
886
887#if (WIRELESS_EXT >= 18)
888
889static int r8192_wx_set_enc_ext(struct net_device *dev,
890 struct iw_request_info *info,
891 union iwreq_data *wrqu, char *extra)
892{
893 int ret=0;
894 struct r8192_priv *priv = ieee80211_priv(dev);
895 struct ieee80211_device* ieee = priv->ieee80211;
896
897
898
899 down(&priv->wx_sem);
900 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
901
902 {
903 u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
904 u8 zero[6] = {0};
905 u32 key[4] = {0};
906 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
907 struct iw_point *encoding = &wrqu->encoding;
908 u8 idx = 0, alg = 0, group = 0;
909 if ((encoding->flags & IW_ENCODE_DISABLED) ||
910 ext->alg == IW_ENCODE_ALG_NONE)
911 goto end_hw_sec;
912
913 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
914 idx = encoding->flags & IW_ENCODE_INDEX;
915 if (idx)
916 idx --;
917 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
918
919 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
920 {
921 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
922 alg = KEY_TYPE_WEP104;
923 ieee->pairwise_key_type = alg;
924 EnableHWSecurityConfig8192(dev);
925 }
926 memcpy((u8*)key, ext->key, 16);
927
928 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
929 {
930
931 setKey( dev,
932 idx,
933 idx,
934 alg,
935 zero,
936 0,
937 key);
938 }
939 else if (group)
940 {
941 ieee->group_key_type = alg;
942 setKey( dev,
943 idx,
944 idx,
945 alg,
946 broadcast_addr,
947 0,
948 key);
949 }
950 else
951 {
952 setKey( dev,
953 4,
954 idx,
955 alg,
956 (u8*)ieee->ap_mac_addr,
957 0,
958 key);
959 }
960
961
962 }
963
964end_hw_sec:
965
966 up(&priv->wx_sem);
967 return ret;
968
969}
970static int r8192_wx_set_auth(struct net_device *dev,
971 struct iw_request_info *info,
972 union iwreq_data *data, char *extra)
973{
974 int ret=0;
975
976 struct r8192_priv *priv = ieee80211_priv(dev);
977 down(&priv->wx_sem);
978 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
979 up(&priv->wx_sem);
980 return ret;
981}
982
983static int r8192_wx_set_mlme(struct net_device *dev,
984 struct iw_request_info *info,
985 union iwreq_data *wrqu, char *extra)
986{
987
988
989 int ret=0;
990 struct r8192_priv *priv = ieee80211_priv(dev);
991 down(&priv->wx_sem);
992 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
993
994 up(&priv->wx_sem);
995 return ret;
996}
997#endif
998static int r8192_wx_set_gen_ie(struct net_device *dev,
999 struct iw_request_info *info,
1000 union iwreq_data *data, char *extra)
1001{
1002
1003 int ret=0;
1004 struct r8192_priv *priv = ieee80211_priv(dev);
1005 down(&priv->wx_sem);
1006 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1007 up(&priv->wx_sem);
1008
1009 return ret;
1010
1011
1012}
1013
1014static int dummy(struct net_device *dev, struct iw_request_info *a,
1015 union iwreq_data *wrqu,char *b)
1016{
1017 return -1;
1018}
1019
1020
1021static iw_handler r8192_wx_handlers[] =
1022{
1023 NULL,
1024 r8192_wx_get_name,
1025 dummy,
1026 dummy,
1027 r8192_wx_set_freq,
1028 r8192_wx_get_freq,
1029 r8192_wx_set_mode,
1030 r8192_wx_get_mode,
1031 r8192_wx_set_sens,
1032 r8192_wx_get_sens,
1033 NULL,
1034 rtl8180_wx_get_range,
1035 NULL,
1036 NULL,
1037 NULL,
1038 NULL,
1039 dummy,
1040 dummy,
1041 NULL,
1042 NULL,
1043 r8192_wx_set_wap,
1044 r8192_wx_get_wap,
1045#if (WIRELESS_EXT >= 18)
1046 r8192_wx_set_mlme,
1047#else
1048 NULL,
1049#endif
1050 dummy,
1051 r8192_wx_set_scan,
1052 r8192_wx_get_scan,
1053 r8192_wx_set_essid,
1054 r8192_wx_get_essid,
1055 dummy,
1056 dummy,
1057 NULL,
1058 NULL,
1059 r8192_wx_set_rate,
1060 r8192_wx_get_rate,
1061 r8192_wx_set_rts,
1062 r8192_wx_get_rts,
1063 r8192_wx_set_frag,
1064 r8192_wx_get_frag,
1065 dummy,
1066 dummy,
1067 r8192_wx_set_retry,
1068 r8192_wx_get_retry,
1069 r8192_wx_set_enc,
1070 r8192_wx_get_enc,
1071 r8192_wx_set_power,
1072 r8192_wx_get_power,
1073 NULL,
1074 NULL,
1075 r8192_wx_set_gen_ie,
1076 NULL,
1077
1078#if (WIRELESS_EXT >= 18)
1079 r8192_wx_set_auth,
1080 NULL,
1081 r8192_wx_set_enc_ext,
1082 NULL,
1083#else
1084 NULL,
1085 NULL,
1086 NULL,
1087 NULL,
1088#endif
1089 NULL,
1090 NULL,
1091
1092};
1093
1094
1095static const struct iw_priv_args r8192_private_args[] = {
1096
1097 {
1098 SIOCIWFIRSTPRIV + 0x0,
1099 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1100 },
1101
1102 {
1103 SIOCIWFIRSTPRIV + 0x1,
1104 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1105
1106 },
1107 {
1108 SIOCIWFIRSTPRIV + 0x2,
1109 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1110 }
1111#ifdef JOHN_IOCTL
1112 ,
1113 {
1114 SIOCIWFIRSTPRIV + 0x3,
1115 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1116 }
1117 ,
1118 {
1119 SIOCIWFIRSTPRIV + 0x4,
1120 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1121 }
1122 ,
1123 {
1124 SIOCIWFIRSTPRIV + 0x5,
1125 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1126 }
1127 ,
1128 {
1129 SIOCIWFIRSTPRIV + 0x6,
1130 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1131 }
1132 ,
1133 {
1134 SIOCIWFIRSTPRIV + 0x7,
1135 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1136 }
1137 ,
1138 {
1139 SIOCIWFIRSTPRIV + 0x8,
1140 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1141 }
1142 ,
1143 {
1144 SIOCIWFIRSTPRIV + 0x9,
1145 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1146 }
1147
1148#endif
1149 ,
1150 {
1151 SIOCIWFIRSTPRIV + 0x3,
1152 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1153
1154 }
1155
1156};
1157
1158
1159static iw_handler r8192_private_handler[] = {
1160
1161 r8192_wx_set_crcmon,
1162
1163
1164
1165 r8192_wx_set_scan_type,
1166 r8192_wx_set_rawtx,
1167#ifdef JOHN_IOCTL
1168 r8192_wx_read_regs,
1169 r8192_wx_write_regs,
1170 r8192_wx_read_bb,
1171 r8192_wx_write_bb,
1172 r8192_wx_read_nicb,
1173 r8192_wx_write_nicb,
1174 r8192_wx_get_ap_status,
1175#endif
1176
1177 r8192_wx_force_reset,
1178};
1179
1180
1181struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1182{
1183 struct r8192_priv *priv = ieee80211_priv(dev);
1184 struct ieee80211_device* ieee = priv->ieee80211;
1185 struct iw_statistics* wstats = &priv->wstats;
1186 int tmp_level = 0;
1187 int tmp_qual = 0;
1188 int tmp_noise = 0;
1189 if(ieee->state < IEEE80211_LINKED)
1190 {
1191 wstats->qual.qual = 0;
1192 wstats->qual.level = 0;
1193 wstats->qual.noise = 0;
1194 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1195 return wstats;
1196 }
1197
1198 tmp_level = (&ieee->current_network)->stats.rssi;
1199 tmp_qual = (&ieee->current_network)->stats.signal;
1200 tmp_noise = (&ieee->current_network)->stats.noise;
1201
1202
1203 wstats->qual.level = tmp_level;
1204 wstats->qual.qual = tmp_qual;
1205 wstats->qual.noise = tmp_noise;
1206 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1207 return wstats;
1208}
1209
1210
1211
1212struct iw_handler_def r8192_wx_handlers_def={
1213 .standard = r8192_wx_handlers,
1214 .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
1215 .private = r8192_private_handler,
1216 .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
1217 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1218#if WIRELESS_EXT >= 17
1219 .get_wireless_stats = r8192_get_wireless_stats,
1220#endif
1221 .private_args = (struct iw_priv_args *)r8192_private_args,
1222};
1223