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