1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "r8180.h"
22#include "r8180_hw.h"
23#include "r8180_sa2400.h"
24
25#ifdef ENABLE_DOT11D
26#include "dot11d.h"
27#endif
28
29
30u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
31 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
32
33#define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
34
35static CHANNEL_LIST DefaultChannelPlan[] = {
36
37 {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19},
38 {{1,2,3,4,5,6,7,8,9,10,11},11},
39 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},
40 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},
41 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},
42 {{14,36,40,44,48,52,56,60,64},9},
43 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},
44 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},
45 {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17},
46 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}
47};
48static int r8180_wx_get_freq(struct net_device *dev,
49 struct iw_request_info *a,
50 union iwreq_data *wrqu, char *b)
51{
52 struct r8180_priv *priv = ieee80211_priv(dev);
53
54 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
55}
56
57
58int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
59 union iwreq_data *wrqu, char *key)
60{
61 struct r8180_priv *priv = ieee80211_priv(dev);
62 struct iw_point *erq = &(wrqu->encoding);
63
64 if(priv->ieee80211->bHwRadioOff)
65 return 0;
66
67 if (erq->flags & IW_ENCODE_DISABLED) {
68 }
69
70
71
72
73
74
75 if (erq->length > 0) {
76
77
78
79 u32* tkey= (u32*) key;
80 priv->key0[0] = tkey[0];
81 priv->key0[1] = tkey[1];
82 priv->key0[2] = tkey[2];
83 priv->key0[3] = tkey[3] &0xff;
84 DMESG("Setting wep key to %x %x %x %x",
85 tkey[0],tkey[1],tkey[2],tkey[3]);
86 rtl8180_set_hw_wep(dev);
87 }
88 return 0;
89}
90
91
92static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
93 union iwreq_data *wrqu, char *b)
94{
95 int *parms = (int *)b;
96 int bi = parms[0];
97
98 struct r8180_priv *priv = ieee80211_priv(dev);
99
100 if(priv->ieee80211->bHwRadioOff)
101 return 0;
102
103 down(&priv->wx_sem);
104 DMESG("setting beacon interval to %x",bi);
105
106 priv->ieee80211->current_network.beacon_interval=bi;
107 rtl8180_commit(dev);
108 up(&priv->wx_sem);
109
110 return 0;
111}
112
113
114
115static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
116 union iwreq_data *wrqu, char *b)
117{
118 struct r8180_priv *priv = ieee80211_priv(dev);
119 return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
120}
121
122
123
124static int r8180_wx_get_rate(struct net_device *dev,
125 struct iw_request_info *info,
126 union iwreq_data *wrqu, char *extra)
127{
128 struct r8180_priv *priv = ieee80211_priv(dev);
129 return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
130}
131
132
133
134static int r8180_wx_set_rate(struct net_device *dev,
135 struct iw_request_info *info,
136 union iwreq_data *wrqu, char *extra)
137{
138 int ret;
139 struct r8180_priv *priv = ieee80211_priv(dev);
140
141
142 if(priv->ieee80211->bHwRadioOff)
143 return 0;
144
145 down(&priv->wx_sem);
146
147 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
148
149 up(&priv->wx_sem);
150
151 return ret;
152}
153
154
155static int r8180_wx_set_crcmon(struct net_device *dev,
156 struct iw_request_info *info,
157 union iwreq_data *wrqu, char *extra)
158{
159 struct r8180_priv *priv = ieee80211_priv(dev);
160 int *parms = (int *)extra;
161 int enable = (parms[0] > 0);
162 short prev = priv->crcmon;
163
164
165 if(priv->ieee80211->bHwRadioOff)
166 return 0;
167
168 down(&priv->wx_sem);
169
170 if(enable)
171 priv->crcmon=1;
172 else
173 priv->crcmon=0;
174
175 DMESG("bad CRC in monitor mode are %s",
176 priv->crcmon ? "accepted" : "rejected");
177
178 if(prev != priv->crcmon && priv->up){
179 rtl8180_down(dev);
180 rtl8180_up(dev);
181 }
182
183 up(&priv->wx_sem);
184
185 return 0;
186}
187
188
189static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
190 union iwreq_data *wrqu, char *b)
191{
192 struct r8180_priv *priv = ieee80211_priv(dev);
193 int ret;
194
195
196 if(priv->ieee80211->bHwRadioOff)
197 return 0;
198
199 down(&priv->wx_sem);
200#ifdef ENABLE_IPS
201
202 if(priv->bInactivePs){
203 if(wrqu->mode == IW_MODE_ADHOC)
204 IPSLeave(dev);
205 }
206#endif
207 ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
208
209
210
211 up(&priv->wx_sem);
212 return ret;
213}
214
215
216struct iw_range_with_scan_capa
217{
218
219 __u32 throughput;
220
221
222
223
224
225
226
227
228 __u32 min_nwid;
229 __u32 max_nwid;
230
231
232 __u16 old_num_channels;
233 __u8 old_num_frequency;
234
235
236 __u8 scan_capa;
237};
238
239
240
241static int rtl8180_wx_get_range(struct net_device *dev,
242 struct iw_request_info *info,
243 union iwreq_data *wrqu, char *extra)
244{
245 struct iw_range *range = (struct iw_range *)extra;
246 struct r8180_priv *priv = ieee80211_priv(dev);
247 u16 val;
248 int i;
249
250
251 wrqu->data.length = sizeof(*range);
252 memset(range, 0, sizeof(*range));
253
254
255
256
257
258
259
260
261
262
263 range->throughput = 5 * 1000 * 1000;
264
265
266
267
268
269
270
271
272
273
274 if(priv->rf_set_sens != NULL)
275 range->sensitivity = priv->max_sens;
276
277 range->max_qual.qual = 100;
278
279 range->max_qual.level = 0;
280 range->max_qual.noise = -98;
281 range->max_qual.updated = 7;
282
283 range->avg_qual.qual = 92;
284
285 range->avg_qual.level = 20 + -98;
286 range->avg_qual.noise = 0;
287 range->avg_qual.updated = 7;
288
289 range->num_bitrates = RATE_COUNT;
290
291 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
292 range->bitrate[i] = rtl8180_rates[i];
293 }
294
295 range->min_frag = MIN_FRAG_THRESHOLD;
296 range->max_frag = MAX_FRAG_THRESHOLD;
297
298 range->pm_capa = 0;
299
300 range->we_version_compiled = WIRELESS_EXT;
301 range->we_version_source = 16;
302
303
304
305
306
307
308
309
310
311 range->num_channels = 14;
312
313 for (i = 0, val = 0; i < 14; i++) {
314
315
316#ifdef ENABLE_DOT11D
317 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
318#else
319 if ((priv->ieee80211->channel_map)[i+1]) {
320#endif
321 range->freq[val].i = i + 1;
322 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
323 range->freq[val].e = 1;
324 val++;
325 } else {
326
327
328 }
329
330 if (val == IW_MAX_FREQUENCIES)
331 break;
332 }
333
334 range->num_frequency = val;
335 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
336 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
337
338
339
340 return 0;
341}
342
343
344static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
345 union iwreq_data *wrqu, char *b)
346{
347 struct r8180_priv *priv = ieee80211_priv(dev);
348 int ret;
349 struct ieee80211_device* ieee = priv->ieee80211;
350
351
352 if(priv->ieee80211->bHwRadioOff)
353 return 0;
354
355
356
357
358 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
359 {
360 struct iw_scan_req* req = (struct iw_scan_req*)b;
361 if (req->essid_len)
362 {
363
364 ieee->current_network.ssid_len = req->essid_len;
365 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
366
367 }
368 }
369
370
371 down(&priv->wx_sem);
372 if(priv->up){
373#ifdef ENABLE_IPS
374
375 priv->ieee80211->actscanning = true;
376 if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
377 IPSLeave(dev);
378
379
380
381
382
383
384
385
386
387
388
389 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
390
391
392
393 ret = 0;
394 }
395 else
396#endif
397 {
398
399
400 if ((priv->link_detect.bBusyTraffic) && (true))
401 {
402 ret = 0;
403 printk("Now traffic is busy, please try later!\n");
404 }
405 else
406
407 ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
408 }
409 }
410 else
411 ret = -1;
412
413 up(&priv->wx_sem);
414
415 return ret;
416}
417
418
419static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
420 union iwreq_data *wrqu, char *b)
421{
422
423 int ret;
424 struct r8180_priv *priv = ieee80211_priv(dev);
425
426 down(&priv->wx_sem);
427 if(priv->up)
428 ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
429 else
430 ret = -1;
431
432 up(&priv->wx_sem);
433 return ret;
434}
435
436
437static int r8180_wx_set_essid(struct net_device *dev,
438 struct iw_request_info *a,
439 union iwreq_data *wrqu, char *b)
440{
441 struct r8180_priv *priv = ieee80211_priv(dev);
442
443 int ret;
444
445 if(priv->ieee80211->bHwRadioOff)
446 return 0;
447
448 down(&priv->wx_sem);
449#ifdef ENABLE_IPS
450
451 if(priv->bInactivePs)
452 IPSLeave(dev);
453#endif
454
455
456 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
457
458 up(&priv->wx_sem);
459 return ret;
460}
461
462
463static int r8180_wx_get_essid(struct net_device *dev,
464 struct iw_request_info *a,
465 union iwreq_data *wrqu, char *b)
466{
467 int ret;
468 struct r8180_priv *priv = ieee80211_priv(dev);
469
470 down(&priv->wx_sem);
471
472 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
473
474 up(&priv->wx_sem);
475
476 return ret;
477}
478
479
480static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
481 union iwreq_data *wrqu, char *b)
482{
483 int ret;
484 struct r8180_priv *priv = ieee80211_priv(dev);
485
486
487 if(priv->ieee80211->bHwRadioOff)
488 return 0;
489
490 down(&priv->wx_sem);
491
492 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
493
494 up(&priv->wx_sem);
495 return ret;
496}
497
498
499static int r8180_wx_get_name(struct net_device *dev,
500 struct iw_request_info *info,
501 union iwreq_data *wrqu, char *extra)
502{
503 struct r8180_priv *priv = ieee80211_priv(dev);
504 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
505}
506
507static int r8180_wx_set_frag(struct net_device *dev,
508 struct iw_request_info *info,
509 union iwreq_data *wrqu, char *extra)
510{
511 struct r8180_priv *priv = ieee80211_priv(dev);
512
513 if(priv->ieee80211->bHwRadioOff)
514 return 0;
515
516 if (wrqu->frag.disabled)
517 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
518 else {
519 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
520 wrqu->frag.value > MAX_FRAG_THRESHOLD)
521 return -EINVAL;
522
523 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
524 }
525
526 return 0;
527}
528
529
530static int r8180_wx_get_frag(struct net_device *dev,
531 struct iw_request_info *info,
532 union iwreq_data *wrqu, char *extra)
533{
534 struct r8180_priv *priv = ieee80211_priv(dev);
535
536 wrqu->frag.value = priv->ieee80211->fts;
537 wrqu->frag.fixed = 0;
538 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
539
540 return 0;
541}
542
543
544static int r8180_wx_set_wap(struct net_device *dev,
545 struct iw_request_info *info,
546 union iwreq_data *awrq,
547 char *extra)
548{
549 int ret;
550 struct r8180_priv *priv = ieee80211_priv(dev);
551
552 if(priv->ieee80211->bHwRadioOff)
553 return 0;
554
555 down(&priv->wx_sem);
556
557 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
558
559 up(&priv->wx_sem);
560 return ret;
561
562}
563
564
565static int r8180_wx_get_wap(struct net_device *dev,
566 struct iw_request_info *info,
567 union iwreq_data *wrqu, char *extra)
568{
569 struct r8180_priv *priv = ieee80211_priv(dev);
570
571 return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
572}
573
574
575static int r8180_wx_set_enc(struct net_device *dev,
576 struct iw_request_info *info,
577 union iwreq_data *wrqu, char *key)
578{
579 struct r8180_priv *priv = ieee80211_priv(dev);
580 int ret;
581
582 if(priv->ieee80211->bHwRadioOff)
583 return 0;
584
585
586 down(&priv->wx_sem);
587
588 if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
589 else{
590 DMESG("Setting SW wep key");
591 ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
592 }
593
594 up(&priv->wx_sem);
595 return ret;
596}
597
598
599static int r8180_wx_get_enc(struct net_device *dev,
600 struct iw_request_info *info,
601 union iwreq_data *wrqu, char *key)
602{
603 struct r8180_priv *priv = ieee80211_priv(dev);
604
605 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
606}
607
608
609static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
610 iwreq_data *wrqu, char *p){
611
612 struct r8180_priv *priv = ieee80211_priv(dev);
613 int *parms=(int*)p;
614 int mode=parms[0];
615
616 if(priv->ieee80211->bHwRadioOff)
617 return 0;
618
619 priv->ieee80211->active_scan = mode;
620
621 return 1;
622}
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646static int r8180_wx_set_retry(struct net_device *dev,
647 struct iw_request_info *info,
648 union iwreq_data *wrqu, char *extra)
649{
650 struct r8180_priv *priv = ieee80211_priv(dev);
651 int err = 0;
652
653 if(priv->ieee80211->bHwRadioOff)
654 return 0;
655
656 down(&priv->wx_sem);
657
658 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
659 wrqu->retry.disabled){
660 err = -EINVAL;
661 goto exit;
662 }
663 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
664 err = -EINVAL;
665 goto exit;
666 }
667
668 if(wrqu->retry.value > R8180_MAX_RETRY){
669 err= -EINVAL;
670 goto exit;
671 }
672 if (wrqu->retry.flags & IW_RETRY_MAX) {
673 priv->retry_rts = wrqu->retry.value;
674 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
675
676 }else {
677 priv->retry_data = wrqu->retry.value;
678 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
679 }
680
681
682
683
684
685
686
687 rtl8180_commit(dev);
688
689
690
691
692
693
694
695
696exit:
697 up(&priv->wx_sem);
698
699 return err;
700}
701
702static int r8180_wx_get_retry(struct net_device *dev,
703 struct iw_request_info *info,
704 union iwreq_data *wrqu, char *extra)
705{
706 struct r8180_priv *priv = ieee80211_priv(dev);
707
708
709 wrqu->retry.disabled = 0;
710
711 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
712 IW_RETRY_LIFETIME)
713 return -EINVAL;
714
715 if (wrqu->retry.flags & IW_RETRY_MAX) {
716 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
717 wrqu->retry.value = priv->retry_rts;
718 } else {
719 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
720 wrqu->retry.value = priv->retry_data;
721 }
722
723
724
725 return 0;
726}
727
728static int r8180_wx_get_sens(struct net_device *dev,
729 struct iw_request_info *info,
730 union iwreq_data *wrqu, char *extra)
731{
732 struct r8180_priv *priv = ieee80211_priv(dev);
733 if(priv->rf_set_sens == NULL)
734 return -1;
735 wrqu->sens.value = priv->sens;
736 return 0;
737}
738
739
740static int r8180_wx_set_sens(struct net_device *dev,
741 struct iw_request_info *info,
742 union iwreq_data *wrqu, char *extra)
743{
744
745 struct r8180_priv *priv = ieee80211_priv(dev);
746
747 short err = 0;
748
749 if(priv->ieee80211->bHwRadioOff)
750 return 0;
751
752 down(&priv->wx_sem);
753
754 if(priv->rf_set_sens == NULL) {
755 err= -1;
756 goto exit;
757 }
758 if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
759 priv->sens = wrqu->sens.value;
760 else
761 err= -EINVAL;
762
763exit:
764 up(&priv->wx_sem);
765
766 return err;
767}
768
769
770static int r8180_wx_set_rawtx(struct net_device *dev,
771 struct iw_request_info *info,
772 union iwreq_data *wrqu, char *extra)
773{
774 struct r8180_priv *priv = ieee80211_priv(dev);
775 int ret;
776
777 if(priv->ieee80211->bHwRadioOff)
778 return 0;
779
780 down(&priv->wx_sem);
781
782 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
783
784 up(&priv->wx_sem);
785
786 return ret;
787
788}
789
790static int r8180_wx_get_power(struct net_device *dev,
791 struct iw_request_info *info,
792 union iwreq_data *wrqu, char *extra)
793{
794 int ret;
795 struct r8180_priv *priv = ieee80211_priv(dev);
796
797 down(&priv->wx_sem);
798
799 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
800
801 up(&priv->wx_sem);
802
803 return ret;
804}
805
806static int r8180_wx_set_power(struct net_device *dev,
807 struct iw_request_info *info,
808 union iwreq_data *wrqu, char *extra)
809{
810 int ret;
811 struct r8180_priv *priv = ieee80211_priv(dev);
812
813
814 if(priv->ieee80211->bHwRadioOff)
815 return 0;
816
817 down(&priv->wx_sem);
818 printk("=>>>>>>>>>>=============================>set power:%d,%d!\n",wrqu->power.disabled, wrqu->power.flags);
819 if (wrqu->power.disabled==0) {
820 wrqu->power.flags|=IW_POWER_ALL_R;
821 wrqu->power.flags|=IW_POWER_TIMEOUT;
822 wrqu->power.value =1000;
823 }
824
825 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
826
827 up(&priv->wx_sem);
828
829 return ret;
830}
831
832static int r8180_wx_set_rts(struct net_device *dev,
833 struct iw_request_info *info,
834 union iwreq_data *wrqu, char *extra)
835{
836 struct r8180_priv *priv = ieee80211_priv(dev);
837
838
839 if(priv->ieee80211->bHwRadioOff)
840 return 0;
841
842 if (wrqu->rts.disabled)
843 priv->rts = DEFAULT_RTS_THRESHOLD;
844 else {
845 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
846 wrqu->rts.value > MAX_RTS_THRESHOLD)
847 return -EINVAL;
848
849 priv->rts = wrqu->rts.value;
850 }
851
852 return 0;
853}
854static int r8180_wx_get_rts(struct net_device *dev,
855 struct iw_request_info *info,
856 union iwreq_data *wrqu, char *extra)
857{
858 struct r8180_priv *priv = ieee80211_priv(dev);
859
860
861
862 wrqu->rts.value = priv->rts;
863 wrqu->rts.fixed = 0;
864 wrqu->rts.disabled = (wrqu->rts.value == 0);
865
866 return 0;
867}
868static int dummy(struct net_device *dev, struct iw_request_info *a,
869 union iwreq_data *wrqu,char *b)
870{
871 return -1;
872}
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926static int r8180_wx_get_iwmode(struct net_device *dev,
927 struct iw_request_info *info,
928 union iwreq_data *wrqu, char *extra)
929{
930 struct r8180_priv *priv = ieee80211_priv(dev);
931 struct ieee80211_device *ieee;
932 int ret = 0;
933
934
935
936 down(&priv->wx_sem);
937
938 ieee = priv->ieee80211;
939
940 strcpy(extra, "802.11");
941 if(ieee->modulation & IEEE80211_CCK_MODULATION) {
942 strcat(extra, "b");
943 if(ieee->modulation & IEEE80211_OFDM_MODULATION)
944 strcat(extra, "/g");
945 } else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
946 strcat(extra, "g");
947
948 up(&priv->wx_sem);
949
950 return ret;
951}
952static int r8180_wx_set_iwmode(struct net_device *dev,
953 struct iw_request_info *info,
954 union iwreq_data *wrqu, char *extra)
955{
956 struct r8180_priv *priv = ieee80211_priv(dev);
957 struct ieee80211_device *ieee = priv->ieee80211;
958 int *param = (int *)extra;
959 int ret = 0;
960 int modulation = 0, mode = 0;
961
962
963 if(priv->ieee80211->bHwRadioOff)
964 return 0;
965
966 down(&priv->wx_sem);
967
968 if (*param == 1) {
969 modulation |= IEEE80211_CCK_MODULATION;
970 mode = IEEE_B;
971 printk(KERN_INFO "B mode!\n");
972 } else if (*param == 2) {
973 modulation |= IEEE80211_OFDM_MODULATION;
974 mode = IEEE_G;
975 printk(KERN_INFO "G mode!\n");
976 } else if (*param == 3) {
977 modulation |= IEEE80211_CCK_MODULATION;
978 modulation |= IEEE80211_OFDM_MODULATION;
979 mode = IEEE_B|IEEE_G;
980 printk(KERN_INFO "B/G mode!\n");
981 }
982
983 if(ieee->proto_started) {
984 ieee80211_stop_protocol(ieee);
985 ieee->mode = mode;
986 ieee->modulation = modulation;
987 ieee80211_start_protocol(ieee);
988 } else {
989 ieee->mode = mode;
990 ieee->modulation = modulation;
991
992 }
993
994 up(&priv->wx_sem);
995
996 return ret;
997}
998static int r8180_wx_get_preamble(struct net_device *dev,
999 struct iw_request_info *info,
1000 union iwreq_data *wrqu, char *extra)
1001{
1002 struct r8180_priv *priv = ieee80211_priv(dev);
1003
1004
1005
1006 down(&priv->wx_sem);
1007
1008
1009
1010 *extra = (char) priv->plcp_preamble_mode;
1011 up(&priv->wx_sem);
1012
1013 return 0;
1014}
1015static int r8180_wx_set_preamble(struct net_device *dev,
1016 struct iw_request_info *info,
1017 union iwreq_data *wrqu, char *extra)
1018{
1019 struct r8180_priv *priv = ieee80211_priv(dev);
1020 int ret = 0;
1021
1022
1023 if(priv->ieee80211->bHwRadioOff)
1024 return 0;
1025
1026 down(&priv->wx_sem);
1027 if (*extra<0||*extra>2)
1028 ret = -1;
1029 else
1030 priv->plcp_preamble_mode = *((short *)extra) ;
1031
1032
1033
1034 up(&priv->wx_sem);
1035
1036 return ret;
1037}
1038static int r8180_wx_get_siglevel(struct net_device *dev,
1039 struct iw_request_info *info,
1040 union iwreq_data *wrqu, char *extra)
1041{
1042 struct r8180_priv *priv = ieee80211_priv(dev);
1043
1044 int ret = 0;
1045
1046
1047
1048 down(&priv->wx_sem);
1049
1050 *((int *)extra) = priv->wstats.qual.level;
1051
1052
1053
1054 up(&priv->wx_sem);
1055
1056 return ret;
1057}
1058static int r8180_wx_get_sigqual(struct net_device *dev,
1059 struct iw_request_info *info,
1060 union iwreq_data *wrqu, char *extra)
1061{
1062 struct r8180_priv *priv = ieee80211_priv(dev);
1063
1064 int ret = 0;
1065
1066
1067
1068 down(&priv->wx_sem);
1069
1070 *((int *)extra) = priv->wstats.qual.qual;
1071
1072
1073
1074 up(&priv->wx_sem);
1075
1076 return ret;
1077}
1078static int r8180_wx_reset_stats(struct net_device *dev,
1079 struct iw_request_info *info,
1080 union iwreq_data *wrqu, char *extra)
1081{
1082 struct r8180_priv *priv =ieee80211_priv(dev);
1083 down(&priv->wx_sem);
1084
1085 priv->stats.txrdu = 0;
1086 priv->stats.rxrdu = 0;
1087 priv->stats.rxnolast = 0;
1088 priv->stats.rxnodata = 0;
1089 priv->stats.rxnopointer = 0;
1090 priv->stats.txnperr = 0;
1091 priv->stats.txresumed = 0;
1092 priv->stats.rxerr = 0;
1093 priv->stats.rxoverflow = 0;
1094 priv->stats.rxint = 0;
1095
1096 priv->stats.txnpokint = 0;
1097 priv->stats.txhpokint = 0;
1098 priv->stats.txhperr = 0;
1099 priv->stats.ints = 0;
1100 priv->stats.shints = 0;
1101 priv->stats.txoverflow = 0;
1102 priv->stats.rxdmafail = 0;
1103 priv->stats.txbeacon = 0;
1104 priv->stats.txbeaconerr = 0;
1105 priv->stats.txlpokint = 0;
1106 priv->stats.txlperr = 0;
1107 priv->stats.txretry =0;
1108 priv->stats.rxcrcerrmin=0;
1109 priv->stats.rxcrcerrmid=0;
1110 priv->stats.rxcrcerrmax=0;
1111 priv->stats.rxicverr=0;
1112
1113 up(&priv->wx_sem);
1114
1115 return 0;
1116
1117}
1118static int r8180_wx_radio_on(struct net_device *dev,
1119 struct iw_request_info *info,
1120 union iwreq_data *wrqu, char *extra)
1121{
1122 struct r8180_priv *priv =ieee80211_priv(dev);
1123
1124 if(priv->ieee80211->bHwRadioOff)
1125 return 0;
1126
1127
1128 down(&priv->wx_sem);
1129 priv->rf_wakeup(dev);
1130
1131 up(&priv->wx_sem);
1132
1133 return 0;
1134
1135}
1136
1137static int r8180_wx_radio_off(struct net_device *dev,
1138 struct iw_request_info *info,
1139 union iwreq_data *wrqu, char *extra)
1140{
1141 struct r8180_priv *priv =ieee80211_priv(dev);
1142
1143 if(priv->ieee80211->bHwRadioOff)
1144 return 0;
1145
1146
1147 down(&priv->wx_sem);
1148 priv->rf_sleep(dev);
1149
1150 up(&priv->wx_sem);
1151
1152 return 0;
1153
1154}
1155static int r8180_wx_get_channelplan(struct net_device *dev,
1156 struct iw_request_info *info,
1157 union iwreq_data *wrqu, char *extra)
1158{
1159 struct r8180_priv *priv = ieee80211_priv(dev);
1160
1161
1162
1163 down(&priv->wx_sem);
1164 *extra = priv->channel_plan;
1165
1166
1167
1168 up(&priv->wx_sem);
1169
1170 return 0;
1171}
1172static int r8180_wx_set_channelplan(struct net_device *dev,
1173 struct iw_request_info *info,
1174 union iwreq_data *wrqu, char *extra)
1175{
1176 struct r8180_priv *priv = ieee80211_priv(dev);
1177
1178 int *val = (int *)extra;
1179 int i;
1180 printk("-----in fun %s\n", __func__);
1181
1182 if(priv->ieee80211->bHwRadioOff)
1183 return 0;
1184
1185
1186 down(&priv->wx_sem);
1187 if (DefaultChannelPlan[*val].Len != 0){
1188 priv ->channel_plan = *val;
1189
1190 for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
1191 {
1192#ifdef ENABLE_DOT11D
1193 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1194#else
1195 priv->ieee80211->channel_map[i] = 0;
1196#endif
1197 }
1198
1199 for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
1200 {
1201#ifdef ENABLE_DOT11D
1202 GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1203#else
1204 priv->ieee80211->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1205#endif
1206 }
1207 }
1208 up(&priv->wx_sem);
1209
1210 return 0;
1211}
1212
1213static int r8180_wx_get_version(struct net_device *dev,
1214 struct iw_request_info *info,
1215 union iwreq_data *wrqu, char *extra)
1216{
1217 struct r8180_priv *priv = ieee80211_priv(dev);
1218
1219
1220 down(&priv->wx_sem);
1221 strcpy(extra, "1020.0808");
1222 up(&priv->wx_sem);
1223
1224 return 0;
1225}
1226
1227
1228
1229static int r8180_wx_set_forcerate(struct net_device *dev,
1230 struct iw_request_info *info,
1231 union iwreq_data *wrqu, char *extra)
1232{
1233 struct r8180_priv *priv = ieee80211_priv(dev);
1234 u8 forcerate = *extra;
1235
1236 down(&priv->wx_sem);
1237
1238 printk("==============>%s(): forcerate is %d\n",__func__,forcerate);
1239 if((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1240 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1241 (forcerate == 96) || (forcerate == 108))
1242 {
1243 priv->ForcedDataRate = 1;
1244 priv->ieee80211->rate = forcerate * 5;
1245 }
1246 else if(forcerate == 0)
1247 {
1248 priv->ForcedDataRate = 0;
1249 printk("OK! return rate adaptive\n");
1250 }
1251 else
1252 printk("ERR: wrong rate\n");
1253 up(&priv->wx_sem);
1254 return 0;
1255}
1256
1257static int r8180_wx_set_enc_ext(struct net_device *dev,
1258 struct iw_request_info *info,
1259 union iwreq_data *wrqu, char *extra)
1260{
1261
1262 struct r8180_priv *priv = ieee80211_priv(dev);
1263
1264
1265 int ret=0;
1266
1267 if(priv->ieee80211->bHwRadioOff)
1268 return 0;
1269
1270 down(&priv->wx_sem);
1271 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1272 up(&priv->wx_sem);
1273 return ret;
1274
1275}
1276static int r8180_wx_set_auth(struct net_device *dev,
1277 struct iw_request_info *info,
1278 union iwreq_data *wrqu, char *extra)
1279{
1280
1281 struct r8180_priv *priv = ieee80211_priv(dev);
1282 int ret=0;
1283
1284 if(priv->ieee80211->bHwRadioOff)
1285 return 0;
1286
1287 down(&priv->wx_sem);
1288 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1289 up(&priv->wx_sem);
1290 return ret;
1291}
1292
1293static int r8180_wx_set_mlme(struct net_device *dev,
1294 struct iw_request_info *info,
1295 union iwreq_data *wrqu, char *extra)
1296{
1297
1298
1299 int ret=0;
1300 struct r8180_priv *priv = ieee80211_priv(dev);
1301
1302
1303 if(priv->ieee80211->bHwRadioOff)
1304 return 0;
1305
1306
1307 down(&priv->wx_sem);
1308#if 1
1309 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1310#endif
1311 up(&priv->wx_sem);
1312 return ret;
1313}
1314static int r8180_wx_set_gen_ie(struct net_device *dev,
1315 struct iw_request_info *info,
1316 union iwreq_data *wrqu, char *extra)
1317{
1318
1319 int ret=0;
1320 struct r8180_priv *priv = ieee80211_priv(dev);
1321
1322
1323 if(priv->ieee80211->bHwRadioOff)
1324 return 0;
1325
1326 down(&priv->wx_sem);
1327#if 1
1328 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1329#endif
1330 up(&priv->wx_sem);
1331
1332 return ret;
1333
1334
1335}
1336static iw_handler r8180_wx_handlers[] =
1337{
1338 NULL,
1339 r8180_wx_get_name,
1340 dummy,
1341 dummy,
1342 r8180_wx_set_freq,
1343 r8180_wx_get_freq,
1344 r8180_wx_set_mode,
1345 r8180_wx_get_mode,
1346 r8180_wx_set_sens,
1347 r8180_wx_get_sens,
1348 NULL,
1349 rtl8180_wx_get_range,
1350 NULL,
1351 NULL,
1352 NULL,
1353 NULL,
1354 dummy,
1355 dummy,
1356 NULL,
1357 NULL,
1358 r8180_wx_set_wap,
1359 r8180_wx_get_wap,
1360 r8180_wx_set_mlme,
1361 dummy,
1362 r8180_wx_set_scan,
1363 r8180_wx_get_scan,
1364 r8180_wx_set_essid,
1365 r8180_wx_get_essid,
1366 dummy,
1367 dummy,
1368 NULL,
1369 NULL,
1370 r8180_wx_set_rate,
1371 r8180_wx_get_rate,
1372 r8180_wx_set_rts,
1373 r8180_wx_get_rts,
1374 r8180_wx_set_frag,
1375 r8180_wx_get_frag,
1376 dummy,
1377 dummy,
1378 r8180_wx_set_retry,
1379 r8180_wx_get_retry,
1380 r8180_wx_set_enc,
1381 r8180_wx_get_enc,
1382 r8180_wx_set_power,
1383 r8180_wx_get_power,
1384 NULL,
1385 NULL,
1386 r8180_wx_set_gen_ie,
1387 NULL,
1388 r8180_wx_set_auth,
1389 NULL,
1390 r8180_wx_set_enc_ext,
1391 NULL,
1392 NULL,
1393 NULL,
1394};
1395
1396
1397static const struct iw_priv_args r8180_private_args[] = {
1398 {
1399 SIOCIWFIRSTPRIV + 0x0,
1400 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1401 },
1402 { SIOCIWFIRSTPRIV + 0x1,
1403 0, 0, "dummy"
1404
1405 },
1406 {
1407 SIOCIWFIRSTPRIV + 0x2,
1408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1409 },
1410 { SIOCIWFIRSTPRIV + 0x3,
1411 0, 0, "dummy"
1412
1413 },
1414
1415
1416
1417
1418
1419
1420 {
1421 SIOCIWFIRSTPRIV + 0x4,
1422 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1423
1424 },
1425 { SIOCIWFIRSTPRIV + 0x5,
1426 0, 0, "dummy"
1427
1428 },
1429 {
1430 SIOCIWFIRSTPRIV + 0x6,
1431 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1432
1433 },
1434 { SIOCIWFIRSTPRIV + 0x7,
1435 0, 0, "dummy"
1436
1437 },
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448 {
1449 SIOCIWFIRSTPRIV + 0x8,
1450 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
1451 },
1452 {
1453 SIOCIWFIRSTPRIV + 0x9,
1454 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
1455 },
1456 {
1457 SIOCIWFIRSTPRIV + 0xA,
1458 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
1459 },
1460 {
1461 SIOCIWFIRSTPRIV + 0xB,
1462 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
1463 },
1464 { SIOCIWFIRSTPRIV + 0xC,
1465 0, 0, "dummy"
1466 },
1467 {
1468 SIOCIWFIRSTPRIV + 0xD,
1469 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1470 },
1471 { SIOCIWFIRSTPRIV + 0xE,
1472 0, 0, "dummy"
1473 },
1474 {
1475 SIOCIWFIRSTPRIV + 0xF,
1476 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1477 },
1478 {
1479 SIOCIWFIRSTPRIV + 0x10,
1480 0, 0, "resetstats"
1481 },
1482 {
1483 SIOCIWFIRSTPRIV + 0x11,
1484 0,0, "dummy"
1485 },
1486 {
1487 SIOCIWFIRSTPRIV + 0x12,
1488 0, 0, "radioon"
1489 },
1490 {
1491 SIOCIWFIRSTPRIV + 0x13,
1492 0, 0, "radiooff"
1493 },
1494 {
1495 SIOCIWFIRSTPRIV + 0x14,
1496 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
1497 },
1498 {
1499 SIOCIWFIRSTPRIV + 0x15,
1500 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
1501 },
1502 {
1503 SIOCIWFIRSTPRIV + 0x16,
1504 0,0, "dummy"
1505 },
1506 {
1507 SIOCIWFIRSTPRIV + 0x17,
1508 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
1509 },
1510 {
1511 SIOCIWFIRSTPRIV + 0x18,
1512 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
1513 },
1514};
1515
1516
1517static iw_handler r8180_private_handler[] = {
1518 r8180_wx_set_crcmon,
1519 dummy,
1520 r8180_wx_set_beaconinterval,
1521 dummy,
1522
1523 r8180_wx_set_scan_type,
1524 dummy,
1525 r8180_wx_set_rawtx,
1526 dummy,
1527 r8180_wx_set_iwmode,
1528 r8180_wx_get_iwmode,
1529 r8180_wx_set_preamble,
1530 r8180_wx_get_preamble,
1531 dummy,
1532 r8180_wx_get_siglevel,
1533 dummy,
1534 r8180_wx_get_sigqual,
1535 r8180_wx_reset_stats,
1536 dummy,
1537 r8180_wx_radio_on,
1538 r8180_wx_radio_off,
1539 r8180_wx_set_channelplan,
1540 r8180_wx_get_channelplan,
1541 dummy,
1542 r8180_wx_get_version,
1543 r8180_wx_set_forcerate,
1544};
1545
1546#if WIRELESS_EXT >= 17
1547static inline int is_same_network(struct ieee80211_network *src,
1548 struct ieee80211_network *dst,
1549 struct ieee80211_device *ieee)
1550{
1551
1552
1553
1554
1555 return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) &&
1556
1557 (src->channel == dst->channel) &&
1558 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1559 (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) &&
1560
1561 ((src->capability & WLAN_CAPABILITY_IBSS) ==
1562 (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1563 ((src->capability & WLAN_CAPABILITY_BSS) ==
1564 (dst->capability & WLAN_CAPABILITY_BSS)));
1565}
1566
1567
1568static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1569{
1570 struct r8180_priv *priv = ieee80211_priv(dev);
1571 struct ieee80211_device* ieee = priv->ieee80211;
1572 struct iw_statistics* wstats = &priv->wstats;
1573
1574 int tmp_level = 0;
1575 int tmp_qual = 0;
1576 int tmp_noise = 0;
1577
1578
1579 if (ieee->state < IEEE80211_LINKED)
1580 {
1581 wstats->qual.qual = 0;
1582 wstats->qual.level = 0;
1583 wstats->qual.noise = 0;
1584 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1585 return wstats;
1586 }
1587#if 0
1588 spin_lock_irqsave(&ieee->lock, flag);
1589 list_for_each_entry(target, &ieee->network_list, list)
1590 {
1591 if (is_same_network(target, &ieee->current_network, ieee))
1592 {
1593 printk("it's same network:%s\n", target->ssid);
1594#if 0
1595 if (!tmp_level)
1596 {
1597 tmp_level = target->stats.signalstrength;
1598 tmp_qual = target->stats.signal;
1599 }
1600 else
1601 {
1602
1603 tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
1604 tmp_qual = (15*tmp_qual + target->stats.signal)/16;
1605 }
1606#else
1607 tmp_level = target->stats.signal;
1608 tmp_qual = target->stats.signalstrength;
1609 tmp_noise = target->stats.noise;
1610 printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1611#endif
1612 break;
1613 }
1614 }
1615 spin_unlock_irqrestore(&ieee->lock, flag);
1616#endif
1617 tmp_level = (&ieee->current_network)->stats.signal;
1618 tmp_qual = (&ieee->current_network)->stats.signalstrength;
1619 tmp_noise = (&ieee->current_network)->stats.noise;
1620
1621
1622
1623 wstats->qual.level = tmp_level;
1624 wstats->qual.qual = tmp_qual;
1625 wstats->qual.noise = tmp_noise;
1626 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1627 return wstats;
1628}
1629#endif
1630
1631
1632struct iw_handler_def r8180_wx_handlers_def={
1633 .standard = r8180_wx_handlers,
1634 .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
1635 .private = r8180_private_handler,
1636 .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
1637 .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1638#if WIRELESS_EXT >= 17
1639 .get_wireless_stats = r8180_get_wireless_stats,
1640#endif
1641 .private_args = (struct iw_priv_args *)r8180_private_args,
1642};
1643
1644
1645