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