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