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