Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rtl8187se / r8180_wx.c
1 /*
2 This file contains wireless extension handlers.
3
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
7
8 Parts of this driver are based on the GPL part
9 of the official realtek driver.
10
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon.
13
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16 We want to thanks the Authors of those projects and the Ndiswrapper
17 project Authors.
18 */
19
20
21 #include "r8180.h"
22 #include "r8180_hw.h"
23
24 #include "ieee80211/dot11d.h"
25
26 u32 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
31 static CHANNEL_LIST DefaultChannelPlan[] = {
32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* FCC */
33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* IC */
34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* ETSI */
35 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Spain. Change to ETSI. */
36 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* France. Change to ETSI. */
37 {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* MKK */
38 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, /* MKK1 */
39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */
40 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */
41 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} /* For Global Domain. 1-11:active scan, 12-14 passive scan.*/ /* +YJ, 080626 */
42 };
43 static 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
53 int 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
76 static 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
99 static 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
108 static 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
118 static 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
139 static 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
173 static 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 /* YJ,add,080819,for hidden ap */
195 struct iw_range_with_scan_capa {
196 /* Informative stuff (to choose between different interface) */
197
198 __u32 throughput; /* To give an idea... */
199
200 /* In theory this value should be the maximum benchmarked
201 * TCP/IP throughput, because with most of these devices the
202 * bit rate is meaningless (overhead an co) to estimate how
203 * fast the connection will go and pick the fastest one.
204 * I suggest people to play with Netperf or any benchmark...
205 */
206
207 /* NWID (or domain id) */
208 __u32 min_nwid; /* Minimal NWID we are able to set */
209 __u32 max_nwid; /* Maximal NWID we are able to set */
210
211 /* Old Frequency (backward compat - moved lower ) */
212 __u16 old_num_channels;
213 __u8 old_num_frequency;
214
215 /* Scan capabilities */
216 __u8 scan_capa;
217 };
218 /* YJ,add,080819,for hidden ap */
219
220
221 static 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 /* Let's try to keep this struct in the same order as in
234 * linux/include/wireless.h
235 */
236
237 /* TODO: See what values we can set, and remove the ones we can't
238 * set, or fill them with some default data.
239 */
240
241 /* ~5 Mb/s real (802.11b) */
242 range->throughput = 5 * 1000 * 1000;
243
244 /* TODO: Not used in 802.11b? */
245 /* range->min_nwid; */ /* Minimal NWID we are able to set */
246 /* TODO: Not used in 802.11b? */
247 /* range->max_nwid; */ /* Maximal NWID we are able to set */
248
249 /* Old Frequency (backward compat - moved lower ) */
250 /* range->old_num_channels; */
251 /* range->old_num_frequency; */
252 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
253 if (priv->rf_set_sens != NULL)
254 range->sensitivity = priv->max_sens; /* signal level threshold range */
255
256 range->max_qual.qual = 100;
257 /* TODO: Find real max RSSI and stick here */
258 range->max_qual.level = 0;
259 range->max_qual.noise = -98;
260 range->max_qual.updated = 7; /* Updated all three */
261
262 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
263 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
264 range->avg_qual.level = 20 + -98;
265 range->avg_qual.noise = 0;
266 range->avg_qual.updated = 7; /* Updated all three */
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 /* Include only legal frequencies for some countries */
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 /* FIXME: do we need to set anything for channels */
293 /* we don't use ? */
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
308 static 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 /* prevent scan in BusyTraffic */
336 /* FIXME: Need to consider last scan time */
337 if ((priv->link_detect.bBusyTraffic) && (true)) {
338 ret = 0;
339 printk("Now traffic is busy, please try later!\n");
340 } else
341 /* prevent scan in BusyTraffic,end */
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
353 static 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
371 static 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
393 static 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
410 static 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
429 static 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
437 static 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
460 static 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; /* no auto select */
468 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
469
470 return 0;
471 }
472
473
474 static 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
495 static 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
505 static 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
529 static 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
539 static 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
554 static 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 /* FIXME !
590 * We might try to write directly the TX config register
591 * or to restart just the (R)TX process.
592 * I'm unsure if whole reset is really needed
593 */
594
595 rtl8180_commit(dev);
596 exit:
597 up(&priv->wx_sem);
598
599 return err;
600 }
601
602 static 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; /* can't be disabled */
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
626 static 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; /* we have not this support for this radio */
633 wrqu->sens.value = priv->sens;
634 return 0;
635 }
636
637
638 static 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; /* we have not this support for this radio */
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
660 exit:
661 up(&priv->wx_sem);
662
663 return err;
664 }
665
666
667 static 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
687 static 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
703 static 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
729 static 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 }
751 static 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; /* no auto select */
761 wrqu->rts.disabled = (wrqu->rts.value == 0);
762
763 return 0;
764 }
765 static int dummy(struct net_device *dev, struct iw_request_info *a,
766 union iwreq_data *wrqu, char *b)
767 {
768 return -1;
769 }
770
771 static 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 }
797 static 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 }
842 static 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; /* 0:auto 1:short 2:long */
855 up(&priv->wx_sem);
856
857 return 0;
858 }
859 static 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 }
882 static 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 /* Modify by hikaru 6.5 */
893 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
894
895
896
897 up(&priv->wx_sem);
898
899 return ret;
900 }
901 static 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 /* Modify by hikaru 6.5 */
912 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
913
914
915
916 up(&priv->wx_sem);
917
918 return ret;
919 }
920 static 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;/* 20060601 */
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 }
960 static 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
979 static 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 }
997 static 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 }
1014 static 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 /* unsigned long flags; */
1027 down(&priv->wx_sem);
1028 if (DefaultChannelPlan[*val].Len != 0) {
1029 priv->channel_plan = *val;
1030 /* Clear old channel map 8 */
1031 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1032 GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1033
1034 /* Set new channel map */
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
1044 static 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 /* struct ieee80211_device *ieee; */
1050
1051 down(&priv->wx_sem);
1052 strcpy(extra, "1020.0808");
1053 up(&priv->wx_sem);
1054
1055 return 0;
1056 }
1057
1058 /* added by amy 080818 */
1059 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1060 static 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
1085 static 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 }
1103 static 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
1119 static 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 }
1138 static 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 }
1158 static iw_handler r8180_wx_handlers[] = {
1159 NULL, /* SIOCSIWCOMMIT */
1160 r8180_wx_get_name, /* SIOCGIWNAME */
1161 dummy, /* SIOCSIWNWID */
1162 dummy, /* SIOCGIWNWID */
1163 r8180_wx_set_freq, /* SIOCSIWFREQ */
1164 r8180_wx_get_freq, /* SIOCGIWFREQ */
1165 r8180_wx_set_mode, /* SIOCSIWMODE */
1166 r8180_wx_get_mode, /* SIOCGIWMODE */
1167 r8180_wx_set_sens, /* SIOCSIWSENS */
1168 r8180_wx_get_sens, /* SIOCGIWSENS */
1169 NULL, /* SIOCSIWRANGE */
1170 rtl8180_wx_get_range, /* SIOCGIWRANGE */
1171 NULL, /* SIOCSIWPRIV */
1172 NULL, /* SIOCGIWPRIV */
1173 NULL, /* SIOCSIWSTATS */
1174 NULL, /* SIOCGIWSTATS */
1175 dummy, /* SIOCSIWSPY */
1176 dummy, /* SIOCGIWSPY */
1177 NULL, /* SIOCGIWTHRSPY */
1178 NULL, /* SIOCWIWTHRSPY */
1179 r8180_wx_set_wap, /* SIOCSIWAP */
1180 r8180_wx_get_wap, /* SIOCGIWAP */
1181 r8180_wx_set_mlme, /* SIOCSIWMLME*/
1182 dummy, /* SIOCGIWAPLIST -- deprecated */
1183 r8180_wx_set_scan, /* SIOCSIWSCAN */
1184 r8180_wx_get_scan, /* SIOCGIWSCAN */
1185 r8180_wx_set_essid, /* SIOCSIWESSID */
1186 r8180_wx_get_essid, /* SIOCGIWESSID */
1187 dummy, /* SIOCSIWNICKN */
1188 dummy, /* SIOCGIWNICKN */
1189 NULL, /* -- hole -- */
1190 NULL, /* -- hole -- */
1191 r8180_wx_set_rate, /* SIOCSIWRATE */
1192 r8180_wx_get_rate, /* SIOCGIWRATE */
1193 r8180_wx_set_rts, /* SIOCSIWRTS */
1194 r8180_wx_get_rts, /* SIOCGIWRTS */
1195 r8180_wx_set_frag, /* SIOCSIWFRAG */
1196 r8180_wx_get_frag, /* SIOCGIWFRAG */
1197 dummy, /* SIOCSIWTXPOW */
1198 dummy, /* SIOCGIWTXPOW */
1199 r8180_wx_set_retry, /* SIOCSIWRETRY */
1200 r8180_wx_get_retry, /* SIOCGIWRETRY */
1201 r8180_wx_set_enc, /* SIOCSIWENCODE */
1202 r8180_wx_get_enc, /* SIOCGIWENCODE */
1203 r8180_wx_set_power, /* SIOCSIWPOWER */
1204 r8180_wx_get_power, /* SIOCGIWPOWER */
1205 NULL, /*---hole---*/
1206 NULL, /*---hole---*/
1207 r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1208 NULL, /* SIOCSIWGENIE */
1209 r8180_wx_set_auth, /* SIOCSIWAUTH */
1210 NULL, /* SIOCSIWAUTH */
1211 r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1212 NULL, /* SIOCSIWENCODEEXT */
1213 NULL, /* SIOCSIWPMKSA */
1214 NULL, /*---hole---*/
1215 };
1216
1217
1218 static 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
1322 static iw_handler r8180_private_handler[] = {
1323 r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1324 dummy,
1325 r8180_wx_set_beaconinterval,
1326 dummy,
1327 /* r8180_wx_set_monitor_type, */
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,/* r8180_wx_get_stats */
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
1351 static inline int is_same_network(struct ieee80211_network *src,
1352 struct ieee80211_network *dst,
1353 struct ieee80211_device *ieee)
1354 {
1355 /* A network is only a duplicate if the channel, BSSID, ESSID
1356 * and the capability field (in particular IBSS and BSS) all match.
1357 * We treat all <hidden> with the same BSSID and channel
1358 * as one network
1359 */
1360 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
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)) && /* YJ,mod, 080819,for hidden ap */
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 /* WB modified to show signal to GUI on 18-01-2008 */
1371 static 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
1399 struct 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