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