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