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