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