]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/rtl8187se/r8180_wx.c
staging: rtl8187se: Fix trailing whitespace in r8180_hw.h and r8180_wx.c
[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 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 CHANNEL_LIST DefaultChannelPlan[] = {
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.bBusyTraffic) && (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) 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,
542                                   struct iw_request_info *aa,
543                                   union iwreq_data *wrqu, char *p)
544 {
545
546         struct r8180_priv *priv = ieee80211_priv(dev);
547         int *parms = (int*)p;
548         int mode = parms[0];
549
550         if (priv->ieee80211->bHwRadioOff)
551                 return 0;
552
553         priv->ieee80211->active_scan = mode;
554
555         return 1;
556 }
557
558 static int r8180_wx_set_retry(struct net_device *dev,
559                               struct iw_request_info *info,
560                               union iwreq_data *wrqu, char *extra)
561 {
562         struct r8180_priv *priv = ieee80211_priv(dev);
563         int err = 0;
564
565         if (priv->ieee80211->bHwRadioOff)
566                 return 0;
567
568         down(&priv->wx_sem);
569
570         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
571             wrqu->retry.disabled)       {
572                 err = -EINVAL;
573                 goto exit;
574         }
575         if (!(wrqu->retry.flags & IW_RETRY_LIMIT))      {
576                 err = -EINVAL;
577                 goto exit;
578         }
579
580         if (wrqu->retry.value > R8180_MAX_RETRY)        {
581                 err = -EINVAL;
582                 goto exit;
583         }
584         if (wrqu->retry.flags & IW_RETRY_MAX) {
585                 priv->retry_rts = wrqu->retry.value;
586                 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
587
588         }       else {
589                 priv->retry_data = wrqu->retry.value;
590                 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
591         }
592
593         /* FIXME !
594          * We might try to write directly the TX config register
595          * or to restart just the (R)TX process.
596          * I'm unsure if whole reset is really needed
597          */
598
599         rtl8180_commit(dev);
600 exit:
601         up(&priv->wx_sem);
602
603         return err;
604 }
605
606 static int r8180_wx_get_retry(struct net_device *dev,
607                               struct iw_request_info *info,
608                               union iwreq_data *wrqu, char *extra)
609 {
610         struct r8180_priv *priv = ieee80211_priv(dev);
611
612
613         wrqu->retry.disabled = 0; /* can't be disabled */
614
615         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
616             IW_RETRY_LIFETIME)
617                 return -EINVAL;
618
619         if (wrqu->retry.flags & IW_RETRY_MAX) {
620                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
621                 wrqu->retry.value = priv->retry_rts;
622         } else {
623                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
624                 wrqu->retry.value = priv->retry_data;
625         }
626
627         return 0;
628 }
629
630 static int r8180_wx_get_sens(struct net_device *dev,
631                              struct iw_request_info *info,
632                              union iwreq_data *wrqu, char *extra)
633 {
634         struct r8180_priv *priv = ieee80211_priv(dev);
635         if (priv->rf_set_sens == NULL)
636                 return -1; /* we have not this support for this radio */
637         wrqu->sens.value = priv->sens;
638         return 0;
639 }
640
641
642 static int r8180_wx_set_sens(struct net_device *dev,
643                              struct iw_request_info *info,
644                              union iwreq_data *wrqu, char *extra)
645 {
646
647         struct r8180_priv *priv = ieee80211_priv(dev);
648
649         short err = 0;
650
651         if (priv->ieee80211->bHwRadioOff)
652                 return 0;
653
654         down(&priv->wx_sem);
655         if (priv->rf_set_sens == NULL) {
656                 err = -1; /* we have not this support for this radio */
657                 goto exit;
658         }
659         if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
660                 priv->sens = wrqu->sens.value;
661         else
662                 err = -EINVAL;
663
664 exit:
665         up(&priv->wx_sem);
666
667         return err;
668 }
669
670
671 static int r8180_wx_set_rawtx(struct net_device *dev,
672                               struct iw_request_info *info,
673                               union iwreq_data *wrqu, char *extra)
674 {
675         struct r8180_priv *priv = ieee80211_priv(dev);
676         int ret;
677
678         if (priv->ieee80211->bHwRadioOff)
679                 return 0;
680
681         down(&priv->wx_sem);
682
683         ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
684
685         up(&priv->wx_sem);
686
687         return ret;
688
689 }
690
691 static int r8180_wx_get_power(struct net_device *dev,
692                               struct iw_request_info *info,
693                               union iwreq_data *wrqu, char *extra)
694 {
695         int ret;
696         struct r8180_priv *priv = ieee80211_priv(dev);
697
698         down(&priv->wx_sem);
699
700         ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
701
702         up(&priv->wx_sem);
703
704         return ret;
705 }
706
707 static int r8180_wx_set_power(struct net_device *dev,
708                               struct iw_request_info *info,
709                               union iwreq_data *wrqu, char *extra)
710 {
711         int ret;
712         struct r8180_priv *priv = ieee80211_priv(dev);
713
714
715         if (priv->ieee80211->bHwRadioOff)
716                 return 0;
717
718         down(&priv->wx_sem);
719         printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
720         if (wrqu->power.disabled == 0) {
721                 wrqu->power.flags |= IW_POWER_ALL_R;
722                 wrqu->power.flags |= IW_POWER_TIMEOUT;
723                 wrqu->power.value = 1000;
724         }
725
726         ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
727
728         up(&priv->wx_sem);
729
730         return ret;
731 }
732
733 static int r8180_wx_set_rts(struct net_device *dev,
734                             struct iw_request_info *info,
735                             union iwreq_data *wrqu, char *extra)
736 {
737         struct r8180_priv *priv = ieee80211_priv(dev);
738
739
740         if (priv->ieee80211->bHwRadioOff)
741                 return 0;
742
743         if (wrqu->rts.disabled)
744                 priv->rts = DEFAULT_RTS_THRESHOLD;
745         else {
746                 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
747                     wrqu->rts.value > MAX_RTS_THRESHOLD)
748                         return -EINVAL;
749
750                 priv->rts = wrqu->rts.value;
751         }
752
753         return 0;
754 }
755 static int r8180_wx_get_rts(struct net_device *dev,
756                             struct iw_request_info *info,
757                             union iwreq_data *wrqu, char *extra)
758 {
759         struct r8180_priv *priv = ieee80211_priv(dev);
760
761
762
763         wrqu->rts.value = priv->rts;
764         wrqu->rts.fixed = 0;    /* no auto select */
765         wrqu->rts.disabled = (wrqu->rts.value == 0);
766
767         return 0;
768 }
769 static int dummy(struct net_device *dev, struct iw_request_info *a,
770                  union iwreq_data *wrqu, char *b)
771 {
772         return -1;
773 }
774
775 static int r8180_wx_get_iwmode(struct net_device *dev,
776                                struct iw_request_info *info,
777                                union iwreq_data *wrqu, char *extra)
778 {
779         struct r8180_priv *priv = ieee80211_priv(dev);
780         struct ieee80211_device *ieee;
781         int ret = 0;
782
783
784
785         down(&priv->wx_sem);
786
787         ieee = priv->ieee80211;
788
789         strcpy(extra, "802.11");
790         if (ieee->modulation & IEEE80211_CCK_MODULATION) {
791                 strcat(extra, "b");
792                 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
793                         strcat(extra, "/g");
794         } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
795                 strcat(extra, "g");
796
797         up(&priv->wx_sem);
798
799         return ret;
800 }
801 static int r8180_wx_set_iwmode(struct net_device *dev,
802                                struct iw_request_info *info,
803                                union iwreq_data *wrqu, char *extra)
804 {
805         struct r8180_priv *priv = ieee80211_priv(dev);
806         struct ieee80211_device *ieee = priv->ieee80211;
807         int *param = (int *)extra;
808         int ret = 0;
809         int modulation = 0, mode = 0;
810
811
812         if (priv->ieee80211->bHwRadioOff)
813                 return 0;
814
815         down(&priv->wx_sem);
816
817         if (*param == 1) {
818                 modulation |= IEEE80211_CCK_MODULATION;
819                 mode = IEEE_B;
820         printk(KERN_INFO "B mode!\n");
821         } else if (*param == 2) {
822                 modulation |= IEEE80211_OFDM_MODULATION;
823                 mode = IEEE_G;
824         printk(KERN_INFO "G mode!\n");
825         } else if (*param == 3) {
826                 modulation |= IEEE80211_CCK_MODULATION;
827                 modulation |= IEEE80211_OFDM_MODULATION;
828                 mode = IEEE_B|IEEE_G;
829         printk(KERN_INFO "B/G mode!\n");
830         }
831
832         if (ieee->proto_started) {
833                 ieee80211_stop_protocol(ieee);
834                 ieee->mode = mode;
835                 ieee->modulation = modulation;
836                 ieee80211_start_protocol(ieee);
837         } else {
838                 ieee->mode = mode;
839                 ieee->modulation = modulation;
840         }
841
842         up(&priv->wx_sem);
843
844         return ret;
845 }
846 static int r8180_wx_get_preamble(struct net_device *dev,
847                                  struct iw_request_info *info,
848                                  union iwreq_data *wrqu, char *extra)
849 {
850         struct r8180_priv *priv = ieee80211_priv(dev);
851
852
853
854         down(&priv->wx_sem);
855
856
857
858         *extra = (char) priv->plcp_preamble_mode;       /* 0:auto 1:short 2:long */
859         up(&priv->wx_sem);
860
861         return 0;
862 }
863 static int r8180_wx_set_preamble(struct net_device *dev,
864                                  struct iw_request_info *info,
865                                  union iwreq_data *wrqu, char *extra)
866 {
867         struct r8180_priv *priv = ieee80211_priv(dev);
868         int ret = 0;
869
870
871         if (priv->ieee80211->bHwRadioOff)
872                 return 0;
873
874         down(&priv->wx_sem);
875         if (*extra < 0 || *extra > 2)
876                 ret = -1;
877         else
878                 priv->plcp_preamble_mode = *((short *)extra) ;
879
880
881
882         up(&priv->wx_sem);
883
884         return ret;
885 }
886 static int r8180_wx_get_siglevel(struct net_device *dev,
887                                  struct iw_request_info *info,
888                                  union iwreq_data *wrqu, char *extra)
889 {
890         struct r8180_priv *priv = ieee80211_priv(dev);
891         int ret = 0;
892
893
894
895         down(&priv->wx_sem);
896         /* Modify by hikaru 6.5 */
897         *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
898
899
900
901         up(&priv->wx_sem);
902
903         return ret;
904 }
905 static int r8180_wx_get_sigqual(struct net_device *dev,
906                                 struct iw_request_info *info,
907                                 union iwreq_data *wrqu, char *extra)
908 {
909         struct r8180_priv *priv = ieee80211_priv(dev);
910         int ret = 0;
911
912
913
914         down(&priv->wx_sem);
915         /* Modify by hikaru 6.5 */
916         *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
917
918
919
920         up(&priv->wx_sem);
921
922         return ret;
923 }
924 static int r8180_wx_reset_stats(struct net_device *dev,
925                                 struct iw_request_info *info,
926                                 union iwreq_data *wrqu, char *extra)
927 {
928         struct r8180_priv *priv = ieee80211_priv(dev);
929         down(&priv->wx_sem);
930
931         priv->stats.txrdu = 0;
932         priv->stats.rxrdu = 0;
933         priv->stats.rxnolast = 0;
934         priv->stats.rxnodata = 0;
935         priv->stats.rxnopointer = 0;
936         priv->stats.txnperr = 0;
937         priv->stats.txresumed = 0;
938         priv->stats.rxerr = 0;
939         priv->stats.rxoverflow = 0;
940         priv->stats.rxint = 0;
941
942         priv->stats.txnpokint = 0;
943         priv->stats.txhpokint = 0;
944         priv->stats.txhperr = 0;
945         priv->stats.ints = 0;
946         priv->stats.shints = 0;
947         priv->stats.txoverflow = 0;
948         priv->stats.rxdmafail = 0;
949         priv->stats.txbeacon = 0;
950         priv->stats.txbeaconerr = 0;
951         priv->stats.txlpokint = 0;
952         priv->stats.txlperr = 0;
953         priv->stats.txretry = 0;/* 20060601 */
954         priv->stats.rxcrcerrmin = 0 ;
955         priv->stats.rxcrcerrmid = 0;
956         priv->stats.rxcrcerrmax = 0;
957         priv->stats.rxicverr = 0;
958
959         up(&priv->wx_sem);
960
961         return 0;
962
963 }
964 static int r8180_wx_radio_on(struct net_device *dev,
965                              struct iw_request_info *info,
966                              union iwreq_data *wrqu, char *extra)
967 {
968         struct r8180_priv *priv = ieee80211_priv(dev);
969
970         if (priv->ieee80211->bHwRadioOff)
971                 return 0;
972
973
974         down(&priv->wx_sem);
975         priv->rf_wakeup(dev);
976
977         up(&priv->wx_sem);
978
979         return 0;
980
981 }
982
983 static int r8180_wx_radio_off(struct net_device *dev,
984                               struct iw_request_info *info,
985                               union iwreq_data *wrqu, char *extra)
986 {
987         struct r8180_priv *priv = ieee80211_priv(dev);
988
989         if (priv->ieee80211->bHwRadioOff)
990                 return 0;
991
992
993         down(&priv->wx_sem);
994         priv->rf_sleep(dev);
995
996         up(&priv->wx_sem);
997
998         return 0;
999
1000 }
1001 static int r8180_wx_get_channelplan(struct net_device *dev,
1002                                     struct iw_request_info *info,
1003                                     union iwreq_data *wrqu, char *extra)
1004 {
1005         struct r8180_priv *priv = ieee80211_priv(dev);
1006
1007
1008
1009         down(&priv->wx_sem);
1010         *extra = priv->channel_plan;
1011
1012
1013
1014         up(&priv->wx_sem);
1015
1016         return 0;
1017 }
1018 static int r8180_wx_set_channelplan(struct net_device *dev,
1019                                     struct iw_request_info *info,
1020                                     union iwreq_data *wrqu, char *extra)
1021 {
1022         struct r8180_priv *priv = ieee80211_priv(dev);
1023         int *val = (int *)extra;
1024         int i;
1025         printk("-----in fun %s\n", __func__);
1026
1027         if (priv->ieee80211->bHwRadioOff)
1028                 return 0;
1029
1030         /* unsigned long flags; */
1031         down(&priv->wx_sem);
1032         if (DefaultChannelPlan[*val].Len != 0)  {
1033                 priv->channel_plan = *val;
1034                 /* Clear old channel map 8 */
1035                 for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
1036                         GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
1037
1038                 /* Set new channel map */
1039                 for (i = 1; i <= DefaultChannelPlan[*val].Len; i++)
1040                         GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
1041
1042         }
1043         up(&priv->wx_sem);
1044
1045         return 0;
1046 }
1047
1048 static int r8180_wx_get_version(struct net_device *dev,
1049                                 struct iw_request_info *info,
1050                                 union iwreq_data *wrqu, char *extra)
1051 {
1052         struct r8180_priv *priv = ieee80211_priv(dev);
1053         /* struct ieee80211_device *ieee; */
1054
1055         down(&priv->wx_sem);
1056         strcpy(extra, "1020.0808");
1057         up(&priv->wx_sem);
1058
1059         return 0;
1060 }
1061
1062 /* added by amy 080818 */
1063 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1064 static int r8180_wx_set_forcerate(struct net_device *dev,
1065                                   struct iw_request_info *info,
1066                                   union iwreq_data *wrqu, char *extra)
1067 {
1068         struct r8180_priv *priv = ieee80211_priv(dev);
1069         u8 forcerate = *extra;
1070
1071         down(&priv->wx_sem);
1072
1073         printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
1074         if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
1075                 (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
1076                 (forcerate == 96) || (forcerate == 108))
1077         {
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                 return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && /* YJ,mod, 080819,for hidden ap */
1348                         (src->channel == dst->channel) &&
1349                         !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1350                         (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&  /* YJ,mod, 080819,for hidden ap */
1351                         ((src->capability & WLAN_CAPABILITY_IBSS) ==
1352                         (dst->capability & WLAN_CAPABILITY_IBSS)) &&
1353                         ((src->capability & WLAN_CAPABILITY_BSS) ==
1354                         (dst->capability & WLAN_CAPABILITY_BSS)));
1355 }
1356
1357 /* WB modified to show signal to GUI on 18-01-2008 */
1358 static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
1359 {
1360         struct r8180_priv *priv = ieee80211_priv(dev);
1361         struct ieee80211_device* ieee = priv->ieee80211;
1362         struct iw_statistics* wstats = &priv->wstats;
1363         int tmp_level = 0;
1364         int tmp_qual = 0;
1365         int tmp_noise = 0;
1366
1367         if (ieee->state < IEEE80211_LINKED)     {
1368                 wstats->qual.qual = 0;
1369                 wstats->qual.level = 0;
1370                 wstats->qual.noise = 0;
1371                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1372                 return wstats;
1373         }
1374
1375         tmp_level = (&ieee->current_network)->stats.signal;
1376         tmp_qual = (&ieee->current_network)->stats.signalstrength;
1377         tmp_noise = (&ieee->current_network)->stats.noise;
1378
1379         wstats->qual.level = tmp_level;
1380         wstats->qual.qual = tmp_qual;
1381         wstats->qual.noise = tmp_noise;
1382         wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1383         return wstats;
1384 }
1385
1386 struct iw_handler_def  r8180_wx_handlers_def = {
1387         .standard = r8180_wx_handlers,
1388         .num_standard = ARRAY_SIZE(r8180_wx_handlers),
1389         .private = r8180_private_handler,
1390         .num_private = ARRAY_SIZE(r8180_private_handler),
1391         .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
1392         .get_wireless_stats = r8180_get_wireless_stats,
1393         .private_args = (struct iw_priv_args *)r8180_private_args,
1394 };
1395
1396