Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
r8180_wx.c
Go to the documentation of this file.
1 /*
2  This file contains wireless extension handlers.
3 
4  This is part of rtl8180 OpenSource driver.
5  Copyright (C) Andrea Merello 2004-2005 <[email protected]>
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 
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 
78 static 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 
101 static 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 
110 static 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 
120 static 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 
141 static 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 
175 static 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 /* YJ,add,080819,for hidden ap */
198  /* Informative stuff (to choose between different interface) */
199 
200  __u32 throughput; /* To give an idea... */
201 
202  /* In theory this value should be the maximum benchmarked
203  * TCP/IP throughput, because with most of these devices the
204  * bit rate is meaningless (overhead an co) to estimate how
205  * fast the connection will go and pick the fastest one.
206  * I suggest people to play with Netperf or any benchmark...
207  */
208 
209  /* NWID (or domain id) */
210  __u32 min_nwid; /* Minimal NWID we are able to set */
211  __u32 max_nwid; /* Maximal NWID we are able to set */
212 
213  /* Old Frequency (backward compat - moved lower ) */
216 
217  /* Scan capabilities */
219 };
220 /* YJ,add,080819,for hidden ap */
221 
222 
223 static 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  /* Let's try to keep this struct in the same order as in
236  * linux/include/wireless.h
237  */
238 
239  /* TODO: See what values we can set, and remove the ones we can't
240  * set, or fill them with some default data.
241  */
242 
243  /* ~5 Mb/s real (802.11b) */
244  range->throughput = 5 * 1000 * 1000;
245 
246  /* TODO: Not used in 802.11b? */
247 /* range->min_nwid; */ /* Minimal NWID we are able to set */
248  /* TODO: Not used in 802.11b? */
249 /* range->max_nwid; */ /* Maximal NWID we are able to set */
250 
251  /* Old Frequency (backward compat - moved lower ) */
252 /* range->old_num_channels; */
253 /* range->old_num_frequency; */
254 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
255  if (priv->rf_set_sens != NULL)
256  range->sensitivity = priv->max_sens; /* signal level threshold range */
257 
258  range->max_qual.qual = 100;
259  /* TODO: Find real max RSSI and stick here */
260  range->max_qual.level = 0;
261  range->max_qual.noise = -98;
262  range->max_qual.updated = 7; /* Updated all three */
263 
264  range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
265  /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
266  range->avg_qual.level = 20 + -98;
267  range->avg_qual.noise = 0;
268  range->avg_qual.updated = 7; /* Updated all three */
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 
281  range->we_version_source = 16;
282 
283  range->num_channels = 14;
284 
285  for (i = 0, val = 0; i < 14; i++) {
286 
287  /* Include only legal frequencies for some countries */
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  /* FIXME: do we need to set anything for channels */
295  /* we don't use ? */
296  }
297 
298  if (val == IW_MAX_FREQUENCIES)
299  break;
300  }
301 
302  range->num_frequency = val;
305 
306  return 0;
307 }
308 
309 
310 static 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);
335  ret = 0;
336  } else {
337  /* prevent scan in BusyTraffic */
338  /* FIXME: Need to consider last scan time */
339  if ((priv->link_detect.bBusyTraffic) && (true)) {
340  ret = 0;
341  printk("Now traffic is busy, please try later!\n");
342  } else
343  /* prevent scan in BusyTraffic,end */
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 
355 static 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 
373 static 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 
395 static 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 
412 static 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 
431 static 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 
439 static 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 
462 static 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; /* no auto select */
470  wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
471 
472  return 0;
473 }
474 
475 
476 static 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 
497 static 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 
507 static 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 
531 static 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 
541 static 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 
556 static 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  /* FIXME !
592  * We might try to write directly the TX config register
593  * or to restart just the (R)TX process.
594  * I'm unsure if whole reset is really needed
595  */
596 
597  rtl8180_commit(dev);
598 exit:
599  up(&priv->wx_sem);
600 
601  return err;
602 }
603 
604 static 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; /* can't be disabled */
612 
613  if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
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 
628 static 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; /* we have not this support for this radio */
635  wrqu->sens.value = priv->sens;
636  return 0;
637 }
638 
639 
640 static 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; /* we have not this support for this radio */
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 
662 exit:
663  up(&priv->wx_sem);
664 
665  return err;
666 }
667 
668 
669 static 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 
689 static 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 
705 static 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 
731 static 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 }
753 static 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; /* no auto select */
763  wrqu->rts.disabled = (wrqu->rts.value == 0);
764 
765  return 0;
766 }
767 static int dummy(struct net_device *dev, struct iw_request_info *a,
768  union iwreq_data *wrqu, char *b)
769 {
770  return -1;
771 }
772 
773 static 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");
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 }
799 static 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) {
832  ieee->mode = mode;
833  ieee->modulation = modulation;
835  } else {
836  ieee->mode = mode;
837  ieee->modulation = modulation;
838  }
839 
840  up(&priv->wx_sem);
841 
842  return ret;
843 }
844 static 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; /* 0:auto 1:short 2:long */
857  up(&priv->wx_sem);
858 
859  return 0;
860 }
861 static 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 }
884 static 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  /* Modify by hikaru 6.5 */
895  *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
896 
897 
898 
899  up(&priv->wx_sem);
900 
901  return ret;
902 }
903 static 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  /* Modify by hikaru 6.5 */
914  *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
915 
916 
917 
918  up(&priv->wx_sem);
919 
920  return ret;
921 }
922 static 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;/* 20060601 */
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 }
962 static 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 
981 static 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 }
999 static 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 }
1016 static 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  /* unsigned long flags; */
1029  down(&priv->wx_sem);
1030  if (DefaultChannelPlan[*val].Len != 0) {
1031  priv->channel_plan = *val;
1032  /* Clear old channel map 8 */
1033  for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1034  GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1035 
1036  /* Set new channel map */
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 
1046 static 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  /* struct ieee80211_device *ieee; */
1052 
1053  down(&priv->wx_sem);
1054  strcpy(extra, "1020.0808");
1055  up(&priv->wx_sem);
1056 
1057  return 0;
1058 }
1059 
1060 /* added by amy 080818 */
1061 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1062 static 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 
1087 static 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 }
1105 static 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 
1121 static 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 }
1140 static 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 }
1160 static iw_handler r8180_wx_handlers[] = {
1161  NULL, /* SIOCSIWCOMMIT */
1162  r8180_wx_get_name, /* SIOCGIWNAME */
1163  dummy, /* SIOCSIWNWID */
1164  dummy, /* SIOCGIWNWID */
1165  r8180_wx_set_freq, /* SIOCSIWFREQ */
1166  r8180_wx_get_freq, /* SIOCGIWFREQ */
1167  r8180_wx_set_mode, /* SIOCSIWMODE */
1168  r8180_wx_get_mode, /* SIOCGIWMODE */
1169  r8180_wx_set_sens, /* SIOCSIWSENS */
1170  r8180_wx_get_sens, /* SIOCGIWSENS */
1171  NULL, /* SIOCSIWRANGE */
1172  rtl8180_wx_get_range, /* SIOCGIWRANGE */
1173  NULL, /* SIOCSIWPRIV */
1174  NULL, /* SIOCGIWPRIV */
1175  NULL, /* SIOCSIWSTATS */
1176  NULL, /* SIOCGIWSTATS */
1177  dummy, /* SIOCSIWSPY */
1178  dummy, /* SIOCGIWSPY */
1179  NULL, /* SIOCGIWTHRSPY */
1180  NULL, /* SIOCWIWTHRSPY */
1181  r8180_wx_set_wap, /* SIOCSIWAP */
1182  r8180_wx_get_wap, /* SIOCGIWAP */
1183  r8180_wx_set_mlme, /* SIOCSIWMLME*/
1184  dummy, /* SIOCGIWAPLIST -- deprecated */
1185  r8180_wx_set_scan, /* SIOCSIWSCAN */
1186  r8180_wx_get_scan, /* SIOCGIWSCAN */
1187  r8180_wx_set_essid, /* SIOCSIWESSID */
1188  r8180_wx_get_essid, /* SIOCGIWESSID */
1189  dummy, /* SIOCSIWNICKN */
1190  dummy, /* SIOCGIWNICKN */
1191  NULL, /* -- hole -- */
1192  NULL, /* -- hole -- */
1193  r8180_wx_set_rate, /* SIOCSIWRATE */
1194  r8180_wx_get_rate, /* SIOCGIWRATE */
1195  r8180_wx_set_rts, /* SIOCSIWRTS */
1196  r8180_wx_get_rts, /* SIOCGIWRTS */
1197  r8180_wx_set_frag, /* SIOCSIWFRAG */
1198  r8180_wx_get_frag, /* SIOCGIWFRAG */
1199  dummy, /* SIOCSIWTXPOW */
1200  dummy, /* SIOCGIWTXPOW */
1201  r8180_wx_set_retry, /* SIOCSIWRETRY */
1202  r8180_wx_get_retry, /* SIOCGIWRETRY */
1203  r8180_wx_set_enc, /* SIOCSIWENCODE */
1204  r8180_wx_get_enc, /* SIOCGIWENCODE */
1205  r8180_wx_set_power, /* SIOCSIWPOWER */
1206  r8180_wx_get_power, /* SIOCGIWPOWER */
1207  NULL, /*---hole---*/
1208  NULL, /*---hole---*/
1209  r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
1210  NULL, /* SIOCSIWGENIE */
1211  r8180_wx_set_auth, /* SIOCSIWAUTH */
1212  NULL, /* SIOCSIWAUTH */
1213  r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1214  NULL, /* SIOCSIWENCODEEXT */
1215  NULL, /* SIOCSIWPMKSA */
1216  NULL, /*---hole---*/
1217 };
1218 
1219 
1220 static 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 
1324 static iw_handler r8180_private_handler[] = {
1325  r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1326  dummy,
1327  r8180_wx_set_beaconinterval,
1328  dummy,
1329  /* r8180_wx_set_monitor_type, */
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,/* r8180_wx_get_stats */
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 
1353 static inline int is_same_network(struct ieee80211_network *src,
1354  struct ieee80211_network *dst,
1355  struct ieee80211_device *ieee)
1356 {
1357  /* A network is only a duplicate if the channel, BSSID, ESSID
1358  * and the capability field (in particular IBSS and BSS) all match.
1359  * We treat all <hidden> with the same BSSID and channel
1360  * as one network
1361  */
1362  return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
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)) && /* YJ,mod, 080819,for hidden ap */
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 /* WB modified to show signal to GUI on 18-01-2008 */
1373 static 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 
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