Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / rtl8192e / rtl8192e / rtl_wx.c
1 /******************************************************************************
2  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3  *
4  * This program is distributed in the hope that it will be useful, but WITHOUT
5  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7  * more details.
8  *
9  * You should have received a copy of the GNU General Public License along with
10  * this program; if not, write to the Free Software Foundation, Inc.,
11  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12  *
13  * The full GNU General Public License is included in this distribution in the
14  * file called LICENSE.
15  *
16  * Contact Information:
17  * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
19
20 #include <linux/string.h>
21 #include "rtl_core.h"
22 #include "rtl_wx.h"
23
24 #define RATE_COUNT 12
25 static u32 rtl8192_rates[] = {
26         1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000,
27         18000000, 24000000, 36000000, 48000000, 54000000
28 };
29
30 #ifndef ENETDOWN
31 #define ENETDOWN 1
32 #endif
33
34 static int r8192_wx_get_freq(struct net_device *dev,
35                              struct iw_request_info *a,
36                              union iwreq_data *wrqu, char *b)
37 {
38         struct r8192_priv *priv = rtllib_priv(dev);
39
40         return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b);
41 }
42
43
44 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
45                              union iwreq_data *wrqu, char *b)
46 {
47         struct r8192_priv *priv = rtllib_priv(dev);
48
49         return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b);
50 }
51
52 static int r8192_wx_get_rate(struct net_device *dev,
53                              struct iw_request_info *info,
54                              union iwreq_data *wrqu, char *extra)
55 {
56         struct r8192_priv *priv = rtllib_priv(dev);
57
58         return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra);
59 }
60
61
62
63 static int r8192_wx_set_rate(struct net_device *dev,
64                              struct iw_request_info *info,
65                              union iwreq_data *wrqu, char *extra)
66 {
67         int ret;
68         struct r8192_priv *priv = rtllib_priv(dev);
69
70         if (priv->bHwRadioOff)
71                 return 0;
72
73         down(&priv->wx_sem);
74
75         ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra);
76
77         up(&priv->wx_sem);
78
79         return ret;
80 }
81
82
83 static int r8192_wx_set_rts(struct net_device *dev,
84                              struct iw_request_info *info,
85                              union iwreq_data *wrqu, char *extra)
86 {
87         int ret;
88         struct r8192_priv *priv = rtllib_priv(dev);
89
90         if (priv->bHwRadioOff)
91                 return 0;
92
93         down(&priv->wx_sem);
94
95         ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra);
96
97         up(&priv->wx_sem);
98
99         return ret;
100 }
101
102 static int r8192_wx_get_rts(struct net_device *dev,
103                              struct iw_request_info *info,
104                              union iwreq_data *wrqu, char *extra)
105 {
106         struct r8192_priv *priv = rtllib_priv(dev);
107
108         return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra);
109 }
110
111 static int r8192_wx_set_power(struct net_device *dev,
112                              struct iw_request_info *info,
113                              union iwreq_data *wrqu, char *extra)
114 {
115         int ret;
116         struct r8192_priv *priv = rtllib_priv(dev);
117
118         if (priv->bHwRadioOff) {
119                 RT_TRACE(COMP_ERR,
120                          "%s():Hw is Radio Off, we can't set Power,return\n",
121                          __func__);
122                 return 0;
123         }
124         down(&priv->wx_sem);
125
126         ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra);
127
128         up(&priv->wx_sem);
129
130         return ret;
131 }
132
133 static int r8192_wx_get_power(struct net_device *dev,
134                              struct iw_request_info *info,
135                              union iwreq_data *wrqu, char *extra)
136 {
137         struct r8192_priv *priv = rtllib_priv(dev);
138
139         return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
140 }
141
142 static int r8192_wx_set_rawtx(struct net_device *dev,
143                               struct iw_request_info *info,
144                               union iwreq_data *wrqu, char *extra)
145 {
146         struct r8192_priv *priv = rtllib_priv(dev);
147         int ret;
148
149         if (priv->bHwRadioOff)
150                 return 0;
151
152         down(&priv->wx_sem);
153
154         ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra);
155
156         up(&priv->wx_sem);
157
158         return ret;
159
160 }
161
162 static int r8192_wx_force_reset(struct net_device *dev,
163                 struct iw_request_info *info,
164                 union iwreq_data *wrqu, char *extra)
165 {
166         struct r8192_priv *priv = rtllib_priv(dev);
167
168         down(&priv->wx_sem);
169
170         RT_TRACE(COMP_DBG, "%s(): force reset ! extra is %d\n",
171                  __func__, *extra);
172         priv->force_reset = *extra;
173         up(&priv->wx_sem);
174         return 0;
175
176 }
177
178 static int r8192_wx_force_mic_error(struct net_device *dev,
179                 struct iw_request_info *info,
180                 union iwreq_data *wrqu, char *extra)
181 {
182         struct r8192_priv *priv = rtllib_priv(dev);
183         struct rtllib_device *ieee = priv->rtllib;
184
185         down(&priv->wx_sem);
186
187         RT_TRACE(COMP_DBG, "%s(): force mic error !\n", __func__);
188         ieee->force_mic_error = true;
189         up(&priv->wx_sem);
190         return 0;
191
192 }
193
194 #define MAX_ADHOC_PEER_NUM 64
195 struct adhoc_peer_entry {
196         unsigned char MacAddr[ETH_ALEN];
197         unsigned char WirelessMode;
198         unsigned char bCurTxBW40MHz;
199 };
200 struct adhoc_peers_info {
201         struct adhoc_peer_entry Entry[MAX_ADHOC_PEER_NUM];
202         unsigned char num;
203 };
204
205 static int r8192_wx_get_adhoc_peers(struct net_device *dev,
206                                     struct iw_request_info *info,
207                                     union iwreq_data *wrqu, char *extra)
208 {
209         return 0;
210 }
211
212
213 static int r8191se_wx_get_firm_version(struct net_device *dev,
214                 struct iw_request_info *info,
215                 struct iw_param *wrqu, char *extra)
216 {
217         return 0;
218 }
219
220 static int r8192_wx_adapter_power_status(struct net_device *dev,
221                 struct iw_request_info *info,
222                 union iwreq_data *wrqu, char *extra)
223 {
224         struct r8192_priv *priv = rtllib_priv(dev);
225         struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
226                                         (&(priv->rtllib->PowerSaveControl));
227         struct rtllib_device *ieee = priv->rtllib;
228
229         down(&priv->wx_sem);
230
231         RT_TRACE(COMP_POWER, "%s(): %s\n", __func__, (*extra == 6) ?
232                  "DC power" : "AC power");
233         if (*extra || priv->force_lps) {
234                 priv->ps_force = false;
235                 pPSC->bLeisurePs = true;
236         } else {
237                 if (priv->rtllib->state == RTLLIB_LINKED)
238                         LeisurePSLeave(dev);
239
240                 priv->ps_force = true;
241                 pPSC->bLeisurePs = false;
242                 ieee->ps = *extra;
243         }
244
245         up(&priv->wx_sem);
246
247         return 0;
248 }
249
250 static int r8192se_wx_set_radio(struct net_device *dev,
251         struct iw_request_info *info,
252         union iwreq_data *wrqu, char *extra)
253 {
254         struct r8192_priv *priv = rtllib_priv(dev);
255
256         down(&priv->wx_sem);
257
258         netdev_info(dev, "%s(): set radio ! extra is %d\n", __func__, *extra);
259         if ((*extra != 0) && (*extra != 1)) {
260                 RT_TRACE(COMP_ERR,
261                          "%s(): set radio an err value,must 0(radio off) or 1(radio on)\n",
262                          __func__);
263                 up(&priv->wx_sem);
264                 return -1;
265         }
266         priv->sw_radio_on = *extra;
267         up(&priv->wx_sem);
268         return 0;
269
270 }
271
272 static int r8192se_wx_set_lps_awake_interval(struct net_device *dev,
273         struct iw_request_info *info,
274         union iwreq_data *wrqu, char *extra)
275 {
276         struct r8192_priv *priv = rtllib_priv(dev);
277         struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
278                                         (&(priv->rtllib->PowerSaveControl));
279
280         down(&priv->wx_sem);
281
282         netdev_info(dev, "%s(): set lps awake interval ! extra is %d\n",
283                     __func__, *extra);
284
285         pPSC->RegMaxLPSAwakeIntvl = *extra;
286         up(&priv->wx_sem);
287         return 0;
288 }
289
290 static int r8192se_wx_set_force_lps(struct net_device *dev,
291                 struct iw_request_info *info,
292                 union iwreq_data *wrqu, char *extra)
293 {
294         struct r8192_priv *priv = rtllib_priv(dev);
295
296         down(&priv->wx_sem);
297
298         netdev_info(dev,
299                     "%s(): force LPS ! extra is %d (1 is open 0 is close)\n",
300                     __func__, *extra);
301         priv->force_lps = *extra;
302         up(&priv->wx_sem);
303         return 0;
304
305 }
306
307 static int r8192_wx_set_debugflag(struct net_device *dev,
308                                   struct iw_request_info *info,
309                                   union iwreq_data *wrqu, char *extra)
310 {
311         struct r8192_priv *priv = rtllib_priv(dev);
312         u8 c = *extra;
313
314         if (priv->bHwRadioOff)
315                 return 0;
316
317         netdev_info(dev, "=====>%s(), *extra:%x, debugflag:%x\n", __func__,
318                     *extra, rt_global_debug_component);
319         if (c > 0)
320                 rt_global_debug_component |= (1<<c);
321         else
322                 rt_global_debug_component &= BIT31;
323         return 0;
324 }
325
326 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
327                              union iwreq_data *wrqu, char *b)
328 {
329         struct r8192_priv *priv = rtllib_priv(dev);
330         struct rtllib_device *ieee = netdev_priv_rsl(dev);
331
332         enum rt_rf_power_state rtState;
333         int ret;
334
335         if (priv->bHwRadioOff)
336                 return 0;
337         rtState = priv->rtllib->eRFPowerState;
338         down(&priv->wx_sem);
339         if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR ||
340             ieee->bNetPromiscuousMode) {
341                 if (priv->rtllib->PowerSaveControl.bInactivePs) {
342                         if (rtState == eRfOff) {
343                                 if (priv->rtllib->RfOffReason >
344                                     RF_CHANGE_BY_IPS) {
345                                         RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",
346                                                  __func__);
347                                         up(&priv->wx_sem);
348                                         return -1;
349                                 }
350                                 netdev_info(dev,  "=========>%s(): IPSLeave\n",
351                                             __func__);
352                                 down(&priv->rtllib->ips_sem);
353                                 IPSLeave(dev);
354                                 up(&priv->rtllib->ips_sem);
355                         }
356                 }
357         }
358         ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b);
359
360         up(&priv->wx_sem);
361         return ret;
362 }
363
364 struct  iw_range_with_scan_capa {
365         /* Informative stuff (to choose between different interface) */
366         __u32      throughput;     /* To give an idea... */
367         /* In theory this value should be the maximum benchmarked
368          * TCP/IP throughput, because with most of these devices the
369          * bit rate is meaningless (overhead an co) to estimate how
370          * fast the connection will go and pick the fastest one.
371          * I suggest people to play with Netperf or any benchmark...
372          */
373
374         /* NWID (or domain id) */
375         __u32      min_nwid;    /* Minimal NWID we are able to set */
376         __u32      max_nwid;    /* Maximal NWID we are able to set */
377
378         /* Old Frequency (backward compat - moved lower ) */
379         __u16      old_num_channels;
380         __u8        old_num_frequency;
381
382         /* Scan capabilities */
383         __u8        scan_capa;
384 };
385
386 static int rtl8192_wx_get_range(struct net_device *dev,
387                                 struct iw_request_info *info,
388                                 union iwreq_data *wrqu, char *extra)
389 {
390         struct iw_range *range = (struct iw_range *)extra;
391         struct r8192_priv *priv = rtllib_priv(dev);
392         u16 val;
393         int i;
394
395         wrqu->data.length = sizeof(*range);
396         memset(range, 0, sizeof(*range));
397
398         /* ~130 Mb/s real (802.11n) */
399         range->throughput = 130 * 1000 * 1000;
400
401         if (priv->rf_set_sens != NULL) {
402                 /* signal level threshold range */
403                 range->sensitivity = priv->max_sens;
404         }
405
406         range->max_qual.qual = 100;
407         range->max_qual.level = 0;
408         range->max_qual.noise = 0;
409         range->max_qual.updated = 7; /* Updated all three */
410
411         range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
412         range->avg_qual.level = 0;
413         range->avg_qual.noise = 0;
414         range->avg_qual.updated = 7; /* Updated all three */
415
416         range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES);
417
418         for (i = 0; i < range->num_bitrates; i++)
419                 range->bitrate[i] = rtl8192_rates[i];
420
421         range->max_rts = DEFAULT_RTS_THRESHOLD;
422         range->min_frag = MIN_FRAG_THRESHOLD;
423         range->max_frag = MAX_FRAG_THRESHOLD;
424
425         range->min_pmp = 0;
426         range->max_pmp = 5000000;
427         range->min_pmt = 0;
428         range->max_pmt = 65535*1000;
429         range->pmp_flags = IW_POWER_PERIOD;
430         range->pmt_flags = IW_POWER_TIMEOUT;
431         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
432         range->we_version_compiled = WIRELESS_EXT;
433         range->we_version_source = 18;
434
435         for (i = 0, val = 0; i < 14; i++) {
436                 if ((priv->rtllib->active_channel_map)[i+1]) {
437                         range->freq[val].i = i + 1;
438                         range->freq[val].m = rtllib_wlan_frequencies[i] *
439                                              100000;
440                         range->freq[val].e = 1;
441                         val++;
442                 }
443
444                 if (val == IW_MAX_FREQUENCIES)
445                         break;
446         }
447         range->num_frequency = val;
448         range->num_channels = val;
449         range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
450                           IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
451         range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
452
453         /* Event capability (kernel + driver) */
454
455         return 0;
456 }
457
458 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
459                              union iwreq_data *wrqu, char *b)
460 {
461         struct r8192_priv *priv = rtllib_priv(dev);
462         struct rtllib_device *ieee = priv->rtllib;
463         enum rt_rf_power_state rtState;
464         int ret;
465
466         if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
467                 if ((ieee->state >= RTLLIB_ASSOCIATING) &&
468                     (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED))
469                         return 0;
470                 if ((priv->rtllib->state == RTLLIB_LINKED) &&
471                     (priv->rtllib->CntAfterLink < 2))
472                         return 0;
473         }
474
475         if (priv->bHwRadioOff) {
476                 netdev_info(dev, "================>%s(): hwradio off\n",
477                             __func__);
478                 return 0;
479         }
480         rtState = priv->rtllib->eRFPowerState;
481         if (!priv->up)
482                 return -ENETDOWN;
483         if (priv->rtllib->LinkDetectInfo.bBusyTraffic == true)
484                 return -EAGAIN;
485
486         if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
487                 struct iw_scan_req *req = (struct iw_scan_req *)b;
488
489                 if (req->essid_len) {
490                         ieee->current_network.ssid_len = req->essid_len;
491                         memcpy(ieee->current_network.ssid, req->essid,
492                                req->essid_len);
493                 }
494         }
495
496         down(&priv->wx_sem);
497
498         priv->rtllib->FirstIe_InScan = true;
499
500         if (priv->rtllib->state != RTLLIB_LINKED) {
501                 if (priv->rtllib->PowerSaveControl.bInactivePs) {
502                         if (rtState == eRfOff) {
503                                 if (priv->rtllib->RfOffReason >
504                                     RF_CHANGE_BY_IPS) {
505                                         RT_TRACE(COMP_ERR,
506                                                  "%s(): RF is OFF.\n",
507                                                  __func__);
508                                         up(&priv->wx_sem);
509                                         return -1;
510                                 }
511                                 RT_TRACE(COMP_PS, "=========>%s(): IPSLeave\n",
512                                          __func__);
513                                 down(&priv->rtllib->ips_sem);
514                                 IPSLeave(dev);
515                                 up(&priv->rtllib->ips_sem);
516                         }
517                 }
518                 rtllib_stop_scan(priv->rtllib);
519                 if (priv->rtllib->LedControlHandler)
520                         priv->rtllib->LedControlHandler(dev,
521                                                          LED_CTL_SITE_SURVEY);
522
523                 if (priv->rtllib->eRFPowerState != eRfOff) {
524                         priv->rtllib->actscanning = true;
525
526                         if (ieee->ScanOperationBackupHandler)
527                                 ieee->ScanOperationBackupHandler(ieee->dev,
528                                                          SCAN_OPT_BACKUP);
529
530                         rtllib_start_scan_syncro(priv->rtllib, 0);
531
532                         if (ieee->ScanOperationBackupHandler)
533                                 ieee->ScanOperationBackupHandler(ieee->dev,
534                                                          SCAN_OPT_RESTORE);
535                 }
536                 ret = 0;
537         } else {
538                 priv->rtllib->actscanning = true;
539                 ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b);
540         }
541
542         up(&priv->wx_sem);
543         return ret;
544 }
545
546
547 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
548                              union iwreq_data *wrqu, char *b)
549 {
550
551         int ret;
552         struct r8192_priv *priv = rtllib_priv(dev);
553
554         if (!priv->up)
555                 return -ENETDOWN;
556
557         if (priv->bHwRadioOff)
558                 return 0;
559
560
561         down(&priv->wx_sem);
562
563         ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b);
564
565         up(&priv->wx_sem);
566
567         return ret;
568 }
569
570 static int r8192_wx_set_essid(struct net_device *dev,
571                               struct iw_request_info *a,
572                               union iwreq_data *wrqu, char *b)
573 {
574         struct r8192_priv *priv = rtllib_priv(dev);
575         int ret;
576
577         if (priv->bHwRadioOff) {
578                 netdev_info(dev,
579                             "=========>%s():hw radio off,or Rf state is eRfOff, return\n",
580                             __func__);
581                 return 0;
582         }
583         down(&priv->wx_sem);
584         ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b);
585
586         up(&priv->wx_sem);
587
588         return ret;
589 }
590
591 static int r8192_wx_get_essid(struct net_device *dev,
592                               struct iw_request_info *a,
593                               union iwreq_data *wrqu, char *b)
594 {
595         int ret;
596         struct r8192_priv *priv = rtllib_priv(dev);
597
598         down(&priv->wx_sem);
599
600         ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b);
601
602         up(&priv->wx_sem);
603
604         return ret;
605 }
606
607 static int r8192_wx_set_nick(struct net_device *dev,
608                            struct iw_request_info *info,
609                            union iwreq_data *wrqu, char *extra)
610 {
611         struct r8192_priv *priv = rtllib_priv(dev);
612
613         if (wrqu->data.length > IW_ESSID_MAX_SIZE)
614                 return -E2BIG;
615         down(&priv->wx_sem);
616         wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick));
617         memset(priv->nick, 0, sizeof(priv->nick));
618         memcpy(priv->nick, extra, wrqu->data.length);
619         up(&priv->wx_sem);
620         return 0;
621
622 }
623
624 static int r8192_wx_get_nick(struct net_device *dev,
625                              struct iw_request_info *info,
626                              union iwreq_data *wrqu, char *extra)
627 {
628         struct r8192_priv *priv = rtllib_priv(dev);
629
630         down(&priv->wx_sem);
631         wrqu->data.length = strlen(priv->nick);
632         memcpy(extra, priv->nick, wrqu->data.length);
633         wrqu->data.flags = 1;   /* active */
634         up(&priv->wx_sem);
635         return 0;
636 }
637
638 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
639                              union iwreq_data *wrqu, char *b)
640 {
641         int ret;
642         struct r8192_priv *priv = rtllib_priv(dev);
643
644         if (priv->bHwRadioOff)
645                 return 0;
646
647         down(&priv->wx_sem);
648
649         ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b);
650
651         up(&priv->wx_sem);
652         return ret;
653 }
654
655 static int r8192_wx_get_name(struct net_device *dev,
656                              struct iw_request_info *info,
657                              union iwreq_data *wrqu, char *extra)
658 {
659         struct r8192_priv *priv = rtllib_priv(dev);
660
661         return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra);
662 }
663
664
665 static int r8192_wx_set_frag(struct net_device *dev,
666                              struct iw_request_info *info,
667                              union iwreq_data *wrqu, char *extra)
668 {
669         struct r8192_priv *priv = rtllib_priv(dev);
670
671         if (priv->bHwRadioOff)
672                 return 0;
673
674         if (wrqu->frag.disabled)
675                 priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
676         else {
677                 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
678                     wrqu->frag.value > MAX_FRAG_THRESHOLD)
679                         return -EINVAL;
680
681                 priv->rtllib->fts = wrqu->frag.value & ~0x1;
682         }
683
684         return 0;
685 }
686
687
688 static int r8192_wx_get_frag(struct net_device *dev,
689                              struct iw_request_info *info,
690                              union iwreq_data *wrqu, char *extra)
691 {
692         struct r8192_priv *priv = rtllib_priv(dev);
693
694         wrqu->frag.value = priv->rtllib->fts;
695         wrqu->frag.fixed = 0;   /* no auto select */
696         wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
697
698         return 0;
699 }
700
701
702 static int r8192_wx_set_wap(struct net_device *dev,
703                          struct iw_request_info *info,
704                          union iwreq_data *awrq,
705                          char *extra)
706 {
707         int ret;
708         struct r8192_priv *priv = rtllib_priv(dev);
709
710         if (priv->bHwRadioOff)
711                 return 0;
712
713         down(&priv->wx_sem);
714
715         ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra);
716
717         up(&priv->wx_sem);
718
719         return ret;
720
721 }
722
723
724 static int r8192_wx_get_wap(struct net_device *dev,
725                             struct iw_request_info *info,
726                             union iwreq_data *wrqu, char *extra)
727 {
728         struct r8192_priv *priv = rtllib_priv(dev);
729
730         return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra);
731 }
732
733
734 static int r8192_wx_get_enc(struct net_device *dev,
735                             struct iw_request_info *info,
736                             union iwreq_data *wrqu, char *key)
737 {
738         struct r8192_priv *priv = rtllib_priv(dev);
739
740         return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key);
741 }
742
743 static int r8192_wx_set_enc(struct net_device *dev,
744                             struct iw_request_info *info,
745                             union iwreq_data *wrqu, char *key)
746 {
747         struct r8192_priv *priv = rtllib_priv(dev);
748         int ret;
749
750         struct rtllib_device *ieee = priv->rtllib;
751         u32 hwkey[4] = {0, 0, 0, 0};
752         u8 mask = 0xff;
753         u32 key_idx = 0;
754         u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
755                              {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
756                              {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
757                              {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
758         int i;
759
760         if (priv->bHwRadioOff)
761                 return 0;
762
763         if (!priv->up)
764                 return -ENETDOWN;
765
766         priv->rtllib->wx_set_enc = 1;
767         down(&priv->rtllib->ips_sem);
768         IPSLeave(dev);
769         up(&priv->rtllib->ips_sem);
770         down(&priv->wx_sem);
771
772         RT_TRACE(COMP_SEC, "Setting SW wep key");
773         ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key);
774         up(&priv->wx_sem);
775
776
777         if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
778                 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
779                 CamResetAllEntry(dev);
780                 memset(priv->rtllib->swcamtable, 0,
781                        sizeof(struct sw_cam_table) * 32);
782                 goto end_hw_sec;
783         }
784         if (wrqu->encoding.length != 0) {
785
786                 for (i = 0; i < 4; i++) {
787                         hwkey[i] |=  key[4*i+0]&mask;
788                         if (i == 1 && (4 * i + 1) == wrqu->encoding.length)
789                                 mask = 0x00;
790                         if (i == 3 && (4 * i + 1) == wrqu->encoding.length)
791                                 mask = 0x00;
792                         hwkey[i] |= (key[4 * i + 1] & mask) << 8;
793                         hwkey[i] |= (key[4 * i + 2] & mask) << 16;
794                         hwkey[i] |= (key[4 * i + 3] & mask) << 24;
795                 }
796
797                 #define CONF_WEP40  0x4
798                 #define CONF_WEP104 0x14
799
800                 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
801                 case 0:
802                         key_idx = ieee->crypt_info.tx_keyidx;
803                         break;
804                 case 1:
805                         key_idx = 0;
806                         break;
807                 case 2:
808                         key_idx = 1;
809                         break;
810                 case 3:
811                         key_idx = 2;
812                         break;
813                 case 4:
814                         key_idx = 3;
815                         break;
816                 default:
817                         break;
818                 }
819                 if (wrqu->encoding.length == 0x5) {
820                         ieee->pairwise_key_type = KEY_TYPE_WEP40;
821                         EnableHWSecurityConfig8192(dev);
822                 }
823
824                 else if (wrqu->encoding.length == 0xd) {
825                         ieee->pairwise_key_type = KEY_TYPE_WEP104;
826                                 EnableHWSecurityConfig8192(dev);
827                         setKey(dev, key_idx, key_idx, KEY_TYPE_WEP104,
828                                zero_addr[key_idx], 0, hwkey);
829                         set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104,
830                                   zero_addr[key_idx], 0, hwkey, 0);
831                 } else {
832                         netdev_info(dev,
833                                     "wrong type in WEP, not WEP40 and WEP104\n");
834                 }
835         }
836
837 end_hw_sec:
838         priv->rtllib->wx_set_enc = 0;
839         return ret;
840 }
841
842 static int r8192_wx_set_scan_type(struct net_device *dev,
843                                   struct iw_request_info *aa,
844                                   union iwreq_data *wrqu, char *p)
845 {
846         struct r8192_priv *priv = rtllib_priv(dev);
847         int *parms = (int *)p;
848         int mode = parms[0];
849
850         if (priv->bHwRadioOff)
851                 return 0;
852
853         priv->rtllib->active_scan = mode;
854
855         return 1;
856 }
857
858
859
860 #define R8192_MAX_RETRY 255
861 static int r8192_wx_set_retry(struct net_device *dev,
862                                 struct iw_request_info *info,
863                                 union iwreq_data *wrqu, char *extra)
864 {
865         struct r8192_priv *priv = rtllib_priv(dev);
866         int err = 0;
867
868         if (priv->bHwRadioOff)
869                 return 0;
870
871         down(&priv->wx_sem);
872
873         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
874             wrqu->retry.disabled) {
875                 err = -EINVAL;
876                 goto exit;
877         }
878         if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
879                 err = -EINVAL;
880                 goto exit;
881         }
882
883         if (wrqu->retry.value > R8192_MAX_RETRY) {
884                 err = -EINVAL;
885                 goto exit;
886         }
887         if (wrqu->retry.flags & IW_RETRY_MAX) {
888                 priv->retry_rts = wrqu->retry.value;
889                 DMESG("Setting retry for RTS/CTS data to %d",
890                       wrqu->retry.value);
891
892         } else {
893                 priv->retry_data = wrqu->retry.value;
894                 DMESG("Setting retry for non RTS/CTS data to %d",
895                       wrqu->retry.value);
896         }
897
898
899         rtl8192_commit(dev);
900 exit:
901         up(&priv->wx_sem);
902
903         return err;
904 }
905
906 static int r8192_wx_get_retry(struct net_device *dev,
907                                 struct iw_request_info *info,
908                                 union iwreq_data *wrqu, char *extra)
909 {
910         struct r8192_priv *priv = rtllib_priv(dev);
911
912
913         wrqu->retry.disabled = 0; /* can't be disabled */
914
915         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
916             IW_RETRY_LIFETIME)
917                 return -EINVAL;
918
919         if (wrqu->retry.flags & IW_RETRY_MAX) {
920                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
921                 wrqu->retry.value = priv->retry_rts;
922         } else {
923                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
924                 wrqu->retry.value = priv->retry_data;
925         }
926         return 0;
927 }
928
929 static int r8192_wx_get_sens(struct net_device *dev,
930                              struct iw_request_info *info,
931                              union iwreq_data *wrqu, char *extra)
932 {
933         struct r8192_priv *priv = rtllib_priv(dev);
934
935         if (priv->rf_set_sens == NULL)
936                 return -1; /* we have not this support for this radio */
937         wrqu->sens.value = priv->sens;
938         return 0;
939 }
940
941
942 static int r8192_wx_set_sens(struct net_device *dev,
943                                 struct iw_request_info *info,
944                                 union iwreq_data *wrqu, char *extra)
945 {
946
947         struct r8192_priv *priv = rtllib_priv(dev);
948
949         short err = 0;
950
951         if (priv->bHwRadioOff)
952                 return 0;
953
954         down(&priv->wx_sem);
955         if (priv->rf_set_sens == NULL) {
956                 err = -1; /* we have not this support for this radio */
957                 goto exit;
958         }
959         if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
960                 priv->sens = wrqu->sens.value;
961         else
962                 err = -EINVAL;
963
964 exit:
965         up(&priv->wx_sem);
966
967         return err;
968 }
969
970 static int r8192_wx_set_enc_ext(struct net_device *dev,
971                                 struct iw_request_info *info,
972                                 union iwreq_data *wrqu, char *extra)
973 {
974         int ret = 0;
975         struct r8192_priv *priv = rtllib_priv(dev);
976         struct rtllib_device *ieee = priv->rtllib;
977
978         if (priv->bHwRadioOff)
979                 return 0;
980
981         down(&priv->wx_sem);
982
983         priv->rtllib->wx_set_enc = 1;
984         down(&priv->rtllib->ips_sem);
985         IPSLeave(dev);
986         up(&priv->rtllib->ips_sem);
987
988         ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra);
989         {
990                 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
991                 u8 zero[6] = {0};
992                 u32 key[4] = {0};
993                 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
994                 struct iw_point *encoding = &wrqu->encoding;
995                 u8 idx = 0, alg = 0, group = 0;
996
997                 if ((encoding->flags & IW_ENCODE_DISABLED) ||
998                      ext->alg == IW_ENCODE_ALG_NONE) {
999                         ieee->pairwise_key_type = ieee->group_key_type
1000                                                 = KEY_TYPE_NA;
1001                         CamResetAllEntry(dev);
1002                         memset(priv->rtllib->swcamtable, 0,
1003                                sizeof(struct sw_cam_table) * 32);
1004                         goto end_hw_sec;
1005                 }
1006                 alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP :
1007                       ext->alg;
1008                 idx = encoding->flags & IW_ENCODE_INDEX;
1009                 if (idx)
1010                         idx--;
1011                 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1012
1013                 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) ||
1014                     (alg ==  KEY_TYPE_WEP40)) {
1015                         if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
1016                                 alg = KEY_TYPE_WEP104;
1017                         ieee->pairwise_key_type = alg;
1018                         EnableHWSecurityConfig8192(dev);
1019                 }
1020                 memcpy((u8 *)key, ext->key, 16);
1021
1022                 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
1023                         if (ext->key_len == 13)
1024                                 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1025                         setKey(dev, idx, idx, alg, zero, 0, key);
1026                         set_swcam(dev, idx, idx, alg, zero, 0, key, 0);
1027                 } else if (group) {
1028                         ieee->group_key_type = alg;
1029                         setKey(dev, idx, idx, alg, broadcast_addr, 0, key);
1030                         set_swcam(dev, idx, idx, alg, broadcast_addr, 0,
1031                                   key, 0);
1032                 } else {
1033                         if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
1034                              ieee->pHTInfo->bCurrentHTSupport)
1035                                 write_nic_byte(dev, 0x173, 1);
1036                         setKey(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr,
1037                                0, key);
1038                         set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr,
1039                                   0, key, 0);
1040                 }
1041
1042
1043         }
1044
1045 end_hw_sec:
1046         priv->rtllib->wx_set_enc = 0;
1047         up(&priv->wx_sem);
1048         return ret;
1049
1050 }
1051 static int r8192_wx_set_auth(struct net_device *dev,
1052                              struct iw_request_info *info,
1053                              union iwreq_data *data, char *extra)
1054 {
1055         int ret = 0;
1056
1057         struct r8192_priv *priv = rtllib_priv(dev);
1058
1059         if (priv->bHwRadioOff)
1060                 return 0;
1061
1062         down(&priv->wx_sem);
1063         ret = rtllib_wx_set_auth(priv->rtllib, info, &(data->param), extra);
1064         up(&priv->wx_sem);
1065         return ret;
1066 }
1067
1068 static int r8192_wx_set_mlme(struct net_device *dev,
1069                              struct iw_request_info *info,
1070                              union iwreq_data *wrqu, char *extra)
1071 {
1072
1073         int ret = 0;
1074
1075         struct r8192_priv *priv = rtllib_priv(dev);
1076
1077         if (priv->bHwRadioOff)
1078                 return 0;
1079
1080         down(&priv->wx_sem);
1081         ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra);
1082         up(&priv->wx_sem);
1083         return ret;
1084 }
1085
1086 static int r8192_wx_set_gen_ie(struct net_device *dev,
1087                                struct iw_request_info *info,
1088                                union iwreq_data *data, char *extra)
1089 {
1090         int ret = 0;
1091
1092         struct r8192_priv *priv = rtllib_priv(dev);
1093
1094         if (priv->bHwRadioOff)
1095                 return 0;
1096
1097         down(&priv->wx_sem);
1098         ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length);
1099         up(&priv->wx_sem);
1100         return ret;
1101 }
1102
1103 static int r8192_wx_get_gen_ie(struct net_device *dev,
1104                                struct iw_request_info *info,
1105                                union iwreq_data *data, char *extra)
1106 {
1107         int ret = 0;
1108         struct r8192_priv *priv = rtllib_priv(dev);
1109         struct rtllib_device *ieee = priv->rtllib;
1110
1111         if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
1112                 data->data.length = 0;
1113                 return 0;
1114         }
1115
1116         if (data->data.length < ieee->wpa_ie_len)
1117                 return -E2BIG;
1118
1119         data->data.length = ieee->wpa_ie_len;
1120         memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
1121         return ret;
1122 }
1123
1124 #define OID_RT_INTEL_PROMISCUOUS_MODE   0xFF0101F6
1125
1126 static int r8192_wx_set_PromiscuousMode(struct net_device *dev,
1127                 struct iw_request_info *info,
1128                 union iwreq_data *wrqu, char *extra)
1129 {
1130         struct r8192_priv *priv = rtllib_priv(dev);
1131         struct rtllib_device *ieee = priv->rtllib;
1132
1133         u32 info_buf[3];
1134
1135         u32 oid;
1136         u32 bPromiscuousOn;
1137         u32 bFilterSourceStationFrame;
1138
1139         if (copy_from_user(info_buf, wrqu->data.pointer, sizeof(info_buf)))
1140                 return -EFAULT;
1141
1142         oid = info_buf[0];
1143         bPromiscuousOn = info_buf[1];
1144         bFilterSourceStationFrame = info_buf[2];
1145
1146         if (OID_RT_INTEL_PROMISCUOUS_MODE == oid) {
1147                 ieee->IntelPromiscuousModeInfo.bPromiscuousOn =
1148                                         (bPromiscuousOn) ? (true) : (false);
1149                 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame =
1150                         (bFilterSourceStationFrame) ? (true) : (false);
1151                         (bPromiscuousOn) ?
1152                         (rtllib_EnableIntelPromiscuousMode(dev, false)) :
1153                         (rtllib_DisableIntelPromiscuousMode(dev, false));
1154
1155                 netdev_info(dev,
1156                             "=======>%s(), on = %d, filter src sta = %d\n",
1157                             __func__, bPromiscuousOn,
1158                             bFilterSourceStationFrame);
1159         } else {
1160                 return -1;
1161         }
1162
1163         return 0;
1164 }
1165
1166
1167 static int r8192_wx_get_PromiscuousMode(struct net_device *dev,
1168                                struct iw_request_info *info,
1169                                union iwreq_data *wrqu, char *extra)
1170 {
1171         struct r8192_priv *priv = rtllib_priv(dev);
1172         struct rtllib_device *ieee = priv->rtllib;
1173
1174         down(&priv->wx_sem);
1175
1176         snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d",
1177                  ieee->IntelPromiscuousModeInfo.bPromiscuousOn,
1178                  ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame);
1179         wrqu->data.length = strlen(extra) + 1;
1180
1181         up(&priv->wx_sem);
1182
1183         return 0;
1184 }
1185
1186
1187 #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
1188 static iw_handler r8192_wx_handlers[] = {
1189         IW_IOCTL(SIOCGIWNAME) = r8192_wx_get_name,
1190         IW_IOCTL(SIOCSIWFREQ) = r8192_wx_set_freq,
1191         IW_IOCTL(SIOCGIWFREQ) = r8192_wx_get_freq,
1192         IW_IOCTL(SIOCSIWMODE) = r8192_wx_set_mode,
1193         IW_IOCTL(SIOCGIWMODE) = r8192_wx_get_mode,
1194         IW_IOCTL(SIOCSIWSENS) = r8192_wx_set_sens,
1195         IW_IOCTL(SIOCGIWSENS) = r8192_wx_get_sens,
1196         IW_IOCTL(SIOCGIWRANGE) = rtl8192_wx_get_range,
1197         IW_IOCTL(SIOCSIWAP) = r8192_wx_set_wap,
1198         IW_IOCTL(SIOCGIWAP) = r8192_wx_get_wap,
1199         IW_IOCTL(SIOCSIWSCAN) = r8192_wx_set_scan,
1200         IW_IOCTL(SIOCGIWSCAN) = r8192_wx_get_scan,
1201         IW_IOCTL(SIOCSIWESSID) = r8192_wx_set_essid,
1202         IW_IOCTL(SIOCGIWESSID) = r8192_wx_get_essid,
1203         IW_IOCTL(SIOCSIWNICKN) = r8192_wx_set_nick,
1204                 IW_IOCTL(SIOCGIWNICKN) = r8192_wx_get_nick,
1205         IW_IOCTL(SIOCSIWRATE) = r8192_wx_set_rate,
1206         IW_IOCTL(SIOCGIWRATE) = r8192_wx_get_rate,
1207         IW_IOCTL(SIOCSIWRTS) = r8192_wx_set_rts,
1208         IW_IOCTL(SIOCGIWRTS) = r8192_wx_get_rts,
1209         IW_IOCTL(SIOCSIWFRAG) = r8192_wx_set_frag,
1210         IW_IOCTL(SIOCGIWFRAG) = r8192_wx_get_frag,
1211         IW_IOCTL(SIOCSIWRETRY) = r8192_wx_set_retry,
1212         IW_IOCTL(SIOCGIWRETRY) = r8192_wx_get_retry,
1213         IW_IOCTL(SIOCSIWENCODE) = r8192_wx_set_enc,
1214         IW_IOCTL(SIOCGIWENCODE) = r8192_wx_get_enc,
1215         IW_IOCTL(SIOCSIWPOWER) = r8192_wx_set_power,
1216         IW_IOCTL(SIOCGIWPOWER) = r8192_wx_get_power,
1217         IW_IOCTL(SIOCSIWGENIE) = r8192_wx_set_gen_ie,
1218         IW_IOCTL(SIOCGIWGENIE) = r8192_wx_get_gen_ie,
1219         IW_IOCTL(SIOCSIWMLME) = r8192_wx_set_mlme,
1220         IW_IOCTL(SIOCSIWAUTH) = r8192_wx_set_auth,
1221         IW_IOCTL(SIOCSIWENCODEEXT) = r8192_wx_set_enc_ext,
1222 };
1223
1224 /* the following rule need to be following,
1225  * Odd : get (world access),
1226  * even : set (root access)
1227  */
1228 static const struct iw_priv_args r8192_private_args[] = {
1229         {
1230                 SIOCIWFIRSTPRIV + 0x0,
1231                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag"
1232         }, {
1233                 SIOCIWFIRSTPRIV + 0x1,
1234                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1235         }, {
1236                 SIOCIWFIRSTPRIV + 0x2,
1237                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1238         }, {
1239                 SIOCIWFIRSTPRIV + 0x3,
1240                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1241         }, {
1242                 SIOCIWFIRSTPRIV + 0x4,
1243                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "force_mic_error"
1244         }, {
1245                 SIOCIWFIRSTPRIV + 0x5,
1246                 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
1247                 "firm_ver"
1248         }, {
1249                 SIOCIWFIRSTPRIV + 0x6,
1250                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1251                 "set_power"
1252         }, {
1253                 SIOCIWFIRSTPRIV + 0x9,
1254                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1255                 "radio"
1256         }, {
1257                 SIOCIWFIRSTPRIV + 0xa,
1258                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1259                 "lps_interv"
1260         }, {
1261                 SIOCIWFIRSTPRIV + 0xb,
1262                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1263                 "lps_force"
1264         }, {
1265                 SIOCIWFIRSTPRIV + 0xc,
1266                 0, IW_PRIV_TYPE_CHAR|2047, "adhoc_peer_list"
1267         }, {
1268                 SIOCIWFIRSTPRIV + 0x16,
1269                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc"
1270         }, {
1271                 SIOCIWFIRSTPRIV + 0x17,
1272                 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc"
1273         }
1274
1275 };
1276
1277 static iw_handler r8192_private_handler[] = {
1278         (iw_handler)r8192_wx_set_debugflag,   /*SIOCIWSECONDPRIV*/
1279         (iw_handler)r8192_wx_set_scan_type,
1280         (iw_handler)r8192_wx_set_rawtx,
1281         (iw_handler)r8192_wx_force_reset,
1282         (iw_handler)r8192_wx_force_mic_error,
1283         (iw_handler)r8191se_wx_get_firm_version,
1284         (iw_handler)r8192_wx_adapter_power_status,
1285         (iw_handler)NULL,
1286         (iw_handler)NULL,
1287         (iw_handler)r8192se_wx_set_radio,
1288         (iw_handler)r8192se_wx_set_lps_awake_interval,
1289         (iw_handler)r8192se_wx_set_force_lps,
1290         (iw_handler)r8192_wx_get_adhoc_peers,
1291         (iw_handler)NULL,
1292         (iw_handler)NULL,
1293         (iw_handler)NULL,
1294         (iw_handler)NULL,
1295         (iw_handler)NULL,
1296         (iw_handler)NULL,
1297         (iw_handler)NULL,
1298         (iw_handler)NULL,
1299         (iw_handler)NULL,
1300         (iw_handler)r8192_wx_set_PromiscuousMode,
1301         (iw_handler)r8192_wx_get_PromiscuousMode,
1302 };
1303
1304 static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1305 {
1306         struct r8192_priv *priv = rtllib_priv(dev);
1307         struct rtllib_device *ieee = priv->rtllib;
1308         struct iw_statistics *wstats = &priv->wstats;
1309         int tmp_level = 0;
1310         int tmp_qual = 0;
1311         int tmp_noise = 0;
1312
1313         if (ieee->state < RTLLIB_LINKED) {
1314                 wstats->qual.qual = 10;
1315                 wstats->qual.level = 0;
1316                 wstats->qual.noise = -100;
1317                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1318                 return wstats;
1319         }
1320
1321         tmp_level = (&ieee->current_network)->stats.rssi;
1322         tmp_qual = (&ieee->current_network)->stats.signal;
1323         tmp_noise = (&ieee->current_network)->stats.noise;
1324
1325         wstats->qual.level = tmp_level;
1326         wstats->qual.qual = tmp_qual;
1327         wstats->qual.noise = tmp_noise;
1328         wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1329         return wstats;
1330 }
1331
1332 const struct iw_handler_def r8192_wx_handlers_def = {
1333         .standard = r8192_wx_handlers,
1334         .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1335         .private = r8192_private_handler,
1336         .num_private = ARRAY_SIZE(r8192_private_handler),
1337         .num_private_args = sizeof(r8192_private_args) /
1338                             sizeof(struct iw_priv_args),
1339         .get_wireless_stats = r8192_get_wireless_stats,
1340         .private_args = (struct iw_priv_args *)r8192_private_args,
1341 };