xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8822cs/os_dep/linux/ioctl_linux.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _IOCTL_LINUX_C_
16 
17 #include <drv_types.h>
18 #include <rtw_mp.h>
19 #include "../../hal/phydm/phydm_precomp.h"
20 #ifdef RTW_HALMAC
21 #include "../../hal/hal_halmac.h"
22 #endif
23 
24 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
25 #define  iwe_stream_add_event(a, b, c, d, e)  iwe_stream_add_event(b, c, d, e)
26 #define  iwe_stream_add_point(a, b, c, d, e)  iwe_stream_add_point(b, c, d, e)
27 #endif
28 
29 #ifdef CONFIG_80211N_HT
30 extern int rtw_ht_enable;
31 #endif
32 
33 
34 
35 #define RTL_IOCTL_WPA_SUPPLICANT	(SIOCIWFIRSTPRIV+30)
36 
37 #define SCAN_ITEM_SIZE 768
38 #define MAX_CUSTOM_LEN 64
39 #define RATE_COUNT 4
40 #define MAX_SCAN_BUFFER_LEN 65535
41 
42 #ifdef CONFIG_GLOBAL_UI_PID
43 extern int ui_pid[3];
44 #endif
45 
46 /* combo scan */
47 #define WEXT_CSCAN_AMOUNT 9
48 #define WEXT_CSCAN_BUF_LEN		360
49 #define WEXT_CSCAN_HEADER		"CSCAN S\x01\x00\x00S\x00"
50 #define WEXT_CSCAN_HEADER_SIZE		12
51 #define WEXT_CSCAN_SSID_SECTION		'S'
52 #define WEXT_CSCAN_CHANNEL_SECTION	'C'
53 #define WEXT_CSCAN_NPROBE_SECTION	'N'
54 #define WEXT_CSCAN_ACTV_DWELL_SECTION	'A'
55 #define WEXT_CSCAN_PASV_DWELL_SECTION	'P'
56 #define WEXT_CSCAN_HOME_DWELL_SECTION	'H'
57 #define WEXT_CSCAN_TYPE_SECTION		'T'
58 
59 
60 extern u8 key_2char2num(u8 hch, u8 lch);
61 extern u8 str_2char2num(u8 hch, u8 lch);
62 extern void macstr2num(u8 *dst, u8 *src);
63 extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
64 
65 u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
66 	6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
67 
68 #ifdef CONFIG_RTW_ANDROID
indicate_wx_custom_event(_adapter * padapter,char * msg)69 static void indicate_wx_custom_event(_adapter *padapter, char *msg)
70 {
71 	u8 *buff;
72 	union iwreq_data wrqu;
73 
74 	if (strlen(msg) > IW_CUSTOM_MAX) {
75 		RTW_INFO("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);
76 		return;
77 	}
78 
79 	buff = rtw_zmalloc(IW_CUSTOM_MAX + 1);
80 	if (!buff)
81 		return;
82 
83 	_rtw_memcpy(buff, msg, strlen(msg));
84 
85 	_rtw_memset(&wrqu, 0, sizeof(wrqu));
86 	wrqu.data.length = strlen(msg);
87 
88 	RTW_INFO("%s %s\n", __FUNCTION__, buff);
89 #ifndef CONFIG_IOCTL_CFG80211
90 	wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
91 #endif
92 
93 	rtw_mfree(buff, IW_CUSTOM_MAX + 1);
94 
95 }
96 #endif
97 
98 #if 0
99 static void request_wps_pbc_event(_adapter *padapter)
100 {
101 	u8 *buff, *p;
102 	union iwreq_data wrqu;
103 
104 
105 	buff = rtw_malloc(IW_CUSTOM_MAX);
106 	if (!buff)
107 		return;
108 
109 	_rtw_memset(buff, 0, IW_CUSTOM_MAX);
110 
111 	p = buff;
112 
113 	p += sprintf(p, "WPS_PBC_START.request=TRUE");
114 
115 	_rtw_memset(&wrqu, 0, sizeof(wrqu));
116 
117 	wrqu.data.length = p - buff;
118 
119 	wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX;
120 
121 	RTW_INFO("%s\n", __FUNCTION__);
122 
123 #ifndef CONFIG_IOCTL_CFG80211
124 	wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
125 #endif
126 
127 	if (buff)
128 		rtw_mfree(buff, IW_CUSTOM_MAX);
129 
130 }
131 #endif
132 
133 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
rtw_request_wps_pbc_event(_adapter * padapter)134 void rtw_request_wps_pbc_event(_adapter *padapter)
135 {
136 #ifdef RTK_DMP_PLATFORM
137 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
138 	kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
139 #else
140 	kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
141 #endif
142 #else
143 
144 	if (padapter->pid[0] == 0) {
145 		/*	0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. */
146 		return;
147 	}
148 
149 	rtw_signal_process(padapter->pid[0], SIGUSR1);
150 
151 #endif
152 
153 	rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
154 }
155 #endif/* #ifdef CONFIG_SUPPORT_HW_WPS_PBC */
156 
indicate_wx_scan_complete_event(_adapter * padapter)157 void indicate_wx_scan_complete_event(_adapter *padapter)
158 {
159 	union iwreq_data wrqu;
160 
161 	_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
162 
163 	/* RTW_INFO("+rtw_indicate_wx_scan_complete_event\n"); */
164 #ifndef CONFIG_IOCTL_CFG80211
165 	wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
166 #endif
167 }
168 
169 
rtw_indicate_wx_assoc_event(_adapter * padapter)170 void rtw_indicate_wx_assoc_event(_adapter *padapter)
171 {
172 	union iwreq_data wrqu;
173 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
174 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
175 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
176 	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
177 
178 	_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
179 
180 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
181 
182 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
183 		_rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
184 	else
185 		_rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
186 
187 	RTW_PRINT("assoc success\n");
188 #ifndef CONFIG_IOCTL_CFG80211
189 	wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
190 #endif
191 }
192 
rtw_indicate_wx_disassoc_event(_adapter * padapter)193 void rtw_indicate_wx_disassoc_event(_adapter *padapter)
194 {
195 	union iwreq_data wrqu;
196 
197 	_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
198 
199 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
200 	_rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
201 
202 #ifndef CONFIG_IOCTL_CFG80211
203 	RTW_PRINT("indicate disassoc\n");
204 	wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
205 #endif
206 }
207 
208 /*
209 uint	rtw_is_cckrates_included(u8 *rate)
210 {
211 		u32	i = 0;
212 
213 		while(rate[i]!=0)
214 		{
215 			if  (  (((rate[i]) & 0x7f) == 2)	|| (((rate[i]) & 0x7f) == 4) ||
216 			(((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22) )
217 			return _TRUE;
218 			i++;
219 		}
220 
221 		return _FALSE;
222 }
223 
224 uint	rtw_is_cckratesonly_included(u8 *rate)
225 {
226 	u32 i = 0;
227 
228 	while(rate[i]!=0)
229 	{
230 			if  (  (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
231 				(((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22) )
232 			return _FALSE;
233 			i++;
234 	}
235 
236 	return _TRUE;
237 }
238 */
239 
240 #ifdef CONFIG_IOCTL_WEXT
search_p2p_wfd_ie(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)241 static int search_p2p_wfd_ie(_adapter *padapter,
242 		struct iw_request_info *info, struct wlan_network *pnetwork,
243 		char *start, char *stop)
244 {
245 #ifdef CONFIG_P2P
246 	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
247 #ifdef CONFIG_WFD
248 	if (SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type) {
249 
250 	} else if ((SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type) ||
251 		(SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type))
252 #endif /* CONFIG_WFD */
253 	{
254 		if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
255 			u32	blnGotP2PIE = _FALSE;
256 
257 			/*	User is doing the P2P device discovery */
258 			/*	The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
259 			/*	If not, the driver should ignore this AP and go to the next AP. */
260 
261 			/*	Verifying the SSID */
262 			if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
263 				u32	p2pielen = 0;
264 
265 				/*	Verifying the P2P IE */
266 				if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen))
267 					blnGotP2PIE = _TRUE;
268 			}
269 
270 			if (blnGotP2PIE == _FALSE)
271 				return _FALSE;
272 
273 		}
274 	}
275 
276 #ifdef CONFIG_WFD
277 	if (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type) {
278 		u32	blnGotWFD = _FALSE;
279 		u8 *wfd_ie;
280 		uint wfd_ielen = 0;
281 
282 		wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
283 		if (wfd_ie) {
284 			u8 *wfd_devinfo;
285 			uint wfd_devlen;
286 
287 			wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
288 			if (wfd_devinfo) {
289 				if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK) {
290 					/*	the first two bits will indicate the WFD device type */
291 					if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_SOURCE) {
292 						/*	If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. */
293 						blnGotWFD = _TRUE;
294 					}
295 				} else if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE) {
296 					/*	the first two bits will indicate the WFD device type */
297 					if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_PSINK) {
298 						/*	If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. */
299 						/*	Todo: How about the SSink?! */
300 						blnGotWFD = _TRUE;
301 					}
302 				}
303 			}
304 		}
305 
306 		if (blnGotWFD == _FALSE)
307 			return _FALSE;
308 	}
309 #endif /* CONFIG_WFD */
310 
311 #endif /* CONFIG_P2P */
312 	return _TRUE;
313 }
iwe_stream_mac_addr_proess(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)314 static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,
315 		struct iw_request_info *info, struct wlan_network *pnetwork,
316 		char *start, char *stop, struct iw_event *iwe)
317 {
318 	/*  AP MAC address */
319 	iwe->cmd = SIOCGIWAP;
320 	iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
321 
322 	_rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
323 	start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);
324 	return start;
325 }
iwe_stream_essid_proess(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)326 static inline char *iwe_stream_essid_proess(_adapter *padapter,
327 		struct iw_request_info *info, struct wlan_network *pnetwork,
328 		char *start, char *stop, struct iw_event *iwe)
329 {
330 
331 	/* Add the ESSID */
332 	iwe->cmd = SIOCGIWESSID;
333 	iwe->u.data.flags = 1;
334 	iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
335 	start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
336 	return start;
337 }
338 
iwe_stream_chan_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)339 static inline char *iwe_stream_chan_process(_adapter *padapter,
340 		struct iw_request_info *info, struct wlan_network *pnetwork,
341 		char *start, char *stop, struct iw_event *iwe)
342 {
343 	if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
344 		pnetwork->network.Configuration.DSConfig = 1;
345 
346 	/* Add frequency/channel */
347 	iwe->cmd = SIOCGIWFREQ;
348 	iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
349 	iwe->u.freq.e = 1;
350 	iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;
351 	start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);
352 	return start;
353 }
iwe_stream_mode_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe,u16 cap)354 static inline char *iwe_stream_mode_process(_adapter *padapter,
355 		struct iw_request_info *info, struct wlan_network *pnetwork,
356 		char *start, char *stop, struct iw_event *iwe, u16 cap)
357 {
358 	/* Add mode */
359 	if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
360 		iwe->cmd = SIOCGIWMODE;
361 		if (cap & WLAN_CAPABILITY_BSS)
362 			iwe->u.mode = IW_MODE_MASTER;
363 		else
364 			iwe->u.mode = IW_MODE_ADHOC;
365 
366 		start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);
367 	}
368 	return start;
369 }
iwe_stream_encryption_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe,u16 cap)370 static inline char *iwe_stream_encryption_process(_adapter *padapter,
371 		struct iw_request_info *info, struct wlan_network *pnetwork,
372 		char *start, char *stop, struct iw_event *iwe, u16 cap)
373 {
374 
375 	/* Add encryption capability */
376 	iwe->cmd = SIOCGIWENCODE;
377 	if (cap & WLAN_CAPABILITY_PRIVACY)
378 		iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
379 	else
380 		iwe->u.data.flags = IW_ENCODE_DISABLED;
381 	iwe->u.data.length = 0;
382 	start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
383 	return start;
384 
385 }
386 
iwe_stream_protocol_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)387 static inline char *iwe_stream_protocol_process(_adapter *padapter,
388 		struct iw_request_info *info, struct wlan_network *pnetwork,
389 		char *start, char *stop, struct iw_event *iwe)
390 {
391 	u16 ht_cap = _FALSE, vht_cap = _FALSE;
392 	u32 ht_ielen = 0, vht_ielen = 0;
393 	char *p;
394 	u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request	 */
395 
396 #ifdef CONFIG_80211N_HT
397 	/* parsing HT_CAP_IE	 */
398 	if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
399 		p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
400 		if (p && ht_ielen > 0)
401 			ht_cap = _TRUE;
402 	}
403 #endif
404 
405 #ifdef CONFIG_80211AC_VHT
406 	/* parsing VHT_CAP_IE */
407 	if(padapter->registrypriv.wireless_mode & WIRELESS_11AC) {
408 		p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
409 		if (p && vht_ielen > 0)
410 			vht_cap = _TRUE;
411 	}
412 #endif
413 	/* Add the protocol name */
414 	iwe->cmd = SIOCGIWNAME;
415 	if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
416 		if (ht_cap == _TRUE)
417 			snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");
418 		else
419 			snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");
420 	} else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
421 		if (ht_cap == _TRUE)
422 			snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");
423 		else
424 			snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");
425 	} else {
426 		if (pnetwork->network.Configuration.DSConfig > 14) {
427 			#ifdef CONFIG_80211AC_VHT
428 			if (vht_cap == _TRUE)
429 				snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");
430 			else
431 			#endif
432 			{
433 				if (ht_cap == _TRUE)
434 					snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");
435 				else
436 					snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");
437 			}
438 		} else {
439 			if (ht_cap == _TRUE)
440 				snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");
441 			else
442 				snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");
443 		}
444 	}
445 	start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);
446 	return start;
447 }
448 
iwe_stream_rate_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)449 static inline char *iwe_stream_rate_process(_adapter *padapter,
450 		struct iw_request_info *info, struct wlan_network *pnetwork,
451 		char *start, char *stop, struct iw_event *iwe)
452 {
453 	u32 ht_ielen = 0, vht_ielen = 0;
454 	char *p;
455 	u16 max_rate = 0, rate, ht_cap = _FALSE, vht_cap = _FALSE;
456 	u32 i = 0;
457 	u8 bw_40MHz = 0, short_GI = 0, bw_160MHz = 0, vht_highest_rate = 0;
458 	u16 mcs_rate = 0, vht_data_rate = 0;
459 	char custom[MAX_CUSTOM_LEN] = {0};
460 	u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request	 */
461 
462 	/* parsing HT_CAP_IE	 */
463 	if(is_supported_ht(padapter->registrypriv.wireless_mode)) {
464 		p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
465 		if (p && ht_ielen > 0) {
466 			struct rtw_ieee80211_ht_cap *pht_capie;
467 			ht_cap = _TRUE;
468 			pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
469 			_rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
470 			bw_40MHz = (pht_capie->cap_info & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
471 			short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
472 		}
473 	}
474 #ifdef CONFIG_80211AC_VHT
475 	/* parsing VHT_CAP_IE */
476 	if(padapter->registrypriv.wireless_mode & WIRELESS_11AC){
477 		p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
478 		if (p && vht_ielen > 0) {
479 			u8	mcs_map[2];
480 
481 			vht_cap = _TRUE;
482 			bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p + 2);
483 			if (bw_160MHz)
484 				short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p + 2);
485 			else
486 				short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p + 2);
487 
488 			_rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p + 2), 2);
489 
490 			vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
491 			vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
492 		}
493 	}
494 #endif
495 
496 	/*Add basic and extended rates */
497 	p = custom;
498 	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
499 	while (pnetwork->network.SupportedRates[i] != 0) {
500 		rate = pnetwork->network.SupportedRates[i] & 0x7F;
501 		if (rate > max_rate)
502 			max_rate = rate;
503 		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
504 			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
505 		i++;
506 	}
507 #ifdef CONFIG_80211AC_VHT
508 	if (vht_cap == _TRUE)
509 		max_rate = vht_data_rate;
510 	else
511 #endif
512 		if (ht_cap == _TRUE) {
513 			if (mcs_rate & 0x8000) /* MCS15 */
514 				max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
515 
516 			else if (mcs_rate & 0x0080) /* MCS7 */
517 				max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
518 			else { /* default MCS7 */
519 				/* RTW_INFO("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); */
520 				max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
521 			}
522 
523 			max_rate = max_rate * 2; /* Mbps/2;		 */
524 		}
525 
526 	iwe->cmd = SIOCGIWRATE;
527 	iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
528 	iwe->u.bitrate.value = max_rate * 500000;
529 	start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);
530 	return start ;
531 }
532 
iwe_stream_wpa_wpa2_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)533 static inline char *iwe_stream_wpa_wpa2_process(_adapter *padapter,
534 		struct iw_request_info *info, struct wlan_network *pnetwork,
535 		char *start, char *stop, struct iw_event *iwe)
536 {
537 	int buf_size = MAX_WPA_IE_LEN * 2;
538 	/* u8 pbuf[buf_size]={0};	 */
539 	u8 *pbuf = rtw_zmalloc(buf_size);
540 
541 	u8 wpa_ie[255] = {0}, rsn_ie[255] = {0};
542 	u16 i, wpa_len = 0, rsn_len = 0;
543 	u8 *p;
544 	sint out_len = 0;
545 
546 
547 	if (pbuf) {
548 		p = pbuf;
549 
550 		/* parsing WPA/WPA2 IE */
551 		if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */
552 			out_len = rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
553 
554 			if (wpa_len > 0) {
555 
556 				_rtw_memset(pbuf, 0, buf_size);
557 				p += sprintf(p, "wpa_ie=");
558 				for (i = 0; i < wpa_len; i++)
559 					p += sprintf(p, "%02x", wpa_ie[i]);
560 
561 				if (wpa_len > 100) {
562 					printk("-----------------Len %d----------------\n", wpa_len);
563 					for (i = 0; i < wpa_len; i++)
564 						printk("%02x ", wpa_ie[i]);
565 					printk("\n");
566 					printk("-----------------Len %d----------------\n", wpa_len);
567 				}
568 
569 				_rtw_memset(iwe, 0, sizeof(*iwe));
570 				iwe->cmd = IWEVCUSTOM;
571 				iwe->u.data.length = strlen(pbuf);
572 				start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
573 
574 				_rtw_memset(iwe, 0, sizeof(*iwe));
575 				iwe->cmd = IWEVGENIE;
576 				iwe->u.data.length = wpa_len;
577 				start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
578 			}
579 			if (rsn_len > 0) {
580 
581 				_rtw_memset(pbuf, 0, buf_size);
582 				p += sprintf(p, "rsn_ie=");
583 				for (i = 0; i < rsn_len; i++)
584 					p += sprintf(p, "%02x", rsn_ie[i]);
585 				_rtw_memset(iwe, 0, sizeof(*iwe));
586 				iwe->cmd = IWEVCUSTOM;
587 				iwe->u.data.length = strlen(pbuf);
588 				start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
589 
590 				_rtw_memset(iwe, 0, sizeof(*iwe));
591 				iwe->cmd = IWEVGENIE;
592 				iwe->u.data.length = rsn_len;
593 				start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
594 			}
595 		}
596 
597 		rtw_mfree(pbuf, buf_size);
598 	}
599 	return start;
600 }
601 
iwe_stream_wps_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)602 static inline char *iwe_stream_wps_process(_adapter *padapter,
603 		struct iw_request_info *info, struct wlan_network *pnetwork,
604 		char *start, char *stop, struct iw_event *iwe)
605 {
606 	/* parsing WPS IE */
607 	uint cnt = 0, total_ielen;
608 	u8 *wpsie_ptr = NULL;
609 	uint wps_ielen = 0;
610 	u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);
611 
612 	u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
613 	total_ielen = pnetwork->network.IELength - ie_offset;
614 
615 	if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) { /* Probe Request */
616 		ie_ptr = pnetwork->network.IEs;
617 		total_ielen = pnetwork->network.IELength;
618 	} else { /* Beacon or Probe Respones */
619 		ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
620 		total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
621 	}
622 	while (cnt < total_ielen) {
623 		if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
624 			wpsie_ptr = &ie_ptr[cnt];
625 			iwe->cmd = IWEVGENIE;
626 			iwe->u.data.length = (u16)wps_ielen;
627 			start = iwe_stream_add_point(info, start, stop, iwe, wpsie_ptr);
628 		}
629 		cnt += ie_ptr[cnt + 1] + 2; /* goto next */
630 	}
631 	return start;
632 }
633 
iwe_stream_wapi_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)634 static inline char *iwe_stream_wapi_process(_adapter *padapter,
635 		struct iw_request_info *info, struct wlan_network *pnetwork,
636 		char *start, char *stop, struct iw_event *iwe)
637 {
638 #ifdef CONFIG_WAPI_SUPPORT
639 	char *p;
640 
641 	if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */
642 		sint out_len_wapi = 0;
643 		/* here use static for stack size */
644 		static u8 buf_wapi[MAX_WAPI_IE_LEN * 2] = {0};
645 		static u8 wapi_ie[MAX_WAPI_IE_LEN] = {0};
646 		u16 wapi_len = 0;
647 		u16  i;
648 
649 		out_len_wapi = rtw_get_wapi_ie(pnetwork->network.IEs , pnetwork->network.IELength, wapi_ie, &wapi_len);
650 
651 		RTW_INFO("rtw_wx_get_scan: %s ", pnetwork->network.Ssid.Ssid);
652 		RTW_INFO("rtw_wx_get_scan: ssid = %d ", wapi_len);
653 
654 
655 		if (wapi_len > 0) {
656 			p = buf_wapi;
657 			/* _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2); */
658 			p += sprintf(p, "wapi_ie=");
659 			for (i = 0; i < wapi_len; i++)
660 				p += sprintf(p, "%02x", wapi_ie[i]);
661 
662 			_rtw_memset(iwe, 0, sizeof(*iwe));
663 			iwe->cmd = IWEVCUSTOM;
664 			iwe->u.data.length = strlen(buf_wapi);
665 			start = iwe_stream_add_point(info, start, stop, iwe, buf_wapi);
666 
667 			_rtw_memset(iwe, 0, sizeof(*iwe));
668 			iwe->cmd = IWEVGENIE;
669 			iwe->u.data.length = wapi_len;
670 			start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);
671 		}
672 	}
673 #endif/* #ifdef CONFIG_WAPI_SUPPORT */
674 	return start;
675 }
676 
iwe_stream_rssi_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)677 static inline char   *iwe_stream_rssi_process(_adapter *padapter,
678 		struct iw_request_info *info, struct wlan_network *pnetwork,
679 		char *start, char *stop, struct iw_event *iwe)
680 {
681 	u8 ss, sq;
682 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
683 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
684 	s16 noise = 0;
685 #endif
686 
687 	/* Add quality statistics */
688 	iwe->cmd = IWEVQUAL;
689 	iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
690 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
691 			      | IW_QUAL_NOISE_UPDATED
692 #else
693 			      | IW_QUAL_NOISE_INVALID
694 #endif
695 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
696 			      | IW_QUAL_DBM
697 #endif
698 			      ;
699 
700 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
701 	    is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
702 		ss = padapter->recvpriv.signal_strength;
703 		sq = padapter->recvpriv.signal_qual;
704 	} else {
705 		ss = pnetwork->network.PhyInfo.SignalStrength;
706 		sq = pnetwork->network.PhyInfo.SignalQuality;
707 	}
708 
709 
710 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
711 	iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
712 #else
713 	iwe->u.qual.level = (u8)ss; /* % */
714 #endif
715 
716 	iwe->u.qual.qual = (u8)sq;   /* signal quality */
717 
718 #ifdef CONFIG_PLATFORM_ROCKCHIPS
719 	iwe->u.qual.noise = -100; /* noise level suggest by zhf@rockchips */
720 #else
721 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
722 	if (IS_NM_ENABLE(padapter)) {
723 		noise = rtw_noise_query_by_chan_num(padapter, pnetwork->network.Configuration.DSConfig);
724 		#ifndef CONFIG_SIGNAL_DISPLAY_DBM
725 		noise = translate_dbm_to_percentage(noise);/*percentage*/
726 		#endif
727 		iwe->u.qual.noise = noise;
728 	}
729 #else
730 	iwe->u.qual.noise = 0; /* noise level */
731 #endif
732 #endif /* CONFIG_PLATFORM_ROCKCHIPS */
733 
734 	/* RTW_INFO("iqual=%d, ilevel=%d, inoise=%d, iupdated=%d\n", iwe.u.qual.qual, iwe.u.qual.level , iwe.u.qual.noise, iwe.u.qual.updated); */
735 
736 	start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);
737 	return start;
738 }
739 
iwe_stream_net_rsv_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)740 static inline char   *iwe_stream_net_rsv_process(_adapter *padapter,
741 		struct iw_request_info *info, struct wlan_network *pnetwork,
742 		char *start, char *stop, struct iw_event *iwe)
743 {
744 	u8 buf[32] = {0};
745 	u8 *p, *pos;
746 	p = buf;
747 	pos = pnetwork->network.Reserved;
748 
749 	p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
750 	_rtw_memset(iwe, 0, sizeof(*iwe));
751 	iwe->cmd = IWEVCUSTOM;
752 	iwe->u.data.length = strlen(buf);
753 	start = iwe_stream_add_point(info, start, stop, iwe, buf);
754 	return start;
755 }
756 
translate_scan(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)757 static char *translate_scan(_adapter *padapter,
758 		struct iw_request_info *info, struct wlan_network *pnetwork,
759 		char *start, char *stop)
760 {
761 	struct iw_event iwe;
762 	u16 cap = 0;
763 	_rtw_memset(&iwe, 0, sizeof(iwe));
764 
765 	if (_FALSE == search_p2p_wfd_ie(padapter, info, pnetwork, start, stop))
766 		return start;
767 
768 	start = iwe_stream_mac_addr_proess(padapter, info, pnetwork, start, stop, &iwe);
769 	start = iwe_stream_essid_proess(padapter, info, pnetwork, start, stop, &iwe);
770 	start = iwe_stream_protocol_process(padapter, info, pnetwork, start, stop, &iwe);
771 	if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) /* Probe Request */
772 		cap = 0;
773 	else {
774 		_rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
775 		cap = le16_to_cpu(cap);
776 	}
777 
778 	start = iwe_stream_mode_process(padapter, info, pnetwork, start, stop, &iwe, cap);
779 	start = iwe_stream_chan_process(padapter, info, pnetwork, start, stop, &iwe);
780 	start = iwe_stream_encryption_process(padapter, info, pnetwork, start, stop, &iwe, cap);
781 	start = iwe_stream_rate_process(padapter, info, pnetwork, start, stop, &iwe);
782 	start = iwe_stream_wpa_wpa2_process(padapter, info, pnetwork, start, stop, &iwe);
783 	start = iwe_stream_wps_process(padapter, info, pnetwork, start, stop, &iwe);
784 	start = iwe_stream_wapi_process(padapter, info, pnetwork, start, stop, &iwe);
785 	start = iwe_stream_rssi_process(padapter, info, pnetwork, start, stop, &iwe);
786 	start = iwe_stream_net_rsv_process(padapter, info, pnetwork, start, stop, &iwe);
787 
788 	return start;
789 }
790 
wpa_set_auth_algs(struct net_device * dev,u32 value)791 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
792 {
793 	_adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
794 	int ret = 0;
795 
796 	if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
797 		RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and  AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
798 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
799 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
800 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
801 	} else if (value & AUTH_ALG_SHARED_KEY) {
802 		RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY  [value:0x%x]\n", value);
803 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
804 
805 #ifdef CONFIG_PLATFORM_MT53XX
806 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
807 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
808 #else
809 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
810 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
811 #endif
812 	} else if (value & AUTH_ALG_OPEN_SYSTEM) {
813 		RTW_INFO("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
814 		/* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
815 		if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
816 #ifdef CONFIG_PLATFORM_MT53XX
817 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
818 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
819 #else
820 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
821 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
822 #endif
823 		}
824 
825 	} else if (value & AUTH_ALG_LEAP)
826 		RTW_INFO("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
827 	else {
828 		RTW_INFO("wpa_set_auth_algs, error!\n");
829 		ret = -EINVAL;
830 	}
831 
832 	return ret;
833 
834 }
835 
wpa_set_encryption(struct net_device * dev,struct ieee_param * param,u32 param_len)836 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
837 {
838 	int ret = 0;
839 	u32 wep_key_idx, wep_key_len;
840 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
841 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
842 	struct security_priv *psecuritypriv = &padapter->securitypriv;
843 #ifdef CONFIG_P2P
844 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
845 #endif /* CONFIG_P2P */
846 
847 
848 	param->u.crypt.err = 0;
849 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
850 
851 	if (param_len < (u32)((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
852 		ret =  -EINVAL;
853 		goto exit;
854 	}
855 
856 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
857 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
858 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
859 
860 		if (param->u.crypt.idx >= WEP_KEYS
861 #ifdef CONFIG_IEEE80211W
862 		    && param->u.crypt.idx > BIP_MAX_KEYID
863 #endif /* CONFIG_IEEE80211W */
864 		   ) {
865 			ret = -EINVAL;
866 			goto exit;
867 		}
868 	} else {
869 #ifdef CONFIG_WAPI_SUPPORT
870 		if (strcmp(param->u.crypt.alg, "SMS4"))
871 #endif
872 		{
873 			ret = -EINVAL;
874 			goto exit;
875 		}
876 	}
877 
878 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
879 		RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
880 
881 		wep_key_idx = param->u.crypt.idx;
882 		wep_key_len = param->u.crypt.key_len;
883 
884 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
885 			ret = -EINVAL;
886 			goto exit;
887 		}
888 
889 		if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
890 			/* wep default key has not been set, so use this key index as default key.*/
891 
892 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
893 
894 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
895 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
896 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
897 
898 			if (wep_key_len == 13) {
899 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
900 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
901 			}
902 
903 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
904 		}
905 
906 		_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
907 
908 		psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
909 
910 		psecuritypriv->key_mask |= BIT(wep_key_idx);
911 
912 		padapter->mlmeextpriv.mlmext_info.key_index = wep_key_idx;
913 		goto exit;
914 	}
915 
916 	if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
917 		struct sta_info *psta, *pbcmc_sta;
918 		struct sta_priv *pstapriv = &padapter->stapriv;
919 
920 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
921 			psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
922 			if (psta == NULL) {
923 				/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
924 			} else {
925 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
926 				if (strcmp(param->u.crypt.alg, "none") != 0)
927 					psta->ieee8021x_blocked = _FALSE;
928 
929 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
930 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
931 					psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
932 
933 				if (param->u.crypt.set_tx == 1) { /* pairwise key */
934 					RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n"
935 						, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
936 					_rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
937 					if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
938 						_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
939 						_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
940 						padapter->securitypriv.busetkipkey = _FALSE;
941 					}
942 					psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
943 					psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
944 					psta->bpairwise_key_installed = _TRUE;
945 					rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
946 
947 				} else { /* group key */
948 					if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
949 						RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"
950 							, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
951 						_rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key,
952 							(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
953 						/* only TKIP group key need to install this */
954 						if (param->u.crypt.key_len > 16) {
955 							_rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
956 							_rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
957 						}
958 						padapter->securitypriv.binstallGrpkey = _TRUE;
959 						if (param->u.crypt.idx < 4)
960 							_rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8);
961 						padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
962 						rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
963 
964 					#ifdef CONFIG_IEEE80211W
965 					} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
966 						RTW_INFO(FUNC_ADPT_FMT" set IGTK idx:%u, len:%u\n"
967 							, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
968 						_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,  param->u.crypt.key,
969 							(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
970 						psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
971 						psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
972 						psecuritypriv->binstallBIPkey = _TRUE;
973 					#endif /* CONFIG_IEEE80211W */
974 
975 					}
976 
977 #ifdef CONFIG_P2P
978 					if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
979 						rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
980 #endif /* CONFIG_P2P */
981 
982 					/* WPA/WPA2 key-handshake has completed */
983 					clr_fwstate(pmlmepriv, WIFI_UNDER_KEY_HANDSHAKE);
984 				}
985 			}
986 
987 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
988 			if (pbcmc_sta == NULL) {
989 				/* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
990 			} else {
991 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
992 				if (strcmp(param->u.crypt.alg, "none") != 0)
993 					pbcmc_sta->ieee8021x_blocked = _FALSE;
994 
995 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
996 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
997 					pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
998 			}
999 		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1000 		}
1001 	}
1002 
1003 #ifdef CONFIG_WAPI_SUPPORT
1004 	if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1005 		rtw_wapi_set_set_encryption(padapter, param);
1006 #endif
1007 
1008 exit:
1009 
1010 
1011 	return ret;
1012 }
1013 
rtw_set_wpa_ie(_adapter * padapter,char * pie,unsigned short ielen)1014 static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1015 {
1016 	u8 *buf = NULL, *pos = NULL;
1017 	int group_cipher = 0, pairwise_cipher = 0;
1018 	u8 mfp_opt = MFP_NO;
1019 	int ret = 0;
1020 	u8 null_addr[] = {0, 0, 0, 0, 0, 0};
1021 #ifdef CONFIG_P2P
1022 	struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1023 #endif /* CONFIG_P2P */
1024 
1025 	if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
1026 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1027 		if (pie == NULL)
1028 			return ret;
1029 		else
1030 			return -EINVAL;
1031 	}
1032 
1033 	if (ielen) {
1034 		buf = rtw_zmalloc(ielen);
1035 		if (buf == NULL) {
1036 			ret =  -ENOMEM;
1037 			goto exit;
1038 		}
1039 
1040 		_rtw_memcpy(buf, pie , ielen);
1041 
1042 		/* dump */
1043 		{
1044 			int i;
1045 			RTW_INFO("\n wpa_ie(length:%d):\n", ielen);
1046 			for (i = 0; i < ielen; i = i + 8)
1047 				RTW_INFO("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
1048 		}
1049 
1050 		pos = buf;
1051 		if (ielen < RSN_HEADER_LEN) {
1052 			ret  = -1;
1053 			goto exit;
1054 		}
1055 
1056 		if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1057 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1058 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
1059 			_rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1060 		}
1061 
1062 		if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL, NULL, &mfp_opt, NULL) == _SUCCESS) {
1063 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1064 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1065 			_rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1066 		}
1067 
1068 		if (group_cipher == 0)
1069 			group_cipher = WPA_CIPHER_NONE;
1070 		if (pairwise_cipher == 0)
1071 			pairwise_cipher = WPA_CIPHER_NONE;
1072 
1073 		switch (group_cipher) {
1074 		case WPA_CIPHER_NONE:
1075 			padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1076 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1077 			break;
1078 		case WPA_CIPHER_WEP40:
1079 			padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1080 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1081 			break;
1082 		case WPA_CIPHER_TKIP:
1083 			padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1084 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1085 			break;
1086 		case WPA_CIPHER_CCMP:
1087 			padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1088 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1089 			break;
1090 		case WPA_CIPHER_WEP104:
1091 			padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1092 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1093 			break;
1094 		}
1095 
1096 		switch (pairwise_cipher) {
1097 		case WPA_CIPHER_NONE:
1098 			padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1099 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1100 			break;
1101 		case WPA_CIPHER_WEP40:
1102 			padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1103 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1104 			break;
1105 		case WPA_CIPHER_TKIP:
1106 			padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1107 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1108 			break;
1109 		case WPA_CIPHER_CCMP:
1110 			padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
1111 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1112 			break;
1113 		case WPA_CIPHER_WEP104:
1114 			padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1115 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1116 			break;
1117 		}
1118 
1119 		if (mfp_opt == MFP_INVALID) {
1120 			RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));
1121 			ret = -EINVAL;
1122 			goto exit;
1123 		}
1124 		padapter->securitypriv.mfp_opt = mfp_opt;
1125 
1126 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1127 		{/* set wps_ie	 */
1128 			u16 cnt = 0;
1129 			u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
1130 
1131 			while (cnt < ielen) {
1132 				eid = buf[cnt];
1133 
1134 				if ((eid == _VENDOR_SPECIFIC_IE_) && (_rtw_memcmp(&buf[cnt + 2], wps_oui, 4) == _TRUE)) {
1135 					RTW_INFO("SET WPS_IE\n");
1136 
1137 					padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < MAX_WPS_IE_LEN) ? (buf[cnt + 1] + 2) : MAX_WPS_IE_LEN;
1138 
1139 					_rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1140 
1141 					set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1142 
1143 #ifdef CONFIG_P2P
1144 					if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1145 						rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1146 #endif /* CONFIG_P2P */
1147 					cnt += buf[cnt + 1] + 2;
1148 
1149 					break;
1150 				} else {
1151 					cnt += buf[cnt + 1] + 2; /* goto next	 */
1152 				}
1153 			}
1154 		}
1155 
1156 		#ifdef CONFIG_RTW_MULTI_AP
1157 		padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA;
1158 		if (padapter->multi_ap)
1159 			adapter_set_use_wds(padapter, 1);
1160 		#endif
1161 	}
1162 
1163 	/* TKIP and AES disallow multicast packets until installing group key */
1164 	if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1165 	    || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1166 	    || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1167 		/* WPS open need to enable multicast
1168 		 * || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
1169 		rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1170 
1171 
1172 exit:
1173 
1174 	if (buf)
1175 		rtw_mfree(buf, ielen);
1176 
1177 	return ret;
1178 }
1179 
rtw_wx_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1180 static int rtw_wx_get_name(struct net_device *dev,
1181 			   struct iw_request_info *info,
1182 			   union iwreq_data *wrqu, char *extra)
1183 {
1184 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1185 	u32 ht_ielen = 0;
1186 	char *p;
1187 	u8 ht_cap = _FALSE, vht_cap = _FALSE;
1188 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1189 	WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1190 	NDIS_802_11_RATES_EX *prates = NULL;
1191 
1192 
1193 
1194 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
1195 		/* parsing HT_CAP_IE */
1196 		if( is_supported_ht(padapter->registrypriv.wireless_mode)&&(padapter->registrypriv.ht_enable)) {
1197 			p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
1198 			if (p && ht_ielen > 0 )
1199 				ht_cap = _TRUE;
1200 		}
1201 #ifdef CONFIG_80211AC_VHT
1202 		if ((padapter->registrypriv.wireless_mode & WIRELESS_11AC) &&
1203 			(pmlmepriv->vhtpriv.vht_option == _TRUE))
1204 			vht_cap = _TRUE;
1205 #endif
1206 
1207 		prates = &pcur_bss->SupportedRates;
1208 		if (rtw_is_cckratesonly_included((u8 *)prates) == _TRUE) {
1209 			if (ht_cap == _TRUE)
1210 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1211 			else
1212 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1213 		} else if ((rtw_is_cckrates_included((u8 *)prates)) == _TRUE) {
1214 			if (ht_cap == _TRUE)
1215 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1216 			else {
1217 				if(padapter->registrypriv.wireless_mode & WIRELESS_11G)
1218 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1219 				else
1220 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1221 			}
1222 		} else {
1223 			if (pcur_bss->Configuration.DSConfig > 14) {
1224 #ifdef CONFIG_80211AC_VHT
1225 				if (vht_cap == _TRUE)
1226 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1227 				else
1228 #endif
1229 				{
1230 					if (ht_cap == _TRUE)
1231 						snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1232 					else
1233 						snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1234 				}
1235 			} else {
1236 				if (ht_cap == _TRUE)
1237 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1238 				else
1239 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1240 			}
1241 		}
1242 	} else {
1243 		/* prates = &padapter->registrypriv.dev_network.SupportedRates; */
1244 		/* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */
1245 		snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1246 	}
1247 
1248 
1249 	return 0;
1250 }
1251 
rtw_wx_set_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1252 static int rtw_wx_set_freq(struct net_device *dev,
1253 			   struct iw_request_info *info,
1254 			   union iwreq_data *wrqu, char *extra)
1255 {
1256 
1257 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1258 	int exp = 1, freq = 0, div = 0;
1259 
1260 	rtw_ps_deny(padapter, PS_DENY_IOCTL);
1261 	if (rtw_pwr_wakeup(padapter) == _FALSE)
1262 		goto exit;
1263 	if (wrqu->freq.m <= 1000) {
1264 		if (wrqu->freq.flags == IW_FREQ_AUTO) {
1265 			if (rtw_chset_search_ch(adapter_to_chset(padapter), wrqu->freq.m) > 0) {
1266 				padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1267 				RTW_INFO("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m);
1268 			} else {
1269 				padapter->mlmeextpriv.cur_channel = 1;
1270 				RTW_INFO("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__);
1271 			}
1272 		} else {
1273 			padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1274 			RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1275 		}
1276 	} else {
1277 		while (wrqu->freq.e) {
1278 			exp *= 10;
1279 			wrqu->freq.e--;
1280 		}
1281 
1282 		freq = wrqu->freq.m;
1283 
1284 		while (!(freq % 10)) {
1285 			freq /= 10;
1286 			exp *= 10;
1287 		}
1288 
1289 		/* freq unit is MHz here */
1290 		div = 1000000 / exp;
1291 
1292 		if (div)
1293 			freq /= div;
1294 		else {
1295 			div = exp / 1000000;
1296 			freq *= div;
1297 		}
1298 
1299 		/* If freq is invalid, rtw_freq2ch() will return channel 1 */
1300 		padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);
1301 		RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1302 	}
1303 	set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
1304 exit:
1305 	rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
1306 
1307 	return 0;
1308 }
1309 
rtw_wx_get_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1310 static int rtw_wx_get_freq(struct net_device *dev,
1311 			   struct iw_request_info *info,
1312 			   union iwreq_data *wrqu, char *extra)
1313 {
1314 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1315 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1316 	WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1317 
1318 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1319 
1320 		wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1321 		wrqu->freq.e = 1;
1322 		wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1323 
1324 	} else {
1325 		wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1326 		wrqu->freq.e = 1;
1327 		wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1328 	}
1329 
1330 	return 0;
1331 }
1332 
rtw_wx_set_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)1333 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1334 			   union iwreq_data *wrqu, char *b)
1335 {
1336 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1337 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1338 	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1339 	int ret = 0;
1340 
1341 
1342 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1343 		ret = -EPERM;
1344 		goto exit;
1345 	}
1346 
1347 	if (!rtw_is_hw_init_completed(padapter)) {
1348 		ret = -EPERM;
1349 		goto exit;
1350 	}
1351 
1352 	/* initial default type */
1353 	dev->type = ARPHRD_ETHER;
1354 
1355 	if (wrqu->mode != IW_MODE_MONITOR) {
1356 		rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE);
1357 	}
1358 
1359 	switch (wrqu->mode) {
1360 #ifdef CONFIG_WIFI_MONITOR
1361 	case IW_MODE_MONITOR:
1362 		networkType = Ndis802_11Monitor;
1363 
1364 		rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE);
1365 		LeaveAllPowerSaveMode(padapter);
1366 
1367 #if 0
1368 		dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
1369 #endif
1370 
1371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
1372 		dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
1373 		RTW_INFO("set_mode = IW_MODE_MONITOR\n");
1374 #else
1375 		RTW_INFO("kernel version < 2.6.24 not support IW_MODE_MONITOR\n");
1376 #endif
1377 		break;
1378 #endif /* CONFIG_WIFI_MONITOR */
1379 	case IW_MODE_AUTO:
1380 		networkType = Ndis802_11AutoUnknown;
1381 		RTW_INFO("set_mode = IW_MODE_AUTO\n");
1382 		break;
1383 	case IW_MODE_ADHOC:
1384 		networkType = Ndis802_11IBSS;
1385 		RTW_INFO("set_mode = IW_MODE_ADHOC\n");
1386 		break;
1387 	case IW_MODE_MASTER:
1388 		networkType = Ndis802_11APMode;
1389 		RTW_INFO("set_mode = IW_MODE_MASTER\n");
1390 		break;
1391 	case IW_MODE_INFRA:
1392 		networkType = Ndis802_11Infrastructure;
1393 		RTW_INFO("set_mode = IW_MODE_INFRA\n");
1394 		break;
1395 
1396 	default:
1397 		ret = -EINVAL;;
1398 		goto exit;
1399 	}
1400 
1401 #ifdef CONFIG_AP_MODE
1402 	if (MLME_IS_AP(padapter) && networkType == Ndis802_11Infrastructure)
1403 		rtw_stop_ap_cmd(padapter, RTW_CMDF_WAIT_ACK);
1404 	else
1405 #endif
1406 	{
1407 		if (rtw_set_802_11_infrastructure_mode(padapter, networkType, 0) == _FALSE) {
1408 			ret = -EPERM;
1409 			goto exit;
1410 		}
1411 		rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
1412 	}
1413 
1414 	if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1415 		rtw_indicate_connect(padapter);
1416 
1417 exit:
1418 
1419 
1420 	return ret;
1421 
1422 }
1423 
rtw_wx_get_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)1424 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1425 			   union iwreq_data *wrqu, char *b)
1426 {
1427 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1428 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1429 
1430 
1431 
1432 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1433 		wrqu->mode = IW_MODE_INFRA;
1434 	else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1435 		 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1436 
1437 		wrqu->mode = IW_MODE_ADHOC;
1438 	else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1439 		wrqu->mode = IW_MODE_MASTER;
1440 	else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1441 		wrqu->mode = IW_MODE_MONITOR;
1442 	else
1443 		wrqu->mode = IW_MODE_AUTO;
1444 
1445 
1446 	return 0;
1447 
1448 }
1449 
1450 
rtw_wx_set_pmkid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1451 static int rtw_wx_set_pmkid(struct net_device *dev,
1452 			    struct iw_request_info *a,
1453 			    union iwreq_data *wrqu, char *extra)
1454 {
1455 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1456 	u8          j, blInserted = _FALSE;
1457 	int         intReturn = _FALSE;
1458 	struct security_priv *psecuritypriv = &padapter->securitypriv;
1459 	struct iw_pmksa  *pPMK = (struct iw_pmksa *) extra;
1460 	u8     strZeroMacAddress[ETH_ALEN] = { 0x00 };
1461 	u8     strIssueBssid[ETH_ALEN] = { 0x00 };
1462 
1463 #if 0
1464 	struct iw_pmksa {
1465 		__u32   cmd;
1466 		struct sockaddr bssid;
1467 		__u8    pmkid[IW_PMKID_LEN];   /* IW_PMKID_LEN=16 */
1468 	}
1469 	There are the BSSID information in the bssid.sa_data array.
1470 	If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1471 	If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID / BSSID to driver.
1472 	If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID / BSSID from driver.
1473 #endif
1474 
1475 	_rtw_memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1476 	if (pPMK->cmd == IW_PMKSA_ADD) {
1477 		RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
1478 		if (_rtw_memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
1479 			return intReturn ;
1480 		else
1481 			intReturn = _TRUE;
1482 		blInserted = _FALSE;
1483 
1484 		/* overwrite PMKID */
1485 		for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1486 			if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1487 				/* BSSID is matched, the same AP => rewrite with new PMKID. */
1488 
1489 				RTW_INFO("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
1490 
1491 				_rtw_memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1492 				psecuritypriv->PMKIDList[j].bUsed = _TRUE;
1493 				blInserted = _TRUE;
1494 				break;
1495 			}
1496 		}
1497 
1498 		if (!blInserted) {
1499 			/* Find a new entry */
1500 			RTW_INFO("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1501 				 psecuritypriv->PMKIDIndex);
1502 
1503 			_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1504 			_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1505 
1506 			psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
1507 			psecuritypriv->PMKIDIndex++ ;
1508 			if (psecuritypriv->PMKIDIndex == 16)
1509 				psecuritypriv->PMKIDIndex = 0;
1510 		}
1511 	} else if (pPMK->cmd == IW_PMKSA_REMOVE) {
1512 		RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
1513 		intReturn = _TRUE;
1514 		for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1515 			if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1516 				/* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
1517 				_rtw_memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
1518 				psecuritypriv->PMKIDList[j].bUsed = _FALSE;
1519 				break;
1520 			}
1521 		}
1522 	} else if (pPMK->cmd == IW_PMKSA_FLUSH) {
1523 		RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
1524 		_rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
1525 		psecuritypriv->PMKIDIndex = 0;
1526 		intReturn = _TRUE;
1527 	}
1528 	return intReturn ;
1529 }
1530 
rtw_wx_get_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1531 static int rtw_wx_get_sens(struct net_device *dev,
1532 			   struct iw_request_info *info,
1533 			   union iwreq_data *wrqu, char *extra)
1534 {
1535 #ifdef CONFIG_PLATFORM_ROCKCHIPS
1536 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1537 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1538 
1539 	/*
1540 	*  20110311 Commented by Jeff
1541 	*  For rockchip platform's wpa_driver_wext_get_rssi
1542 	*/
1543 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
1544 		/* wrqu->sens.value=-padapter->recvpriv.signal_strength; */
1545 		wrqu->sens.value = -padapter->recvpriv.rssi;
1546 		/* RTW_INFO("%s: %d\n", __FUNCTION__, wrqu->sens.value); */
1547 		wrqu->sens.fixed = 0; /* no auto select */
1548 	} else
1549 #endif
1550 	{
1551 		wrqu->sens.value = 0;
1552 		wrqu->sens.fixed = 0;	/* no auto select */
1553 		wrqu->sens.disabled = 1;
1554 	}
1555 	return 0;
1556 }
1557 
rtw_wx_get_range(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1558 static int rtw_wx_get_range(struct net_device *dev,
1559 			    struct iw_request_info *info,
1560 			    union iwreq_data *wrqu, char *extra)
1561 {
1562 	struct iw_range *range = (struct iw_range *)extra;
1563 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1564 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1565 	u16 val;
1566 	int i;
1567 
1568 
1569 
1570 	wrqu->data.length = sizeof(*range);
1571 	_rtw_memset(range, 0, sizeof(*range));
1572 
1573 	/* Let's try to keep this struct in the same order as in
1574 	 * linux/include/wireless.h
1575 	 */
1576 
1577 	/* TODO: See what values we can set, and remove the ones we can't
1578 	 * set, or fill them with some default data.
1579 	 */
1580 
1581 	/* ~5 Mb/s real (802.11b) */
1582 	range->throughput = 5 * 1000 * 1000;
1583 
1584 	/* TODO: Not used in 802.11b?
1585 	*	range->min_nwid;	 Minimal NWID we are able to set  */
1586 	/* TODO: Not used in 802.11b?
1587 	*	range->max_nwid;	 Maximal NWID we are able to set  */
1588 
1589 	/* Old Frequency (backward compat - moved lower ) */
1590 	/*	range->old_num_channels;
1591 	 *	range->old_num_frequency;
1592 	 * 	range->old_freq[6];  Filler to keep "version" at the same offset  */
1593 
1594 	/* signal level threshold range */
1595 
1596 	/* Quality of link & SNR stuff */
1597 	/* Quality range (link, level, noise)
1598 	 * If the quality is absolute, it will be in the range [0 ; max_qual],
1599 	 * if the quality is dBm, it will be in the range [max_qual ; 0].
1600 	 * Don't forget that we use 8 bit arithmetics...
1601 	 *
1602 	 * If percentage range is 0~100
1603 	 * Signal strength dbm range logical is -100 ~ 0
1604 	 * but usually value is -90 ~ -20
1605 	 */
1606 	range->max_qual.qual = 100;
1607 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1608 	range->max_qual.level = (u8)-100;
1609 	range->max_qual.noise = (u8)-100;
1610 	range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1611 	range->max_qual.updated |= IW_QUAL_DBM;
1612 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
1613 	/* percent values between 0 and 100. */
1614 	range->max_qual.level = 100;
1615 	range->max_qual.noise = 100;
1616 	range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1617 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
1618 
1619 	/* This should contain the average/typical values of the quality
1620 	 * indicator. This should be the threshold between a "good" and
1621 	 * a "bad" link (example : monitor going from green to orange).
1622 	 * Currently, user space apps like quality monitors don't have any
1623 	 * way to calibrate the measurement. With this, they can split
1624 	 * the range between 0 and max_qual in different quality level
1625 	 * (using a geometric subdivision centered on the average).
1626 	 * I expect that people doing the user space apps will feedback
1627 	 * us on which value we need to put in each driver... */
1628 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1629 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1630 	/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
1631 	range->avg_qual.level = (u8)-70;
1632 	range->avg_qual.noise = 0;
1633 	range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1634 	range->avg_qual.updated |= IW_QUAL_DBM;
1635 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
1636 	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1637 	range->avg_qual.level = 30;
1638 	range->avg_qual.noise = 100;
1639 	range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1640 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
1641 
1642 	range->num_bitrates = RATE_COUNT;
1643 
1644 	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
1645 		range->bitrate[i] = rtw_rates[i];
1646 
1647 	range->min_frag = MIN_FRAG_THRESHOLD;
1648 	range->max_frag = MAX_FRAG_THRESHOLD;
1649 
1650 	range->pm_capa = 0;
1651 
1652 	range->we_version_compiled = WIRELESS_EXT;
1653 	range->we_version_source = 16;
1654 
1655 	/*	range->retry_capa;	 What retry options are supported
1656 	 *	range->retry_flags;	 How to decode max/min retry limit
1657 	 *	range->r_time_flags;	 How to decode max/min retry life
1658 	 *	range->min_retry;	 Minimal number of retries
1659 	 *	range->max_retry;	 Maximal number of retries
1660 	 *	range->min_r_time;	 Minimal retry lifetime
1661 	 *	range->max_r_time;	 Maximal retry lifetime  */
1662 
1663 	for (i = 0, val = 0; i < rfctl->max_chan_nums; i++) {
1664 
1665 		/* Include only legal frequencies for some countries */
1666 		if (rfctl->channel_set[i].ChannelNum != 0) {
1667 			range->freq[val].i = rfctl->channel_set[i].ChannelNum;
1668 			range->freq[val].m = rtw_ch2freq(rfctl->channel_set[i].ChannelNum) * 100000;
1669 			range->freq[val].e = 1;
1670 			val++;
1671 		}
1672 
1673 		if (val == IW_MAX_FREQUENCIES)
1674 			break;
1675 	}
1676 
1677 	range->num_channels = val;
1678 	range->num_frequency = val;
1679 
1680 	/* Commented by Albert 2009/10/13
1681 	 * The following code will proivde the security capability to network manager.
1682 	 * If the driver doesn't provide this capability to network manager,
1683 	 * the WPA/WPA2 routers can't be choosen in the network manager. */
1684 
1685 	/*
1686 	#define IW_SCAN_CAPA_NONE		0x00
1687 	#define IW_SCAN_CAPA_ESSID		0x01
1688 	#define IW_SCAN_CAPA_BSSID		0x02
1689 	#define IW_SCAN_CAPA_CHANNEL	0x04
1690 	#define IW_SCAN_CAPA_MODE		0x08
1691 	#define IW_SCAN_CAPA_RATE		0x10
1692 	#define IW_SCAN_CAPA_TYPE		0x20
1693 	#define IW_SCAN_CAPA_TIME		0x40
1694 	*/
1695 
1696 #if WIRELESS_EXT > 17
1697 	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1698 			  IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1699 #endif
1700 
1701 #ifdef IW_SCAN_CAPA_ESSID /* WIRELESS_EXT > 21 */
1702 	range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID |
1703 		   IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
1704 #endif
1705 
1706 
1707 
1708 	return 0;
1709 
1710 }
1711 
1712 /* set bssid flow
1713  * s1. rtw_set_802_11_infrastructure_mode()
1714  * s2. rtw_set_802_11_authentication_mode()
1715  * s3. set_802_11_encryption_mode()
1716  * s4. rtw_set_802_11_bssid() */
rtw_wx_set_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)1717 static int rtw_wx_set_wap(struct net_device *dev,
1718 			  struct iw_request_info *info,
1719 			  union iwreq_data *awrq,
1720 			  char *extra)
1721 {
1722 	_irqL	irqL;
1723 	uint ret = 0;
1724 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1725 	struct sockaddr *temp = (struct sockaddr *)awrq;
1726 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1727 	_list	*phead;
1728 	u8 *dst_bssid, *src_bssid;
1729 	_queue	*queue	= &(pmlmepriv->scanned_queue);
1730 	struct	wlan_network	*pnetwork = NULL;
1731 	NDIS_802_11_AUTHENTICATION_MODE	authmode;
1732 
1733 	/*
1734 	#ifdef CONFIG_CONCURRENT_MODE
1735 		if(padapter->adapter_type > PRIMARY_IFACE)
1736 		{
1737 			ret = -EINVAL;
1738 			goto exit;
1739 		}
1740 	#endif
1741 	*/
1742 
1743 #ifdef CONFIG_CONCURRENT_MODE
1744 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) {
1745 		RTW_INFO("set bssid, but buddy_intf is under scanning or linking\n");
1746 
1747 		ret = -EINVAL;
1748 
1749 		goto exit;
1750 	}
1751 #endif
1752 
1753 	rtw_ps_deny(padapter, PS_DENY_JOIN);
1754 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1755 		ret = -1;
1756 		goto cancel_ps_deny;
1757 	}
1758 
1759 	if (!padapter->bup) {
1760 		ret = -1;
1761 		goto cancel_ps_deny;
1762 	}
1763 
1764 
1765 	if (temp->sa_family != ARPHRD_ETHER) {
1766 		ret = -EINVAL;
1767 		goto cancel_ps_deny;
1768 	}
1769 
1770 	authmode = padapter->securitypriv.ndisauthtype;
1771 	_enter_critical_bh(&queue->lock, &irqL);
1772 	phead = get_list_head(queue);
1773 	pmlmepriv->pscanned = get_next(phead);
1774 
1775 	while (1) {
1776 
1777 		if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) {
1778 #if 0
1779 			ret = -EINVAL;
1780 			goto cancel_ps_deny;
1781 
1782 			if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
1783 				rtw_set_802_11_bssid(padapter, temp->sa_data);
1784 				goto cancel_ps_deny;
1785 			} else {
1786 				ret = -EINVAL;
1787 				goto cancel_ps_deny;
1788 			}
1789 #endif
1790 
1791 			break;
1792 		}
1793 
1794 		pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1795 
1796 		pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1797 
1798 		dst_bssid = pnetwork->network.MacAddress;
1799 
1800 		src_bssid = temp->sa_data;
1801 
1802 		if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) {
1803 			if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0)) {
1804 				ret = -1;
1805 				_exit_critical_bh(&queue->lock, &irqL);
1806 				goto cancel_ps_deny;
1807 			}
1808 
1809 			break;
1810 		}
1811 
1812 	}
1813 	_exit_critical_bh(&queue->lock, &irqL);
1814 
1815 	rtw_set_802_11_authentication_mode(padapter, authmode);
1816 	/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1817 	if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
1818 		ret = -1;
1819 		goto cancel_ps_deny;
1820 	}
1821 
1822 cancel_ps_deny:
1823 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1824 
1825 #ifdef CONFIG_CONCURRENT_MODE
1826 exit:
1827 #endif
1828 	return ret;
1829 }
1830 
rtw_wx_get_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1831 static int rtw_wx_get_wap(struct net_device *dev,
1832 			  struct iw_request_info *info,
1833 			  union iwreq_data *wrqu, char *extra)
1834 {
1835 
1836 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1837 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
1838 	WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
1839 
1840 	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1841 
1842 	_rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1843 
1844 
1845 
1846 	if (((check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) == _TRUE) ||
1847 	    ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
1848 	    ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE))
1849 
1850 		_rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1851 	else
1852 		_rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1853 
1854 
1855 	return 0;
1856 
1857 }
1858 
rtw_wx_set_mlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1859 static int rtw_wx_set_mlme(struct net_device *dev,
1860 			   struct iw_request_info *info,
1861 			   union iwreq_data *wrqu, char *extra)
1862 {
1863 #if 0
1864 	/* SIOCSIWMLME data */
1865 	struct	iw_mlme {
1866 		__u16		cmd; /* IW_MLME_* */
1867 		__u16		reason_code;
1868 		struct sockaddr	addr;
1869 	};
1870 #endif
1871 
1872 	int ret = 0;
1873 	u16 reason;
1874 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1875 	struct iw_mlme *mlme = (struct iw_mlme *) extra;
1876 
1877 
1878 	if (mlme == NULL)
1879 		return -1;
1880 
1881 	RTW_INFO("%s\n", __FUNCTION__);
1882 
1883 	reason = cpu_to_le16(mlme->reason_code);
1884 
1885 
1886 	RTW_INFO("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
1887 
1888 
1889 	switch (mlme->cmd) {
1890 	case IW_MLME_DEAUTH:
1891 		if (!rtw_set_802_11_disassociate(padapter))
1892 			ret = -1;
1893 		break;
1894 
1895 	case IW_MLME_DISASSOC:
1896 		if (!rtw_set_802_11_disassociate(padapter))
1897 			ret = -1;
1898 
1899 		break;
1900 
1901 	default:
1902 		return -EOPNOTSUPP;
1903 	}
1904 #ifdef CONFIG_RTW_REPEATER_SON
1905 	rtw_rson_do_disconnect(padapter);
1906 #endif
1907 	return ret;
1908 }
1909 
rtw_wx_set_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1910 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1911 			   union iwreq_data *wrqu, char *extra)
1912 {
1913 	u8 _status = _FALSE;
1914 	int ret = 0;
1915 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1916 	/*struct mlme_priv *pmlmepriv = &padapter->mlmepriv;*/
1917 	struct sitesurvey_parm parm;
1918 	u8 ssc_chk;
1919 #ifdef CONFIG_P2P
1920 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1921 #endif /* CONFIG_P2P */
1922 
1923 #ifdef DBG_IOCTL
1924 	RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
1925 #endif
1926 
1927 #if 1
1928 	ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
1929 
1930 	#ifdef CONFIG_DOSCAN_IN_BUSYTRAFFIC
1931 	if ((ssc_chk != SS_ALLOW) && (ssc_chk != SS_DENY_BUSY_TRAFFIC))
1932 	#else
1933 	/* When Busy Traffic, driver do not site survey. So driver return success. */
1934 	/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1935 	/* modify by thomas 2011-02-22. */
1936 	if (ssc_chk != SS_ALLOW)
1937 	#endif
1938 	{
1939 		if (ssc_chk == SS_DENY_MP_MODE)
1940 			ret = -EPERM;
1941 		#ifdef DBG_LA_MODE
1942 		else if (ssc_chk == SS_DENY_LA_MODE)
1943 			ret = -EPERM;
1944 		#endif
1945 		else
1946 			indicate_wx_scan_complete_event(padapter);
1947 
1948 		goto exit;
1949 	} else
1950 		RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1951 
1952 	rtw_ps_deny(padapter, PS_DENY_SCAN);
1953 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1954 		ret = -1;
1955 		goto cancel_ps_deny;
1956 	}
1957 	if (!rtw_is_adapter_up(padapter)) {
1958 		ret = -1;
1959 		goto cancel_ps_deny;
1960 	}
1961 #else
1962 
1963 #ifdef CONFIG_MP_INCLUDED
1964 	if (rtw_mp_mode_check(padapter)) {
1965 		RTW_INFO("MP mode block Scan request\n");
1966 		ret = -EPERM;
1967 		goto exit;
1968 	}
1969 #endif
1970 	if (rtw_is_scan_deny(padapter)) {
1971 		indicate_wx_scan_complete_event(padapter);
1972 		goto exit;
1973 	}
1974 
1975 	rtw_ps_deny(padapter, PS_DENY_SCAN);
1976 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1977 		ret = -1;
1978 		goto cancel_ps_deny;
1979 	}
1980 
1981 	if (!rtw_is_adapter_up(padapter)) {
1982 		ret = -1;
1983 		goto cancel_ps_deny;
1984 	}
1985 
1986 #ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC
1987 	/* When Busy Traffic, driver do not site survey. So driver return success. */
1988 	/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1989 	/* modify by thomas 2011-02-22. */
1990 	if (rtw_mi_busy_traffic_check(padapter)) {
1991 		indicate_wx_scan_complete_event(padapter);
1992 		goto cancel_ps_deny;
1993 	}
1994 #endif
1995 #ifdef CONFIG_RTW_REPEATER_SON
1996 	if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {
1997 		RTW_INFO(FUNC_ADPT_FMT" blocking scan for under rson scanning process\n", FUNC_ADPT_ARG(padapter));
1998 		indicate_wx_scan_complete_event(padapter);
1999 		goto cancel_ps_deny;
2000 	}
2001 #endif
2002 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2003 		RTW_INFO("AP mode process WPS\n");
2004 		indicate_wx_scan_complete_event(padapter);
2005 		goto cancel_ps_deny;
2006 	}
2007 
2008 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) {
2009 		indicate_wx_scan_complete_event(padapter);
2010 		goto cancel_ps_deny;
2011 	}
2012 
2013 #ifdef CONFIG_CONCURRENT_MODE
2014 	if (rtw_mi_buddy_check_fwstate(padapter,
2015 		       WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) {
2016 
2017 		indicate_wx_scan_complete_event(padapter);
2018 		goto cancel_ps_deny;
2019 	}
2020 #endif
2021 #endif
2022 
2023 #ifdef CONFIG_P2P
2024 	if (pwdinfo->p2p_state != P2P_STATE_NONE) {
2025 		rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2026 		rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2027 		rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2028 		rtw_free_network_queue(padapter, _TRUE);
2029 	}
2030 #endif /* CONFIG_P2P */
2031 
2032 #if WIRELESS_EXT >= 17
2033 	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
2034 		struct iw_scan_req *req = (struct iw_scan_req *)extra;
2035 
2036 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2037 			int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2038 
2039 			rtw_init_sitesurvey_parm(padapter, &parm);
2040 			_rtw_memcpy(&parm.ssid[0].Ssid, &req->essid, len);
2041 			parm.ssid[0].SsidLength = len;
2042 			parm.ssid_num = 1;
2043 
2044 			RTW_INFO("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2045 
2046 			_status = rtw_set_802_11_bssid_list_scan(padapter, &parm);
2047 
2048 		} else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2049 			RTW_INFO("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2050 
2051 	} else
2052 #endif
2053 
2054 		if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2055 		    && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2056 		   ) {
2057 			int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
2058 			char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
2059 			char section;
2060 			char sec_len;
2061 			int ssid_index = 0;
2062 
2063 			/* RTW_INFO("%s COMBO_SCAN header is recognized\n", __FUNCTION__); */
2064 			rtw_init_sitesurvey_parm(padapter, &parm);
2065 
2066 			while (len >= 1) {
2067 				section = *(pos++);
2068 				len -= 1;
2069 
2070 				switch (section) {
2071 				case WEXT_CSCAN_SSID_SECTION:
2072 					/* RTW_INFO("WEXT_CSCAN_SSID_SECTION\n"); */
2073 					if (len < 1) {
2074 						len = 0;
2075 						break;
2076 					}
2077 
2078 					sec_len = *(pos++);
2079 					len -= 1;
2080 
2081 					if (sec_len > 0 && sec_len <= len) {
2082 
2083 						parm.ssid[ssid_index].SsidLength = sec_len;
2084 						_rtw_memcpy(&parm.ssid[ssid_index].Ssid, pos, sec_len);
2085 
2086 						/* RTW_INFO("%s COMBO_SCAN with specific parm.ssid:%s, %d\n", __FUNCTION__ */
2087 						/*	, parm.ssid[ssid_index].Ssid, parm.ssid[ssid_index].SsidLength); */
2088 						ssid_index++;
2089 					}
2090 
2091 					pos += sec_len;
2092 					len -= sec_len;
2093 					break;
2094 
2095 
2096 				case WEXT_CSCAN_CHANNEL_SECTION:
2097 					/* RTW_INFO("WEXT_CSCAN_CHANNEL_SECTION\n"); */
2098 					pos += 1;
2099 					len -= 1;
2100 					break;
2101 				case WEXT_CSCAN_ACTV_DWELL_SECTION:
2102 					/* RTW_INFO("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); */
2103 					pos += 2;
2104 					len -= 2;
2105 					break;
2106 				case WEXT_CSCAN_PASV_DWELL_SECTION:
2107 					/* RTW_INFO("WEXT_CSCAN_PASV_DWELL_SECTION\n"); */
2108 					pos += 2;
2109 					len -= 2;
2110 					break;
2111 				case WEXT_CSCAN_HOME_DWELL_SECTION:
2112 					/* RTW_INFO("WEXT_CSCAN_HOME_DWELL_SECTION\n"); */
2113 					pos += 2;
2114 					len -= 2;
2115 					break;
2116 				case WEXT_CSCAN_TYPE_SECTION:
2117 					/* RTW_INFO("WEXT_CSCAN_TYPE_SECTION\n"); */
2118 					pos += 1;
2119 					len -= 1;
2120 					break;
2121 #if 0
2122 				case WEXT_CSCAN_NPROBE_SECTION:
2123 					RTW_INFO("WEXT_CSCAN_NPROBE_SECTION\n");
2124 					break;
2125 #endif
2126 
2127 				default:
2128 					/* RTW_INFO("Unknown CSCAN section %c\n", section); */
2129 					len = 0; /* stop parsing */
2130 				}
2131 				/* RTW_INFO("len:%d\n", len); */
2132 
2133 			}
2134 			parm.ssid_num = ssid_index;
2135 
2136 			/* jeff: it has still some scan paramater to parse, we only do this now... */
2137 			_status = rtw_set_802_11_bssid_list_scan(padapter, &parm);
2138 
2139 		} else
2140 
2141 			_status = rtw_set_802_11_bssid_list_scan(padapter, NULL);
2142 
2143 	if (_status == _FALSE)
2144 		ret = -1;
2145 
2146 cancel_ps_deny:
2147 	rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2148 
2149 exit:
2150 #ifdef DBG_IOCTL
2151 	RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2152 #endif
2153 
2154 	return ret;
2155 }
2156 
rtw_wx_get_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)2157 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2158 			   union iwreq_data *wrqu, char *extra)
2159 {
2160 	_irqL	irqL;
2161 	_list					*plist, *phead;
2162 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2163 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2164 	RT_CHANNEL_INFO *chset = rfctl->channel_set;
2165 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
2166 	_queue				*queue	= &(pmlmepriv->scanned_queue);
2167 	struct	wlan_network	*pnetwork = NULL;
2168 	char *ev = extra;
2169 	char *stop = ev + wrqu->data.length;
2170 	u32 ret = 0;
2171 	u32 wait_for_surveydone;
2172 	sint wait_status;
2173 	u8 ch;
2174 
2175 #ifdef CONFIG_P2P
2176 	struct	wifidirect_info	*pwdinfo = &padapter->wdinfo;
2177 #endif /* CONFIG_P2P */
2178 
2179 
2180 #ifdef DBG_IOCTL
2181 	RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2182 #endif
2183 
2184 	if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) {
2185 		ret = -EINVAL;
2186 		goto exit;
2187 	}
2188 
2189 #ifdef CONFIG_P2P
2190 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2191 		wait_for_surveydone = 200;
2192 	else {
2193 		/*	P2P is disabled */
2194 		wait_for_surveydone = 100;
2195 	}
2196 #else
2197 	{
2198 		wait_for_surveydone = 100;
2199 	}
2200 #endif /* CONFIG_P2P */
2201 
2202 #if 1 /* Wireless Extension use EAGAIN to try */
2203 	wait_status = WIFI_UNDER_SURVEY
2204 #ifndef CONFIG_RTW_ANDROID
2205 		      | WIFI_UNDER_LINKING
2206 #endif
2207 		      ;
2208 
2209 	while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2210 		return -EAGAIN;
2211 #else
2212 	wait_status = WIFI_UNDER_SURVEY
2213 #ifndef CONFIG_RTW_ANDROID
2214 		      | WIFI_UNDER_LINKING
2215 #endif
2216 		      ;
2217 
2218 	while (check_fwstate(pmlmepriv, wait_status) == _TRUE) {
2219 		rtw_msleep_os(30);
2220 		cnt++;
2221 		if (cnt > wait_for_surveydone)
2222 			break;
2223 	}
2224 #endif
2225 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2226 
2227 	phead = get_list_head(queue);
2228 	plist = get_next(phead);
2229 
2230 	while (1) {
2231 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
2232 			break;
2233 
2234 		if ((stop - ev) < SCAN_ITEM_SIZE) {
2235 			if(wrqu->data.length == MAX_SCAN_BUFFER_LEN){ /*max buffer len defined by iwlist*/
2236 				ret = 0;
2237 				RTW_INFO("%s: Scan results incomplete\n", __FUNCTION__);
2238 				break;
2239 			}
2240 			ret = -E2BIG;
2241 			break;
2242 		}
2243 
2244 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2245 		ch = pnetwork->network.Configuration.DSConfig;
2246 
2247 		/* report network only if the current channel set contains the channel to which this network belongs */
2248 		if (rtw_chset_search_ch(chset, ch) >= 0
2249 			&& rtw_mlme_band_check(padapter, ch) == _TRUE
2250 			&& _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2251 			&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
2252 				|| rtw_rfctl_dfs_domain_unknown(rfctl)
2253 				|| !rtw_chset_is_ch_non_ocp(chset, ch))
2254 		)
2255 			ev = translate_scan(padapter, a, pnetwork, ev, stop);
2256 
2257 		plist = get_next(plist);
2258 
2259 	}
2260 
2261 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2262 
2263 	wrqu->data.length = ev - extra;
2264 	wrqu->data.flags = 0;
2265 
2266 exit:
2267 
2268 
2269 #ifdef DBG_IOCTL
2270 	RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2271 #endif
2272 
2273 	return ret ;
2274 
2275 }
2276 
2277 /* set ssid flow
2278  * s1. rtw_set_802_11_infrastructure_mode()
2279  * s2. set_802_11_authenticaion_mode()
2280  * s3. set_802_11_encryption_mode()
2281  * s4. rtw_set_802_11_ssid() */
rtw_wx_set_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)2282 static int rtw_wx_set_essid(struct net_device *dev,
2283 			    struct iw_request_info *a,
2284 			    union iwreq_data *wrqu, char *extra)
2285 {
2286 	_irqL irqL;
2287 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2288 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2289 	_queue *queue = &pmlmepriv->scanned_queue;
2290 	_list *phead;
2291 	struct wlan_network *pnetwork = NULL;
2292 	NDIS_802_11_AUTHENTICATION_MODE authmode;
2293 	NDIS_802_11_SSID ndis_ssid;
2294 	u8 *dst_ssid, *src_ssid;
2295 
2296 	uint ret = 0, len;
2297 
2298 
2299 #ifdef DBG_IOCTL
2300 	RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2301 #endif
2302 #ifdef CONFIG_WEXT_DONT_JOIN_BYSSID
2303 	RTW_INFO("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);
2304 	return -EPERM;
2305 #endif
2306 
2307 #if WIRELESS_EXT <= 20
2308 	if ((wrqu->essid.length - 1) > IW_ESSID_MAX_SIZE) {
2309 #else
2310 	if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
2311 #endif
2312 		ret = -E2BIG;
2313 		goto exit;
2314 	}
2315 
2316 
2317 
2318 	rtw_ps_deny(padapter, PS_DENY_JOIN);
2319 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
2320 		ret = -1;
2321 		goto cancel_ps_deny;
2322 	}
2323 
2324 	if (!padapter->bup) {
2325 		ret = -1;
2326 		goto cancel_ps_deny;
2327 	}
2328 
2329 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2330 		ret = -1;
2331 		goto cancel_ps_deny;
2332 	}
2333 
2334 #ifdef CONFIG_CONCURRENT_MODE
2335 	if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING)) {
2336 		RTW_INFO("set ssid, but buddy_intf is under scanning or linking\n");
2337 		ret = -EINVAL;
2338 		goto cancel_ps_deny;
2339 	}
2340 #endif
2341 	authmode = padapter->securitypriv.ndisauthtype;
2342 	RTW_INFO("=>%s\n", __FUNCTION__);
2343 	if (wrqu->essid.flags && wrqu->essid.length) {
2344 		/* Commented by Albert 20100519 */
2345 		/* We got the codes in "set_info" function of iwconfig source code. */
2346 		/*	========================================= */
2347 		/*	wrq.u.essid.length = strlen(essid) + 1; */
2348 		/*	if(we_kernel_version > 20) */
2349 		/*		wrq.u.essid.length--; */
2350 		/*	========================================= */
2351 		/*	That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. */
2352 #if WIRELESS_EXT <= 20
2353 		len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE;
2354 #else
2355 		len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2356 #endif
2357 
2358 		if (wrqu->essid.length != 33)
2359 			RTW_INFO("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2360 
2361 		_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2362 		ndis_ssid.SsidLength = len;
2363 		_rtw_memcpy(ndis_ssid.Ssid, extra, len);
2364 		src_ssid = ndis_ssid.Ssid;
2365 
2366 		_enter_critical_bh(&queue->lock, &irqL);
2367 		phead = get_list_head(queue);
2368 		pmlmepriv->pscanned = get_next(phead);
2369 
2370 		while (1) {
2371 			if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) {
2372 #if 0
2373 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2374 					rtw_set_802_11_ssid(padapter, &ndis_ssid);
2375 
2376 					goto cancel_ps_deny;
2377 				} else {
2378 					ret = -EINVAL;
2379 					goto cancel_ps_deny;
2380 				}
2381 #endif
2382 
2383 				break;
2384 			}
2385 
2386 			pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2387 
2388 			pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2389 
2390 			dst_ssid = pnetwork->network.Ssid.Ssid;
2391 
2392 
2393 			if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2394 			    (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
2395 
2396 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2397 					if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2398 						continue;
2399 				}
2400 
2401 				if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0) == _FALSE) {
2402 					ret = -1;
2403 					_exit_critical_bh(&queue->lock, &irqL);
2404 					goto cancel_ps_deny;
2405 				}
2406 
2407 				break;
2408 			}
2409 		}
2410 		_exit_critical_bh(&queue->lock, &irqL);
2411 		rtw_set_802_11_authentication_mode(padapter, authmode);
2412 		/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
2413 		if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2414 			ret = -1;
2415 			goto cancel_ps_deny;
2416 		}
2417 	}
2418 
2419 cancel_ps_deny:
2420 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2421 
2422 exit:
2423 	RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
2424 
2425 #ifdef DBG_IOCTL
2426 	RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2427 #endif
2428 
2429 
2430 	return ret;
2431 }
2432 
2433 static int rtw_wx_get_essid(struct net_device *dev,
2434 			    struct iw_request_info *a,
2435 			    union iwreq_data *wrqu, char *extra)
2436 {
2437 	u32 len, ret = 0;
2438 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2439 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
2440 	WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
2441 
2442 
2443 
2444 	if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) ||
2445 	    (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
2446 		len = pcur_bss->Ssid.SsidLength;
2447 
2448 		wrqu->essid.length = len;
2449 
2450 		_rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2451 
2452 		wrqu->essid.flags = 1;
2453 	} else {
2454 		ret = -1;
2455 		goto exit;
2456 	}
2457 
2458 exit:
2459 
2460 
2461 	return ret;
2462 
2463 }
2464 
2465 static int rtw_wx_set_rate(struct net_device *dev,
2466 			   struct iw_request_info *a,
2467 			   union iwreq_data *wrqu, char *extra)
2468 {
2469 	int ret = 0;
2470 #if 0
2471 	int i;
2472 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2473 	u8	datarates[NumRates];
2474 	u32	target_rate = wrqu->bitrate.value;
2475 	u32	fixed = wrqu->bitrate.fixed;
2476 	u32	ratevalue = 0;
2477 	u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2478 
2479 
2480 
2481 	if (target_rate == -1) {
2482 		ratevalue = 11;
2483 		goto set_rate;
2484 	}
2485 	target_rate = target_rate / 100000;
2486 
2487 	switch (target_rate) {
2488 	case 10:
2489 		ratevalue = 0;
2490 		break;
2491 	case 20:
2492 		ratevalue = 1;
2493 		break;
2494 	case 55:
2495 		ratevalue = 2;
2496 		break;
2497 	case 60:
2498 		ratevalue = 3;
2499 		break;
2500 	case 90:
2501 		ratevalue = 4;
2502 		break;
2503 	case 110:
2504 		ratevalue = 5;
2505 		break;
2506 	case 120:
2507 		ratevalue = 6;
2508 		break;
2509 	case 180:
2510 		ratevalue = 7;
2511 		break;
2512 	case 240:
2513 		ratevalue = 8;
2514 		break;
2515 	case 360:
2516 		ratevalue = 9;
2517 		break;
2518 	case 480:
2519 		ratevalue = 10;
2520 		break;
2521 	case 540:
2522 		ratevalue = 11;
2523 		break;
2524 	default:
2525 		ratevalue = 11;
2526 		break;
2527 	}
2528 
2529 set_rate:
2530 
2531 	for (i = 0; i < NumRates; i++) {
2532 		if (ratevalue == mpdatarate[i]) {
2533 			datarates[i] = mpdatarate[i];
2534 			if (fixed == 0)
2535 				break;
2536 		} else
2537 			datarates[i] = 0xff;
2538 
2539 	}
2540 
2541 	if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
2542 		ret = -1;
2543 	}
2544 
2545 #endif
2546 	return ret;
2547 }
2548 
2549 static int rtw_wx_get_rate(struct net_device *dev,
2550 			   struct iw_request_info *info,
2551 			   union iwreq_data *wrqu, char *extra)
2552 {
2553 	u16 max_rate = 0;
2554 
2555 	max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
2556 
2557 	if (max_rate == 0)
2558 		return -EPERM;
2559 
2560 	wrqu->bitrate.fixed = 0;	/* no auto select */
2561 	wrqu->bitrate.value = max_rate * 100000;
2562 
2563 	return 0;
2564 }
2565 
2566 static int rtw_wx_set_rts(struct net_device *dev,
2567 			  struct iw_request_info *info,
2568 			  union iwreq_data *wrqu, char *extra)
2569 {
2570 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2571 
2572 
2573 	if (wrqu->rts.disabled)
2574 		padapter->registrypriv.rts_thresh = 2347;
2575 	else {
2576 		if (wrqu->rts.value < 0 ||
2577 		    wrqu->rts.value > 2347)
2578 			return -EINVAL;
2579 
2580 		padapter->registrypriv.rts_thresh = wrqu->rts.value;
2581 	}
2582 
2583 	RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2584 
2585 
2586 	return 0;
2587 
2588 }
2589 
2590 static int rtw_wx_get_rts(struct net_device *dev,
2591 			  struct iw_request_info *info,
2592 			  union iwreq_data *wrqu, char *extra)
2593 {
2594 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2595 
2596 
2597 	RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2598 
2599 	wrqu->rts.value = padapter->registrypriv.rts_thresh;
2600 	wrqu->rts.fixed = 0;	/* no auto select */
2601 	/* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
2602 
2603 
2604 	return 0;
2605 }
2606 
2607 static int rtw_wx_set_frag(struct net_device *dev,
2608 			   struct iw_request_info *info,
2609 			   union iwreq_data *wrqu, char *extra)
2610 {
2611 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2612 
2613 
2614 	if (wrqu->frag.disabled)
2615 		padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
2616 	else {
2617 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
2618 		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
2619 			return -EINVAL;
2620 
2621 		padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
2622 	}
2623 
2624 	RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2625 
2626 
2627 	return 0;
2628 
2629 }
2630 
2631 static int rtw_wx_get_frag(struct net_device *dev,
2632 			   struct iw_request_info *info,
2633 			   union iwreq_data *wrqu, char *extra)
2634 {
2635 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2636 
2637 
2638 	RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2639 
2640 	wrqu->frag.value = padapter->xmitpriv.frag_len;
2641 	wrqu->frag.fixed = 0;	/* no auto select */
2642 	/* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */
2643 
2644 
2645 	return 0;
2646 }
2647 
2648 static int rtw_wx_get_retry(struct net_device *dev,
2649 			    struct iw_request_info *info,
2650 			    union iwreq_data *wrqu, char *extra)
2651 {
2652 	/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
2653 
2654 
2655 	wrqu->retry.value = 7;
2656 	wrqu->retry.fixed = 0;	/* no auto select */
2657 	wrqu->retry.disabled = 1;
2658 
2659 	return 0;
2660 
2661 }
2662 
2663 #if 0
2664 	#define IW_ENCODE_INDEX		0x00FF	/* Token index (if needed) */
2665 	#define IW_ENCODE_FLAGS		0xFF00	/* Flags defined below */
2666 	#define IW_ENCODE_MODE		0xF000	/* Modes defined below */
2667 	#define IW_ENCODE_DISABLED	0x8000	/* Encoding disabled */
2668 	#define IW_ENCODE_ENABLED	0x0000	/* Encoding enabled */
2669 	#define IW_ENCODE_RESTRICTED	0x4000	/* Refuse non-encoded packets */
2670 	#define IW_ENCODE_OPEN		0x2000	/* Accept non-encoded packets */
2671 	#define IW_ENCODE_NOKEY		0x0800  /* Key is write only, so not present */
2672 	#define IW_ENCODE_TEMP		0x0400  /* Temporary key */
2673 	/*
2674 	iwconfig wlan0 key on->flags = 0x6001->maybe it means auto
2675 	iwconfig wlan0 key off->flags = 0x8800
2676 	iwconfig wlan0 key open->flags = 0x2800
2677 	iwconfig wlan0 key open 1234567890->flags = 0x2000
2678 	iwconfig wlan0 key restricted->flags = 0x4800
2679 	iwconfig wlan0 key open [3] 1234567890->flags = 0x2003
2680 	iwconfig wlan0 key restricted [2] 1234567890->flags = 0x4002
2681 	iwconfig wlan0 key open [3] -> flags = 0x2803
2682 	iwconfig wlan0 key restricted [2] -> flags = 0x4802
2683 	*/
2684 #endif
2685 
2686 static int rtw_wx_set_enc(struct net_device *dev,
2687 			  struct iw_request_info *info,
2688 			  union iwreq_data *wrqu, char *keybuf)
2689 {
2690 	u32 key, ret = 0;
2691 	u32 keyindex_provided;
2692 	NDIS_802_11_WEP	 wep;
2693 	NDIS_802_11_AUTHENTICATION_MODE authmode;
2694 
2695 	struct iw_point *erq = &(wrqu->encoding);
2696 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2697 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2698 	RTW_INFO("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
2699 
2700 	_rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
2701 
2702 	key = erq->flags & IW_ENCODE_INDEX;
2703 
2704 
2705 	if (erq->flags & IW_ENCODE_DISABLED) {
2706 		RTW_INFO("EncryptionDisabled\n");
2707 		padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2708 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2709 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2710 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2711 		authmode = Ndis802_11AuthModeOpen;
2712 		padapter->securitypriv.ndisauthtype = authmode;
2713 
2714 		goto exit;
2715 	}
2716 
2717 	if (key) {
2718 		if (key > WEP_KEYS)
2719 			return -EINVAL;
2720 		key--;
2721 		keyindex_provided = 1;
2722 	} else {
2723 		keyindex_provided = 0;
2724 		key = padapter->securitypriv.dot11PrivacyKeyIndex;
2725 		RTW_INFO("rtw_wx_set_enc, key=%d\n", key);
2726 	}
2727 
2728 	/* set authentication mode	 */
2729 	if (erq->flags & IW_ENCODE_OPEN) {
2730 		RTW_INFO("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
2731 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
2732 
2733 #ifdef CONFIG_PLATFORM_MT53XX
2734 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2735 #else
2736 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2737 #endif
2738 
2739 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2740 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2741 		authmode = Ndis802_11AuthModeOpen;
2742 		padapter->securitypriv.ndisauthtype = authmode;
2743 	} else if (erq->flags & IW_ENCODE_RESTRICTED) {
2744 		RTW_INFO("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
2745 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2746 
2747 #ifdef CONFIG_PLATFORM_MT53XX
2748 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2749 #else
2750 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2751 #endif
2752 
2753 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2754 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
2755 		authmode = Ndis802_11AuthModeShared;
2756 		padapter->securitypriv.ndisauthtype = authmode;
2757 	} else {
2758 		RTW_INFO("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
2759 
2760 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
2761 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2762 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2763 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2764 		authmode = Ndis802_11AuthModeOpen;
2765 		padapter->securitypriv.ndisauthtype = authmode;
2766 	}
2767 
2768 	wep.KeyIndex = key;
2769 	if (erq->length > 0) {
2770 		wep.KeyLength = erq->length <= 5 ? 5 : 13;
2771 
2772 		wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2773 	} else {
2774 		wep.KeyLength = 0 ;
2775 
2776 		if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length==0). */
2777 			padapter->securitypriv.dot11PrivacyKeyIndex = key;
2778 
2779 			RTW_INFO("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
2780 
2781 			switch (padapter->securitypriv.dot11DefKeylen[key]) {
2782 			case 5:
2783 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2784 				break;
2785 			case 13:
2786 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2787 				break;
2788 			default:
2789 				padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2790 				break;
2791 			}
2792 
2793 			goto exit;
2794 
2795 		}
2796 
2797 	}
2798 
2799 	wep.KeyIndex |= 0x80000000;
2800 
2801 	_rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
2802 
2803 	if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
2804 		if (rf_on == pwrpriv->rf_pwrstate)
2805 			ret = -EOPNOTSUPP;
2806 		goto exit;
2807 	}
2808 
2809 exit:
2810 
2811 
2812 	return ret;
2813 
2814 }
2815 
2816 static int rtw_wx_get_enc(struct net_device *dev,
2817 			  struct iw_request_info *info,
2818 			  union iwreq_data *wrqu, char *keybuf)
2819 {
2820 	uint key, ret = 0;
2821 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2822 	struct iw_point *erq = &(wrqu->encoding);
2823 	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
2824 
2825 
2826 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE) {
2827 		if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) {
2828 			erq->length = 0;
2829 			erq->flags |= IW_ENCODE_DISABLED;
2830 			return 0;
2831 		}
2832 	}
2833 
2834 
2835 	key = erq->flags & IW_ENCODE_INDEX;
2836 
2837 	if (key) {
2838 		if (key > WEP_KEYS)
2839 			return -EINVAL;
2840 		key--;
2841 	} else
2842 		key = padapter->securitypriv.dot11PrivacyKeyIndex;
2843 
2844 	erq->flags = key + 1;
2845 
2846 	/* if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */
2847 	/* { */
2848 	/* erq->flags |= IW_ENCODE_OPEN; */
2849 	/* }	  */
2850 
2851 	switch (padapter->securitypriv.ndisencryptstatus) {
2852 	case Ndis802_11EncryptionNotSupported:
2853 	case Ndis802_11EncryptionDisabled:
2854 
2855 		erq->length = 0;
2856 		erq->flags |= IW_ENCODE_DISABLED;
2857 
2858 		break;
2859 
2860 	case Ndis802_11Encryption1Enabled:
2861 
2862 		erq->length = padapter->securitypriv.dot11DefKeylen[key];
2863 
2864 		if (erq->length) {
2865 			_rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
2866 
2867 			erq->flags |= IW_ENCODE_ENABLED;
2868 
2869 			if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2870 				erq->flags |= IW_ENCODE_OPEN;
2871 			else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
2872 				erq->flags |= IW_ENCODE_RESTRICTED;
2873 		} else {
2874 			erq->length = 0;
2875 			erq->flags |= IW_ENCODE_DISABLED;
2876 		}
2877 
2878 		break;
2879 
2880 	case Ndis802_11Encryption2Enabled:
2881 	case Ndis802_11Encryption3Enabled:
2882 
2883 		erq->length = 16;
2884 		erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
2885 
2886 		break;
2887 
2888 	default:
2889 		erq->length = 0;
2890 		erq->flags |= IW_ENCODE_DISABLED;
2891 
2892 		break;
2893 
2894 	}
2895 
2896 
2897 	return ret;
2898 
2899 }
2900 
2901 static int rtw_wx_get_power(struct net_device *dev,
2902 			    struct iw_request_info *info,
2903 			    union iwreq_data *wrqu, char *extra)
2904 {
2905 	/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
2906 
2907 	wrqu->power.value = 0;
2908 	wrqu->power.fixed = 0;	/* no auto select */
2909 	wrqu->power.disabled = 1;
2910 
2911 	return 0;
2912 
2913 }
2914 
2915 static int rtw_wx_set_gen_ie(struct net_device *dev,
2916 			     struct iw_request_info *info,
2917 			     union iwreq_data *wrqu, char *extra)
2918 {
2919 	int ret;
2920 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2921 
2922 	ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
2923 
2924 	return ret;
2925 }
2926 
2927 static int rtw_wx_set_auth(struct net_device *dev,
2928 			   struct iw_request_info *info,
2929 			   union iwreq_data *wrqu, char *extra)
2930 {
2931 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2932 	struct iw_param *param = (struct iw_param *)&(wrqu->param);
2933 #ifdef CONFIG_WAPI_SUPPORT
2934 #ifndef CONFIG_IOCTL_CFG80211
2935 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
2936 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2937 	struct security_priv *psecuritypriv = &padapter->securitypriv;
2938 	u32 value = param->value;
2939 #endif
2940 #endif
2941 	int ret = 0;
2942 
2943 	switch (param->flags & IW_AUTH_INDEX) {
2944 
2945 	case IW_AUTH_WPA_VERSION:
2946 #ifdef CONFIG_WAPI_SUPPORT
2947 #ifndef CONFIG_IOCTL_CFG80211
2948 		padapter->wapiInfo.bWapiEnable = false;
2949 		if (value == IW_AUTH_WAPI_VERSION_1) {
2950 			padapter->wapiInfo.bWapiEnable = true;
2951 			psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
2952 			psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
2953 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2954 			pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
2955 			padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
2956 			padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
2957 		}
2958 #endif
2959 #endif
2960 		break;
2961 	case IW_AUTH_CIPHER_PAIRWISE:
2962 
2963 		break;
2964 	case IW_AUTH_CIPHER_GROUP:
2965 
2966 		break;
2967 	case IW_AUTH_KEY_MGMT:
2968 #ifdef CONFIG_WAPI_SUPPORT
2969 #ifndef CONFIG_IOCTL_CFG80211
2970 		RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case\n");
2971 		if (value == IW_AUTH_KEY_MGMT_WAPI_PSK)
2972 			padapter->wapiInfo.bWapiPSK = true;
2973 		else
2974 			padapter->wapiInfo.bWapiPSK = false;
2975 		RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d\n", padapter->wapiInfo.bWapiPSK);
2976 #endif
2977 #endif
2978 		/*
2979 		 *  ??? does not use these parameters
2980 		 */
2981 		break;
2982 
2983 	case IW_AUTH_TKIP_COUNTERMEASURES: {
2984 		if (param->value) {
2985 			/* wpa_supplicant is enabling the tkip countermeasure. */
2986 			padapter->securitypriv.btkip_countermeasure = _TRUE;
2987 		} else {
2988 			/* wpa_supplicant is disabling the tkip countermeasure. */
2989 			padapter->securitypriv.btkip_countermeasure = _FALSE;
2990 		}
2991 		break;
2992 	}
2993 	case IW_AUTH_DROP_UNENCRYPTED: {
2994 		/* HACK:
2995 		 *
2996 		 * wpa_supplicant calls set_wpa_enabled when the driver
2997 		 * is loaded and unloaded, regardless of if WPA is being
2998 		 * used.  No other calls are made which can be used to
2999 		 * determine if encryption will be used or not prior to
3000 		 * association being expected.  If encryption is not being
3001 		 * used, drop_unencrypted is set to false, else true -- we
3002 		 * can use this to determine if the CAP_PRIVACY_ON bit should
3003 		 * be set.
3004 		 */
3005 
3006 		if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) {
3007 			break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
3008 			/* then it needn't reset it; */
3009 		}
3010 
3011 		if (param->value) {
3012 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3013 			padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3014 			padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3015 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3016 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
3017 		}
3018 
3019 		break;
3020 	}
3021 
3022 	case IW_AUTH_80211_AUTH_ALG:
3023 
3024 #if defined(CONFIG_RTW_ANDROID) || 1
3025 		/*
3026 		 *  It's the starting point of a link layer connection using wpa_supplicant
3027 		*/
3028 		if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
3029 			LeaveAllPowerSaveMode(padapter);
3030 			rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK);
3031 			RTW_INFO("%s...call rtw_indicate_disconnect\n ", __FUNCTION__);
3032 			rtw_indicate_disconnect(padapter, 0, _FALSE);
3033 			rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK);
3034 		}
3035 #endif
3036 
3037 
3038 		ret = wpa_set_auth_algs(dev, (u32)param->value);
3039 
3040 		break;
3041 
3042 	case IW_AUTH_WPA_ENABLED:
3043 
3044 		/* if(param->value) */
3045 		/* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; */ /* 802.1x */
3046 		/* else */
3047 		/* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; */ /* open system */
3048 
3049 		/* _disassociate(priv); */
3050 
3051 		break;
3052 
3053 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3054 		/* ieee->ieee802_1x = param->value; */
3055 		break;
3056 
3057 	case IW_AUTH_PRIVACY_INVOKED:
3058 		/* ieee->privacy_invoked = param->value; */
3059 		break;
3060 
3061 #ifdef CONFIG_WAPI_SUPPORT
3062 #ifndef CONFIG_IOCTL_CFG80211
3063 	case IW_AUTH_WAPI_ENABLED:
3064 		break;
3065 #endif
3066 #endif
3067 
3068 	default:
3069 		return -EOPNOTSUPP;
3070 
3071 	}
3072 
3073 	return ret;
3074 
3075 }
3076 
3077 static int rtw_wx_set_enc_ext(struct net_device *dev,
3078 			      struct iw_request_info *info,
3079 			      union iwreq_data *wrqu, char *extra)
3080 {
3081 	char *alg_name;
3082 	u32 param_len;
3083 	struct ieee_param *param = NULL;
3084 	struct iw_point *pencoding = &wrqu->encoding;
3085 	struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3086 	int ret = 0;
3087 
3088 	param_len = sizeof(struct ieee_param) + pext->key_len;
3089 	param = (struct ieee_param *)rtw_malloc(param_len);
3090 	if (param == NULL)
3091 		return -1;
3092 
3093 	_rtw_memset(param, 0, param_len);
3094 
3095 	param->cmd = IEEE_CMD_SET_ENCRYPTION;
3096 	_rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3097 
3098 
3099 	switch (pext->alg) {
3100 	case IW_ENCODE_ALG_NONE:
3101 		/* todo: remove key */
3102 		/* remove = 1;	 */
3103 		alg_name = "none";
3104 		break;
3105 	case IW_ENCODE_ALG_WEP:
3106 		alg_name = "WEP";
3107 		break;
3108 	case IW_ENCODE_ALG_TKIP:
3109 		alg_name = "TKIP";
3110 		break;
3111 	case IW_ENCODE_ALG_CCMP:
3112 		alg_name = "CCMP";
3113 		break;
3114 #ifdef CONFIG_IEEE80211W
3115 	case IW_ENCODE_ALG_AES_CMAC:
3116 		alg_name = "BIP";
3117 		break;
3118 #endif /* CONFIG_IEEE80211W */
3119 #ifdef CONFIG_WAPI_SUPPORT
3120 #ifndef CONFIG_IOCTL_CFG80211
3121 	case IW_ENCODE_ALG_SM4:
3122 		alg_name = "SMS4";
3123 		_rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3124 		RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
3125 		break;
3126 #endif
3127 #endif
3128 	default:
3129 		ret = -1;
3130 		goto exit;
3131 	}
3132 
3133 	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3134 
3135 	if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3136 		param->u.crypt.set_tx = 1;
3137 
3138 	/* cliW: WEP does not have group key
3139 	 * just not checking GROUP key setting
3140 	 */
3141 	if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3142 	    ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3143 #ifdef CONFIG_IEEE80211W
3144 	     || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3145 #endif /* CONFIG_IEEE80211W */
3146 	    ))
3147 		param->u.crypt.set_tx = 0;
3148 
3149 	param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1 ;
3150 
3151 	if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3152 #ifdef CONFIG_WAPI_SUPPORT
3153 #ifndef CONFIG_IOCTL_CFG80211
3154 		if (pext->alg == IW_ENCODE_ALG_SM4)
3155 			_rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3156 		else
3157 #endif /* CONFIG_IOCTL_CFG80211 */
3158 #endif /* CONFIG_WAPI_SUPPORT */
3159 			_rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3160 	}
3161 
3162 	if (pext->key_len) {
3163 		param->u.crypt.key_len = pext->key_len;
3164 		/* _rtw_memcpy(param + 1, pext + 1, pext->key_len); */
3165 		_rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3166 	}
3167 
3168 	if (pencoding->flags & IW_ENCODE_DISABLED) {
3169 		/* todo: remove key */
3170 		/* remove = 1; */
3171 	}
3172 
3173 	ret =  wpa_set_encryption(dev, param, param_len);
3174 
3175 exit:
3176 	if (param)
3177 		rtw_mfree((u8 *)param, param_len);
3178 
3179 	return ret;
3180 }
3181 
3182 
3183 static int rtw_wx_get_nick(struct net_device *dev,
3184 			   struct iw_request_info *info,
3185 			   union iwreq_data *wrqu, char *extra)
3186 {
3187 	/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3188 	/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3189 	/* struct security_priv *psecuritypriv = &padapter->securitypriv; */
3190 
3191 	if (extra) {
3192 		wrqu->data.length = 14;
3193 		wrqu->data.flags = 1;
3194 		_rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
3195 	}
3196 
3197 	/* rtw_signal_process(pid, SIGUSR1); */ /* for test */
3198 
3199 	/* dump debug info here	 */
3200 #if 0
3201 	u32 dot11AuthAlgrthm;		/*  802.11 auth, could be open, shared, and 8021x */
3202 	u32 dot11PrivacyAlgrthm;	/*  This specify the privacy for shared auth. algorithm. */
3203 	u32 dot118021XGrpPrivacy;	/*  This specify the privacy algthm. used for Grp key */
3204 	u32 ndisauthtype;
3205 	u32 ndisencryptstatus;
3206 #endif
3207 
3208 	/* RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",  */
3209 	/*		psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, */
3210 	/*		psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); */
3211 
3212 	/* RTW_INFO("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); */
3213 	/* RTW_INFO("auth_type=0x%x\n", psecuritypriv->ndisauthtype); */
3214 	/* RTW_INFO("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); */
3215 
3216 #if 0
3217 	RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3218 	RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3219 	RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3220 	RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3221 	RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3222 
3223 	RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3224 
3225 
3226 	RTW_INFO("\n");
3227 
3228 	RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3229 	RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3230 
3231 	RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3232 
3233 	RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3234 
3235 	RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3236 	RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3237 
3238 	RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3239 	RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3240 	RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3241 	RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3242 #endif
3243 
3244 	return 0;
3245 
3246 }
3247 #endif
3248 
3249 static int rtw_wx_read32(struct net_device *dev,
3250 			 struct iw_request_info *info,
3251 			 union iwreq_data *wrqu, char *extra)
3252 {
3253 	PADAPTER padapter;
3254 	struct iw_point *p;
3255 	u16 len;
3256 	u32 addr;
3257 	u32 data32;
3258 	u32 bytes;
3259 	u8 *ptmp;
3260 	int ret;
3261 
3262 
3263 	ret = 0;
3264 	padapter = (PADAPTER)rtw_netdev_priv(dev);
3265 	p = &wrqu->data;
3266 	len = p->length;
3267 	if (0 == len)
3268 		return -EINVAL;
3269 
3270 	ptmp = (u8 *)rtw_malloc(len);
3271 	if (NULL == ptmp)
3272 		return -ENOMEM;
3273 
3274 	if (copy_from_user(ptmp, p->pointer, len)) {
3275 		ret = -EFAULT;
3276 		goto exit;
3277 	}
3278 
3279 	bytes = 0;
3280 	addr = 0;
3281 	sscanf(ptmp, "%d,%x", &bytes, &addr);
3282 
3283 	switch (bytes) {
3284 	case 1:
3285 		data32 = rtw_read8(padapter, addr);
3286 		sprintf(extra, "0x%02X", data32);
3287 		break;
3288 	case 2:
3289 		data32 = rtw_read16(padapter, addr);
3290 		sprintf(extra, "0x%04X", data32);
3291 		break;
3292 	case 4:
3293 		data32 = rtw_read32(padapter, addr);
3294 		sprintf(extra, "0x%08X", data32);
3295 		break;
3296 
3297 	#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)
3298 	case 11:
3299 		data32 = rtw_sd_iread8(padapter, addr);
3300 		sprintf(extra, "0x%02X", data32);
3301 		break;
3302 	case 12:
3303 		data32 = rtw_sd_iread16(padapter, addr);
3304 		sprintf(extra, "0x%04X", data32);
3305 		break;
3306 	case 14:
3307 		data32 = rtw_sd_iread32(padapter, addr);
3308 		sprintf(extra, "0x%08X", data32);
3309 		break;
3310 	#endif
3311 	default:
3312 		RTW_INFO("%s: usage> read [bytes],[address(hex)]\n", __func__);
3313 		ret = -EINVAL;
3314 		goto exit;
3315 	}
3316 	RTW_INFO("%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3317 
3318 exit:
3319 	rtw_mfree(ptmp, len);
3320 
3321 	return 0;
3322 }
3323 
3324 static int rtw_wx_write32(struct net_device *dev,
3325 			  struct iw_request_info *info,
3326 			  union iwreq_data *wrqu, char *extra)
3327 {
3328 	PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3329 
3330 	u32 addr;
3331 	u32 data32;
3332 	u32 bytes;
3333 
3334 
3335 	bytes = 0;
3336 	addr = 0;
3337 	data32 = 0;
3338 	sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3339 
3340 	switch (bytes) {
3341 	case 1:
3342 		rtw_write8(padapter, addr, (u8)data32);
3343 		RTW_INFO("%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3344 		break;
3345 	case 2:
3346 		rtw_write16(padapter, addr, (u16)data32);
3347 		RTW_INFO("%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3348 		break;
3349 	case 4:
3350 		rtw_write32(padapter, addr, data32);
3351 		RTW_INFO("%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3352 		break;
3353 	default:
3354 		RTW_INFO("%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3355 		return -EINVAL;
3356 	}
3357 
3358 	return 0;
3359 }
3360 
3361 static int rtw_wx_read_rf(struct net_device *dev,
3362 			  struct iw_request_info *info,
3363 			  union iwreq_data *wrqu, char *extra)
3364 {
3365 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3366 	u32 path, addr, data32;
3367 
3368 
3369 	path = *(u32 *)extra;
3370 	addr = *((u32 *)extra + 1);
3371 	data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3372 	/*	RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3373 	/*
3374 	 * IMPORTANT!!
3375 	 * Only when wireless private ioctl is at odd order,
3376 	 * "extra" would be copied to user space.
3377 	 */
3378 	sprintf(extra, "0x%05x", data32);
3379 
3380 	return 0;
3381 }
3382 
3383 static int rtw_wx_write_rf(struct net_device *dev,
3384 			   struct iw_request_info *info,
3385 			   union iwreq_data *wrqu, char *extra)
3386 {
3387 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3388 	u32 path, addr, data32;
3389 
3390 
3391 	path = *(u32 *)extra;
3392 	addr = *((u32 *)extra + 1);
3393 	data32 = *((u32 *)extra + 2);
3394 	/*	RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3395 	rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3396 
3397 	return 0;
3398 }
3399 
3400 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3401 			    union iwreq_data *wrqu, char *b)
3402 {
3403 	return -1;
3404 }
3405 
3406 #ifdef CONFIG_RTW_80211K
3407 extern void rm_dbg_cmd(_adapter *padapter, char *s);
3408 static int rtw_wx_priv_rrm(struct net_device *dev, struct iw_request_info *a,
3409 			    union iwreq_data *wrqu, char *b)
3410 {
3411 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3412 	u32 path, addr, data32;
3413 
3414 
3415 	rm_dbg_cmd(padapter, b);
3416 	wrqu->data.length = strlen(b);
3417 
3418 	return 0;
3419 }
3420 #endif
3421 
3422 #ifdef CONFIG_IOCTL_WEXT
3423 static int dummy(struct net_device *dev, struct iw_request_info *a,
3424 		 union iwreq_data *wrqu, char *b)
3425 {
3426 	/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);	 */
3427 	/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3428 
3429 	/* RTW_INFO("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); */
3430 
3431 	return -1;
3432 
3433 }
3434 #endif
3435 
3436 static int rtw_wx_set_channel_plan(struct net_device *dev,
3437 				   struct iw_request_info *info,
3438 				   union iwreq_data *wrqu, char *extra)
3439 {
3440 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3441 	u16 channel_plan_req = (u16)(*((int *)wrqu));
3442 
3443 	rtw_chplan_ioctl_input_mapping(&channel_plan_req, NULL);
3444 
3445 	if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req, RTW_CHPLAN_6G_UNSPECIFIED, RTW_REGD_SET_BY_USER))
3446 		return -EPERM;
3447 
3448 	return 0;
3449 }
3450 
3451 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3452 				       struct iw_request_info *a,
3453 				       union iwreq_data *wrqu, char *b)
3454 {
3455 #ifdef CONFIG_PLATFORM_MT53XX
3456 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3457 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3458 
3459 #endif
3460 	return 0;
3461 }
3462 
3463 static int rtw_wx_get_sensitivity(struct net_device *dev,
3464 				  struct iw_request_info *info,
3465 				  union iwreq_data *wrqu, char *buf)
3466 {
3467 #ifdef CONFIG_PLATFORM_MT53XX
3468 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3469 
3470 	/*	Modified by Albert 20110914 */
3471 	/*	This is in dbm format for MTK platform. */
3472 	wrqu->qual.level = padapter->recvpriv.rssi;
3473 	RTW_INFO(" level = %u\n",  wrqu->qual.level);
3474 #endif
3475 	return 0;
3476 }
3477 
3478 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3479 				 struct iw_request_info *info,
3480 				 union iwreq_data *wrqu, char *extra)
3481 {
3482 #ifdef CONFIG_PLATFORM_MT53XX
3483 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3484 
3485 	return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3486 #else
3487 	return 0;
3488 #endif
3489 }
3490 
3491 #ifdef MP_IOCTL_HDL
3492 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
3493 {
3494 	pRW_Reg	RegRWStruct;
3495 	struct rf_reg_param *prfreg;
3496 	u8 path;
3497 	u8 offset;
3498 	u32 value;
3499 
3500 	RTW_INFO("%s\n", __FUNCTION__);
3501 
3502 	switch (id) {
3503 	case GEN_MP_IOCTL_SUBCODE(MP_START):
3504 		RTW_INFO("871x_driver is only for normal mode, can't enter mp mode\n");
3505 		break;
3506 	case GEN_MP_IOCTL_SUBCODE(READ_REG):
3507 		RegRWStruct = (pRW_Reg)pdata;
3508 		switch (RegRWStruct->width) {
3509 		case 1:
3510 			RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
3511 			break;
3512 		case 2:
3513 			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
3514 			break;
3515 		case 4:
3516 			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
3517 			break;
3518 		default:
3519 			break;
3520 		}
3521 
3522 		break;
3523 	case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
3524 		RegRWStruct = (pRW_Reg)pdata;
3525 		switch (RegRWStruct->width) {
3526 		case 1:
3527 			rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
3528 			break;
3529 		case 2:
3530 			rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
3531 			break;
3532 		case 4:
3533 			rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
3534 			break;
3535 		default:
3536 			break;
3537 		}
3538 
3539 		break;
3540 	case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
3541 
3542 		prfreg = (struct rf_reg_param *)pdata;
3543 
3544 		path = (u8)prfreg->path;
3545 		offset = (u8)prfreg->offset;
3546 
3547 		value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
3548 
3549 		prfreg->value = value;
3550 
3551 		break;
3552 	case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
3553 
3554 		prfreg = (struct rf_reg_param *)pdata;
3555 
3556 		path = (u8)prfreg->path;
3557 		offset = (u8)prfreg->offset;
3558 		value = prfreg->value;
3559 
3560 		rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
3561 
3562 		break;
3563 	case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
3564 		RTW_INFO("==> trigger gpio 0\n");
3565 		rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
3566 		break;
3567 #ifdef CONFIG_BT_COEXIST
3568 	case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):
3569 		RTW_INFO("==> set dm_bt_coexist:%x\n", *(u8 *)pdata);
3570 		rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
3571 		break;
3572 	case GEN_MP_IOCTL_SUBCODE(DEL_BA):
3573 		RTW_INFO("==> delete ba:%x\n", *(u8 *)pdata);
3574 		rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
3575 		break;
3576 #endif
3577 #ifdef DBG_CONFIG_ERROR_DETECT
3578 	case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
3579 		*pdata = rtw_hal_sreset_get_wifi_status(padapter);
3580 		break;
3581 #endif
3582 
3583 	default:
3584 		break;
3585 	}
3586 
3587 }
3588 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
3589 			    union iwreq_data *wrqu, char *extra)
3590 {
3591 	int ret = 0;
3592 	u32 BytesRead, BytesWritten, BytesNeeded;
3593 	struct oid_par_priv	oid_par;
3594 	struct mp_ioctl_handler	*phandler;
3595 	struct mp_ioctl_param	*poidparam;
3596 	uint status = 0;
3597 	u16 len;
3598 	u8 *pparmbuf = NULL, bset;
3599 	PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3600 	struct iw_point *p = &wrqu->data;
3601 
3602 	/* RTW_INFO("+rtw_mp_ioctl_hdl\n"); */
3603 
3604 	/* mutex_lock(&ioctl_mutex); */
3605 
3606 	if ((!p->length) || (!p->pointer)) {
3607 		ret = -EINVAL;
3608 		goto _rtw_mp_ioctl_hdl_exit;
3609 	}
3610 
3611 	pparmbuf = NULL;
3612 	bset = (u8)(p->flags & 0xFFFF);
3613 	len = p->length;
3614 	pparmbuf = (u8 *)rtw_malloc(len);
3615 	if (pparmbuf == NULL) {
3616 		ret = -ENOMEM;
3617 		goto _rtw_mp_ioctl_hdl_exit;
3618 	}
3619 
3620 	if (copy_from_user(pparmbuf, p->pointer, len)) {
3621 		ret = -EFAULT;
3622 		goto _rtw_mp_ioctl_hdl_exit;
3623 	}
3624 
3625 	poidparam = (struct mp_ioctl_param *)pparmbuf;
3626 
3627 	if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
3628 		ret = -EINVAL;
3629 		goto _rtw_mp_ioctl_hdl_exit;
3630 	}
3631 
3632 	/* RTW_INFO("%s: %d\n", __func__, poidparam->subcode); */
3633 #ifdef CONFIG_MP_INCLUDED
3634 	if (padapter->registrypriv.mp_mode == 1) {
3635 		phandler = mp_ioctl_hdl + poidparam->subcode;
3636 
3637 		if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {
3638 			ret = -EINVAL;
3639 			goto _rtw_mp_ioctl_hdl_exit;
3640 		}
3641 
3642 		if (phandler->handler) {
3643 			oid_par.adapter_context = padapter;
3644 			oid_par.oid = phandler->oid;
3645 			oid_par.information_buf = poidparam->data;
3646 			oid_par.information_buf_len = poidparam->len;
3647 			oid_par.dbg = 0;
3648 
3649 			BytesWritten = 0;
3650 			BytesNeeded = 0;
3651 
3652 			if (bset) {
3653 				oid_par.bytes_rw = &BytesRead;
3654 				oid_par.bytes_needed = &BytesNeeded;
3655 				oid_par.type_of_oid = SET_OID;
3656 			} else {
3657 				oid_par.bytes_rw = &BytesWritten;
3658 				oid_par.bytes_needed = &BytesNeeded;
3659 				oid_par.type_of_oid = QUERY_OID;
3660 			}
3661 
3662 			status = phandler->handler(&oid_par);
3663 
3664 			/* todo:check status, BytesNeeded, etc. */
3665 		} else {
3666 			RTW_INFO("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",
3667 				poidparam->subcode, phandler->oid, phandler->handler);
3668 			ret = -EFAULT;
3669 			goto _rtw_mp_ioctl_hdl_exit;
3670 		}
3671 	} else
3672 #endif
3673 	{
3674 		rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
3675 	}
3676 
3677 	if (bset == 0x00) {/* query info */
3678 		if (copy_to_user(p->pointer, pparmbuf, len))
3679 			ret = -EFAULT;
3680 	}
3681 
3682 	if (status) {
3683 		ret = -EFAULT;
3684 		goto _rtw_mp_ioctl_hdl_exit;
3685 	}
3686 
3687 _rtw_mp_ioctl_hdl_exit:
3688 
3689 	if (pparmbuf)
3690 		rtw_mfree(pparmbuf, len);
3691 
3692 	/* mutex_unlock(&ioctl_mutex); */
3693 
3694 	return ret;
3695 }
3696 #endif /*MP_IOCTL_HDL*/
3697 static int rtw_get_ap_info(struct net_device *dev,
3698 			   struct iw_request_info *info,
3699 			   union iwreq_data *wrqu, char *extra)
3700 {
3701 	int ret = 0;
3702 	u32 cnt = 0, wpa_ielen;
3703 	_irqL	irqL;
3704 	_list	*plist, *phead;
3705 	unsigned char *pbuf;
3706 	u8 bssid[ETH_ALEN];
3707 	char data[32];
3708 	struct wlan_network *pnetwork = NULL;
3709 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3710 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3711 	_queue *queue = &(pmlmepriv->scanned_queue);
3712 	struct iw_point *pdata = &wrqu->data;
3713 
3714 	RTW_INFO("+rtw_get_aplist_info\n");
3715 
3716 	if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
3717 		ret = -EINVAL;
3718 		goto exit;
3719 	}
3720 
3721 	while ((check_fwstate(pmlmepriv, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING))) == _TRUE) {
3722 		rtw_msleep_os(30);
3723 		cnt++;
3724 		if (cnt > 100)
3725 			break;
3726 	}
3727 
3728 
3729 	/* pdata->length = 0; */ /* ?	 */
3730 	pdata->flags = 0;
3731 	if (pdata->length >= 32) {
3732 		if (copy_from_user(data, pdata->pointer, 32)) {
3733 			ret = -EINVAL;
3734 			goto exit;
3735 		}
3736 	} else {
3737 		ret = -EINVAL;
3738 		goto exit;
3739 	}
3740 
3741 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3742 
3743 	phead = get_list_head(queue);
3744 	plist = get_next(phead);
3745 
3746 	while (1) {
3747 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
3748 			break;
3749 
3750 
3751 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
3752 
3753 		if (hwaddr_aton_i(data, bssid)) {
3754 			RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data);
3755 			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3756 			return -EINVAL;
3757 		}
3758 
3759 
3760 		if (_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) { /* BSSID match, then check if supporting wpa/wpa2 */
3761 			RTW_INFO("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
3762 
3763 			pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
3764 			if (pbuf && (wpa_ielen > 0)) {
3765 				pdata->flags = 1;
3766 				break;
3767 			}
3768 
3769 			pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
3770 			if (pbuf && (wpa_ielen > 0)) {
3771 				pdata->flags = 2;
3772 				break;
3773 			}
3774 
3775 		}
3776 
3777 		plist = get_next(plist);
3778 
3779 	}
3780 
3781 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3782 
3783 	if (pdata->length >= 34) {
3784 		if (copy_to_user((u8 *)pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
3785 			ret = -EINVAL;
3786 			goto exit;
3787 		}
3788 	}
3789 
3790 exit:
3791 
3792 	return ret;
3793 
3794 }
3795 
3796 static int rtw_set_pid(struct net_device *dev,
3797 		       struct iw_request_info *info,
3798 		       union iwreq_data *wrqu, char *extra)
3799 {
3800 
3801 	int ret = 0;
3802 	_adapter *padapter = rtw_netdev_priv(dev);
3803 	int *pdata = (int *)wrqu;
3804 	int selector;
3805 
3806 	if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
3807 		ret = -EINVAL;
3808 		goto exit;
3809 	}
3810 
3811 	selector = *pdata;
3812 	if (selector < 3 && selector >= 0) {
3813 		padapter->pid[selector] = *(pdata + 1);
3814 #ifdef CONFIG_GLOBAL_UI_PID
3815 		ui_pid[selector] = *(pdata + 1);
3816 #endif
3817 		RTW_INFO("%s set pid[%d]=%d\n", __FUNCTION__, selector , padapter->pid[selector]);
3818 	} else
3819 		RTW_INFO("%s selector %d error\n", __FUNCTION__, selector);
3820 
3821 exit:
3822 
3823 	return ret;
3824 
3825 }
3826 
3827 static int rtw_wps_start(struct net_device *dev,
3828 			 struct iw_request_info *info,
3829 			 union iwreq_data *wrqu, char *extra)
3830 {
3831 
3832 	int ret = 0;
3833 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3834 	struct iw_point *pdata = &wrqu->data;
3835 	u32   u32wps_start = 0;
3836 	unsigned int uintRet = 0;
3837 
3838 	if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) {
3839 		ret = -EINVAL;
3840 		goto exit;
3841 	}
3842 
3843 	uintRet = copy_from_user((void *) &u32wps_start, pdata->pointer, 4);
3844 	if (u32wps_start == 0)
3845 		u32wps_start = *extra;
3846 
3847 	RTW_INFO("[%s] wps_start = %d\n", __FUNCTION__, u32wps_start);
3848 
3849 	if (u32wps_start == 1)   /* WPS Start */
3850 		rtw_led_control(padapter, LED_CTL_START_WPS);
3851 	else if (u32wps_start == 2)   /* WPS Stop because of wps success */
3852 		rtw_led_control(padapter, LED_CTL_STOP_WPS);
3853 	else if (u32wps_start == 3)   /* WPS Stop because of wps fail */
3854 		rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
3855 
3856 exit:
3857 
3858 	return ret;
3859 
3860 }
3861 
3862 #ifdef CONFIG_P2P
3863 static int rtw_wext_p2p_enable(struct net_device *dev,
3864 			       struct iw_request_info *info,
3865 			       union iwreq_data *wrqu, char *extra)
3866 {
3867 
3868 	int ret = 0;
3869 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3870 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3871 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3872 	enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
3873 #ifdef CONFIG_CONCURRENT_MODE
3874 	struct roch_info *prochinfo = &padapter->rochinfo;
3875 #endif
3876 
3877 	if (*extra == '0')
3878 		init_role = P2P_ROLE_DISABLE;
3879 	else if (*extra == '1')
3880 		init_role = P2P_ROLE_DEVICE;
3881 	else if (*extra == '2')
3882 		init_role = P2P_ROLE_CLIENT;
3883 	else if (*extra == '3')
3884 		init_role = P2P_ROLE_GO;
3885 
3886 	if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
3887 		ret = -EFAULT;
3888 		goto exit;
3889 	}
3890 
3891 	/* set channel/bandwidth */
3892 	if (init_role != P2P_ROLE_DISABLE) {
3893 		u8 channel, ch_offset;
3894 		u16 bwmode;
3895 
3896 		if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
3897 			/*	Stay at the listen state and wait for discovery. */
3898 			channel = pwdinfo->listen_channel;
3899 			pwdinfo->operating_channel = pwdinfo->listen_channel;
3900 			ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3901 			bwmode = CHANNEL_WIDTH_20;
3902 		}
3903 #ifdef CONFIG_CONCURRENT_MODE
3904 		else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
3905 
3906 			_set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_interval);
3907 
3908 			channel = rtw_mi_get_union_chan(padapter);
3909 			ch_offset = rtw_mi_get_union_offset(padapter);
3910 			bwmode = rtw_mi_get_union_bw(padapter);
3911 
3912 			pwdinfo->operating_channel = channel;
3913 		}
3914 #endif
3915 		else {
3916 			pwdinfo->operating_channel = pmlmeext->cur_channel;
3917 
3918 			channel = pwdinfo->operating_channel;
3919 			ch_offset = pmlmeext->cur_ch_offset;
3920 			bwmode = pmlmeext->cur_bwmode;
3921 		}
3922 
3923 		set_channel_bwmode(padapter, channel, ch_offset, bwmode);
3924 	}
3925 
3926 exit:
3927 	return ret;
3928 
3929 }
3930 
3931 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
3932 				    struct iw_request_info *info,
3933 				    union iwreq_data *wrqu, char *extra)
3934 {
3935 
3936 	int ret = 0;
3937 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3938 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3939 
3940 	RTW_INFO("[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen(extra));
3941 	if( strlen(extra) > WPS_MAX_DEVICE_NAME_LEN){
3942 		RTW_ERR("Invalid strlen(extra): %zu\n", strlen(extra));
3943 		rtw_warn_on(1);
3944 		return -1;
3945 	}
3946 	_rtw_memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
3947 	pwdinfo->nego_ssidlen = strlen(extra);
3948 
3949 	return ret;
3950 
3951 }
3952 
3953 
3954 static int rtw_p2p_set_intent(struct net_device *dev,
3955 			      struct iw_request_info *info,
3956 			      union iwreq_data *wrqu, char *extra)
3957 {
3958 	int							ret = 0;
3959 	_adapter						*padapter = (_adapter *)rtw_netdev_priv(dev);
3960 	struct wifidirect_info			*pwdinfo = &(padapter->wdinfo);
3961 	u8							intent = pwdinfo->intent;
3962 
3963 	extra[wrqu->data.length] = 0x00;
3964 
3965 	intent = rtw_atoi(extra);
3966 
3967 	if (intent <= 15)
3968 		pwdinfo->intent = intent;
3969 	else
3970 		ret = -1;
3971 
3972 	RTW_INFO("[%s] intent = %d\n", __FUNCTION__, intent);
3973 
3974 	return ret;
3975 
3976 }
3977 
3978 static int rtw_p2p_set_listen_ch(struct net_device *dev,
3979 				 struct iw_request_info *info,
3980 				 union iwreq_data *wrqu, char *extra)
3981 {
3982 
3983 	int ret = 0;
3984 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3985 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3986 	u8	listen_ch = pwdinfo->listen_channel;	/*	Listen channel number */
3987 
3988 	extra[wrqu->data.length] = 0x00;
3989 	listen_ch = rtw_atoi(extra);
3990 
3991 	if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
3992 		pwdinfo->listen_channel = listen_ch;
3993 		set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3994 	} else
3995 		ret = -1;
3996 
3997 	RTW_INFO("[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel);
3998 
3999 	return ret;
4000 
4001 }
4002 
4003 static int rtw_p2p_set_op_ch(struct net_device *dev,
4004 			     struct iw_request_info *info,
4005 			     union iwreq_data *wrqu, char *extra)
4006 {
4007 	/*	Commented by Albert 20110524
4008 	 *	This function is used to set the operating channel if the driver will become the group owner */
4009 
4010 	int ret = 0;
4011 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4012 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4013 	u8	op_ch = pwdinfo->operating_channel;	/*	Operating channel number */
4014 
4015 	extra[wrqu->data.length] = 0x00;
4016 
4017 	op_ch = (u8) rtw_atoi(extra);
4018 	if (op_ch > 0)
4019 		pwdinfo->operating_channel = op_ch;
4020 	else
4021 		ret = -1;
4022 
4023 	RTW_INFO("[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel);
4024 
4025 	return ret;
4026 
4027 }
4028 
4029 
4030 static int rtw_p2p_profilefound(struct net_device *dev,
4031 				struct iw_request_info *info,
4032 				union iwreq_data *wrqu, char *extra)
4033 {
4034 
4035 	int ret = 0;
4036 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4037 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4038 
4039 	/*	Comment by Albert 2010/10/13 */
4040 	/*	Input data format: */
4041 	/*	Ex:  0 */
4042 	/*	Ex:  1XX:XX:XX:XX:XX:XXYYSSID */
4043 	/*	0 => Reflush the profile record list. */
4044 	/*	1 => Add the profile list */
4045 	/*	XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) */
4046 	/*	YY => SSID Length */
4047 	/*	SSID => SSID for persistence group */
4048 
4049 	RTW_INFO("[%s] In value = %s, len = %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4050 
4051 
4052 	/*	The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
4053 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4054 		if (extra[0] == '0') {
4055 			/*	Remove all the profile information of wifidirect_info structure. */
4056 			_rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
4057 			pwdinfo->profileindex = 0;
4058 		} else {
4059 			if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM)
4060 				ret = -1;
4061 			else {
4062 				int jj, kk;
4063 
4064 				/*	Add this profile information into pwdinfo->profileinfo */
4065 				/*	Ex:  1XX:XX:XX:XX:XX:XXYYSSID */
4066 				for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
4067 					pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4068 
4069 				/* pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[19] - '0' ); */
4070 				/* _rtw_memcpy( pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen ); */
4071 				pwdinfo->profileindex++;
4072 			}
4073 		}
4074 	}
4075 
4076 	return ret;
4077 
4078 }
4079 
4080 static int rtw_p2p_setDN(struct net_device *dev,
4081 			 struct iw_request_info *info,
4082 			 union iwreq_data *wrqu, char *extra)
4083 {
4084 
4085 	int ret = 0;
4086 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4087 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4088 
4089 
4090 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4091 	_rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
4092 	if( wrqu->data.length - 1 > WPS_MAX_DEVICE_NAME_LEN){
4093 		RTW_ERR("Invalid wrqu->data.length:%d\n", wrqu->data.length - 1);
4094 		rtw_warn_on(1);
4095 		return -1;
4096 	}
4097 	_rtw_memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
4098 	pwdinfo->device_name_len = wrqu->data.length - 1;
4099 
4100 	return ret;
4101 
4102 }
4103 
4104 
4105 static int rtw_p2p_get_status(struct net_device *dev,
4106 			      struct iw_request_info *info,
4107 			      union iwreq_data *wrqu, char *extra)
4108 {
4109 
4110 	int ret = 0;
4111 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4112 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4113 
4114 	if (padapter->bShowGetP2PState) {
4115 		RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4116 			pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4117 			pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4118 	}
4119 
4120 	/*	Commented by Albert 2010/10/12 */
4121 	/*	Because of the output size limitation, I had removed the "Role" information. */
4122 	/*	About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
4123 	sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
4124 	wrqu->data.length = strlen(extra);
4125 
4126 	return ret;
4127 
4128 }
4129 
4130 /*	Commented by Albert 20110520
4131  *	This function will return the config method description
4132  *	This config method description will show us which config method the remote P2P device is intented to use
4133  *	by sending the provisioning discovery request frame. */
4134 
4135 static int rtw_p2p_get_req_cm(struct net_device *dev,
4136 			      struct iw_request_info *info,
4137 			      union iwreq_data *wrqu, char *extra)
4138 {
4139 
4140 	int ret = 0;
4141 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4142 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4143 
4144 	sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
4145 	wrqu->data.length = strlen(extra);
4146 	return ret;
4147 
4148 }
4149 
4150 
4151 static int rtw_p2p_get_role(struct net_device *dev,
4152 			    struct iw_request_info *info,
4153 			    union iwreq_data *wrqu, char *extra)
4154 {
4155 
4156 	int ret = 0;
4157 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4158 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4159 
4160 	RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4161 		pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4162 		pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4163 
4164 	sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
4165 	wrqu->data.length = strlen(extra);
4166 	return ret;
4167 
4168 }
4169 
4170 
4171 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4172 				   struct iw_request_info *info,
4173 				   union iwreq_data *wrqu, char *extra)
4174 {
4175 
4176 	int ret = 0;
4177 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4178 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4179 
4180 
4181 	RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4182 		pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4183 		pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4184 
4185 	sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4186 		pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4187 		pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4188 	wrqu->data.length = strlen(extra);
4189 	return ret;
4190 
4191 }
4192 
4193 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4194 				    struct iw_request_info *info,
4195 				    union iwreq_data *wrqu, char *extra)
4196 
4197 {
4198 
4199 	int ret = 0;
4200 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4201 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4202 
4203 	RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4204 		pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4205 		pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4206 		pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4207 	sprintf(extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4208 		pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4209 		pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4210 		pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4211 	wrqu->data.length = strlen(extra);
4212 	return ret;
4213 
4214 }
4215 
4216 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4217 		struct iw_request_info *info,
4218 		union iwreq_data *wrqu, char *extra)
4219 
4220 {
4221 
4222 	int ret = 0;
4223 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4224 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4225 
4226 	RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4227 		pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4228 		pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4229 		pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4230 	sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4231 		pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4232 		pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4233 		pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4234 	wrqu->data.length = strlen(extra);
4235 	return ret;
4236 
4237 }
4238 
4239 static int rtw_p2p_get_groupid(struct net_device *dev,
4240 			       struct iw_request_info *info,
4241 			       union iwreq_data *wrqu, char *extra)
4242 
4243 {
4244 
4245 	int ret = 0;
4246 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4247 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4248 
4249 	sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4250 		pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
4251 		pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
4252 		pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
4253 		pwdinfo->groupid_info.ssid);
4254 	wrqu->data.length = strlen(extra);
4255 	return ret;
4256 
4257 }
4258 
4259 static int rtw_p2p_get_op_ch(struct net_device *dev,
4260 			     struct iw_request_info *info,
4261 			     union iwreq_data *wrqu, char *extra)
4262 
4263 {
4264 
4265 	int ret = 0;
4266 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4267 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4268 
4269 
4270 	RTW_INFO("[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4271 
4272 	sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
4273 	wrqu->data.length = strlen(extra);
4274 	return ret;
4275 
4276 }
4277 
4278 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4279 					struct iw_request_info *info,
4280 			union iwreq_data *wrqu, char *extra, char *subcmd)
4281 {
4282 
4283 	int ret = 0;
4284 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4285 	u8 peerMAC[ETH_ALEN] = { 0x00 };
4286 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4287 	_irqL irqL;
4288 	_list *plist, *phead;
4289 	_queue *queue = &(pmlmepriv->scanned_queue);
4290 	struct wlan_network *pnetwork = NULL;
4291 	u8 blnMatch = 0;
4292 	u16	attr_content = 0;
4293 	uint attr_contentlen = 0;
4294 	u8	attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4295 
4296 	/*	Commented by Albert 20110727 */
4297 	/*	The input data is the MAC address which the application wants to know its WPS config method. */
4298 	/*	After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
4299 	/*	Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
4300 
4301 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4302 
4303 	macstr2num(peerMAC, subcmd);
4304 
4305 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4306 
4307 	phead = get_list_head(queue);
4308 	plist = get_next(phead);
4309 
4310 	while (1) {
4311 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4312 			break;
4313 
4314 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4315 		if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4316 			u8 *wpsie;
4317 			uint	wpsie_len = 0;
4318 
4319 			/*	The mac address is matched. */
4320 
4321 			wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4322 			if (wpsie) {
4323 				attr_contentlen = sizeof(attr_content);
4324 				rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4325 				if (attr_contentlen) {
4326 					attr_content = be16_to_cpu(attr_content);
4327 					sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4328 					blnMatch = 1;
4329 				}
4330 			}
4331 
4332 			break;
4333 		}
4334 
4335 		plist = get_next(plist);
4336 
4337 	}
4338 
4339 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4340 
4341 	if (!blnMatch)
4342 		sprintf(attr_content_str, "\n\nM=0000");
4343 
4344 	wrqu->data.length = strlen(attr_content_str);
4345 	_rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4346 
4347 	return ret;
4348 
4349 }
4350 
4351 #ifdef CONFIG_WFD
4352 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4353 				     struct iw_request_info *info,
4354 				     union iwreq_data *wrqu, char *extra)
4355 {
4356 
4357 	int ret = 0;
4358 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4359 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4360 
4361 	RTW_INFO("[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
4362 
4363 	sprintf(extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport);
4364 	RTW_INFO("[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
4365 
4366 	wrqu->data.length = strlen(extra);
4367 	return ret;
4368 
4369 }
4370 
4371 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4372 		struct iw_request_info *info,
4373 		union iwreq_data *wrqu, char *extra)
4374 {
4375 
4376 	int ret = 0;
4377 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4378 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4379 
4380 	sprintf(extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc);
4381 	RTW_INFO("[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc);
4382 
4383 	wrqu->data.length = strlen(extra);
4384 	pwdinfo->wfd_info->wfd_pc = _FALSE;	/*	Reset the WFD preferred connection to P2P */
4385 	return ret;
4386 
4387 }
4388 
4389 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4390 		struct iw_request_info *info,
4391 		union iwreq_data *wrqu, char *extra)
4392 {
4393 
4394 	int ret = 0;
4395 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4396 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4397 
4398 	sprintf(extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail);
4399 	RTW_INFO("[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail);
4400 
4401 	wrqu->data.length = strlen(extra);
4402 	pwdinfo->wfd_info->peer_session_avail = _TRUE;	/*	Reset the WFD session available */
4403 	return ret;
4404 
4405 }
4406 #endif /* CONFIG_WFD */
4407 
4408 static int rtw_p2p_get_go_device_address(struct net_device *dev,
4409 		struct iw_request_info *info,
4410 		union iwreq_data *wrqu, char *extra, char *subcmd)
4411 {
4412 
4413 	int ret = 0;
4414 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4415 	u8 peerMAC[ETH_ALEN] = { 0x00 };
4416 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4417 	_irqL irqL;
4418 	_list *plist, *phead;
4419 	_queue *queue	= &(pmlmepriv->scanned_queue);
4420 	struct wlan_network *pnetwork = NULL;
4421 	u8 blnMatch = 0;
4422 	u8 *p2pie;
4423 	uint p2pielen = 0, attr_contentlen = 0;
4424 	u8 attr_content[100] = { 0x00 };
4425 	u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4426 
4427 	/*	Commented by Albert 20121209 */
4428 	/*	The input data is the GO's interface address which the application wants to know its device address. */
4429 	/*	Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 */
4430 
4431 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4432 
4433 	macstr2num(peerMAC, subcmd);
4434 
4435 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4436 
4437 	phead = get_list_head(queue);
4438 	plist = get_next(phead);
4439 
4440 	while (1) {
4441 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4442 			break;
4443 
4444 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4445 		if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4446 			/*	Commented by Albert 2011/05/18 */
4447 			/*	Match the device address located in the P2P IE */
4448 			/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
4449 
4450 			p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4451 			if (p2pie) {
4452 				while (p2pie) {
4453 					/*	The P2P Device ID attribute is included in the Beacon frame. */
4454 					/*	The P2P Device Info attribute is included in the probe response frame. */
4455 
4456 					_rtw_memset(attr_content, 0x00, 100);
4457 					attr_contentlen = sizeof(attr_content);
4458 					if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
4459 						/*	Handle the P2P Device ID attribute of Beacon first */
4460 						blnMatch = 1;
4461 						break;
4462 
4463 					} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
4464 						/*	Handle the P2P Device Info attribute of probe response */
4465 						blnMatch = 1;
4466 						break;
4467 					}
4468 
4469 					/* Get the next P2P IE */
4470 					p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
4471 				}
4472 			}
4473 		}
4474 
4475 		plist = get_next(plist);
4476 
4477 	}
4478 
4479 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4480 
4481 	if (!blnMatch)
4482 		sprintf(go_devadd_str, "\n\ndev_add=NULL");
4483 	else {
4484 		sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4485 			attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
4486 	}
4487 
4488 	wrqu->data.length = strlen(go_devadd_str);
4489 	_rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
4490 
4491 	return ret;
4492 
4493 }
4494 
4495 static int rtw_p2p_get_device_type(struct net_device *dev,
4496 				   struct iw_request_info *info,
4497 			   union iwreq_data *wrqu, char *extra, char *subcmd)
4498 {
4499 
4500 	int ret = 0;
4501 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4502 	u8 peerMAC[ETH_ALEN] = { 0x00 };
4503 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4504 	_irqL irqL;
4505 	_list *plist, *phead;
4506 	_queue *queue = &(pmlmepriv->scanned_queue);
4507 	struct wlan_network *pnetwork = NULL;
4508 	u8 blnMatch = 0;
4509 	u8 dev_type[8] = { 0x00 };
4510 	uint dev_type_len = 0;
4511 	u8 dev_type_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };    /* +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */
4512 
4513 	/*	Commented by Albert 20121209 */
4514 	/*	The input data is the MAC address which the application wants to know its device type. */
4515 	/*	Such user interface could know the device type. */
4516 	/*	Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 */
4517 
4518 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4519 
4520 	macstr2num(peerMAC, subcmd);
4521 
4522 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4523 
4524 	phead = get_list_head(queue);
4525 	plist = get_next(phead);
4526 
4527 	while (1) {
4528 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4529 			break;
4530 
4531 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4532 		if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4533 			u8 *wpsie;
4534 			uint	wpsie_len = 0;
4535 
4536 			/*	The mac address is matched. */
4537 
4538 			wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4539 			if (wpsie) {
4540 				dev_type_len = sizeof(dev_type);
4541 				rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
4542 				if (dev_type_len) {
4543 					u16	type = 0;
4544 
4545 					_rtw_memcpy(&type, dev_type, 2);
4546 					type = be16_to_cpu(type);
4547 					sprintf(dev_type_str, "\n\nN=%.2d", type);
4548 					blnMatch = 1;
4549 				}
4550 			}
4551 			break;
4552 		}
4553 
4554 		plist = get_next(plist);
4555 
4556 	}
4557 
4558 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4559 
4560 	if (!blnMatch)
4561 		sprintf(dev_type_str, "\n\nN=00");
4562 
4563 	wrqu->data.length = strlen(dev_type_str);
4564 	_rtw_memcpy(extra, dev_type_str, wrqu->data.length);
4565 
4566 	return ret;
4567 
4568 }
4569 
4570 static int rtw_p2p_get_device_name(struct net_device *dev,
4571 				   struct iw_request_info *info,
4572 			   union iwreq_data *wrqu, char *extra, char *subcmd)
4573 {
4574 
4575 	int ret = 0;
4576 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4577 	u8 peerMAC[ETH_ALEN] = { 0x00 };
4578 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4579 	_irqL irqL;
4580 	_list *plist, *phead;
4581 	_queue *queue = &(pmlmepriv->scanned_queue);
4582 	struct wlan_network *pnetwork = NULL;
4583 	u8 blnMatch = 0;
4584 	u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
4585 	uint dev_len = 0;
4586 	u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4587 
4588 	/*	Commented by Albert 20121225 */
4589 	/*	The input data is the MAC address which the application wants to know its device name. */
4590 	/*	Such user interface could show peer device's device name instead of ssid. */
4591 	/*	Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 */
4592 
4593 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4594 
4595 	macstr2num(peerMAC, subcmd);
4596 
4597 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4598 
4599 	phead = get_list_head(queue);
4600 	plist = get_next(phead);
4601 
4602 	while (1) {
4603 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4604 			break;
4605 
4606 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4607 		if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4608 			u8 *wpsie;
4609 			uint	wpsie_len = 0;
4610 
4611 			/*	The mac address is matched. */
4612 
4613 			wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4614 			if (wpsie) {
4615 				dev_len = sizeof(dev_name);
4616 				rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
4617 				if (dev_len) {
4618 					sprintf(dev_name_str, "\n\nN=%s", dev_name);
4619 					blnMatch = 1;
4620 				}
4621 			}
4622 			break;
4623 		}
4624 
4625 		plist = get_next(plist);
4626 
4627 	}
4628 
4629 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4630 
4631 	if (!blnMatch)
4632 		sprintf(dev_name_str, "\n\nN=0000");
4633 
4634 	wrqu->data.length = strlen(dev_name_str);
4635 	_rtw_memcpy(extra, dev_name_str, wrqu->data.length);
4636 
4637 	return ret;
4638 
4639 }
4640 
4641 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
4642 		struct iw_request_info *info,
4643 		union iwreq_data *wrqu, char *extra, char *subcmd)
4644 {
4645 
4646 	int ret = 0;
4647 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4648 	u8 peerMAC[ETH_ALEN] = { 0x00 };
4649 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4650 	_irqL irqL;
4651 	_list *plist, *phead;
4652 	_queue *queue	= &(pmlmepriv->scanned_queue);
4653 	struct wlan_network *pnetwork = NULL;
4654 	u8 blnMatch = 0;
4655 	u8 *p2pie;
4656 	uint p2pielen = 0, attr_contentlen = 2;
4657 	u8 attr_content[2] = { 0x00 };
4658 	u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4659 
4660 	/*	Commented by Ouden 20121226 */
4661 	/*	The application wants to know P2P initation procedure is support or not. */
4662 	/*	Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 */
4663 
4664 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4665 
4666 	macstr2num(peerMAC, subcmd);
4667 
4668 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4669 
4670 	phead = get_list_head(queue);
4671 	plist = get_next(phead);
4672 
4673 	while (1) {
4674 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4675 			break;
4676 
4677 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4678 		if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4679 			/*	Commented by Albert 20121226 */
4680 			/*	Match the device address located in the P2P IE */
4681 			/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
4682 
4683 			p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4684 			if (p2pie) {
4685 				while (p2pie) {
4686 					/* _rtw_memset( attr_content, 0x00, 2); */
4687 					attr_contentlen = sizeof(attr_content);
4688 					if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
4689 						/*	Handle the P2P capability attribute */
4690 						blnMatch = 1;
4691 						break;
4692 
4693 					}
4694 
4695 					/* Get the next P2P IE */
4696 					p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
4697 				}
4698 			}
4699 		}
4700 
4701 		plist = get_next(plist);
4702 
4703 	}
4704 
4705 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4706 
4707 	if (!blnMatch)
4708 		sprintf(inv_proc_str, "\nIP=-1");
4709 	else {
4710 		if ((attr_content[0] & 0x20) == 0x20)
4711 			sprintf(inv_proc_str, "\nIP=1");
4712 		else
4713 			sprintf(inv_proc_str, "\nIP=0");
4714 	}
4715 
4716 	wrqu->data.length = strlen(inv_proc_str);
4717 	_rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
4718 
4719 	return ret;
4720 
4721 }
4722 
4723 static int rtw_p2p_connect(struct net_device *dev,
4724 			   struct iw_request_info *info,
4725 			   union iwreq_data *wrqu, char *extra)
4726 {
4727 
4728 	int ret = 0;
4729 	_adapter				*padapter = (_adapter *)rtw_netdev_priv(dev);
4730 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
4731 	u8					peerMAC[ETH_ALEN] = { 0x00 };
4732 	int					jj, kk;
4733 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
4734 	_irqL				irqL;
4735 	_list					*plist, *phead;
4736 	_queue				*queue	= &(pmlmepriv->scanned_queue);
4737 	struct	wlan_network	*pnetwork = NULL;
4738 	uint					uintPeerChannel = 0;
4739 #ifdef CONFIG_CONCURRENT_MODE
4740 	struct roch_info		*prochinfo = &padapter->rochinfo;
4741 #endif
4742 
4743 	/*	Commented by Albert 20110304 */
4744 	/*	The input data contains two informations. */
4745 	/*	1. First information is the MAC address which wants to formate with */
4746 	/*	2. Second information is the WPS PINCode or "pbc" string for push button method */
4747 	/*	Format: 00:E0:4C:00:00:05 */
4748 	/*	Format: 00:E0:4C:00:00:05 */
4749 
4750 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
4751 
4752 	if (pwdinfo->p2p_state == P2P_STATE_NONE) {
4753 		RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
4754 		return ret;
4755 	}
4756 
4757 	if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
4758 		return -1;
4759 
4760 	for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4761 		peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4762 
4763 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4764 
4765 	phead = get_list_head(queue);
4766 	plist = get_next(phead);
4767 
4768 	while (1) {
4769 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4770 			break;
4771 
4772 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4773 		if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4774 			if (pnetwork->network.Configuration.DSConfig != 0)
4775 				uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4776 			else if (pwdinfo->nego_req_info.peer_ch != 0)
4777 				uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch;
4778 			else {
4779 				/* Unexpected case */
4780 				uintPeerChannel = 0;
4781 				RTW_INFO("%s  uintPeerChannel = 0\n", __func__);
4782 			}
4783 			break;
4784 		}
4785 
4786 		plist = get_next(plist);
4787 
4788 	}
4789 
4790 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4791 
4792 	if (uintPeerChannel) {
4793 #ifdef CONFIG_CONCURRENT_MODE
4794 		if (rtw_mi_check_status(padapter, MI_LINKED))
4795 			_cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
4796 #endif /* CONFIG_CONCURRENT_MODE */
4797 
4798 		_rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
4799 		_rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
4800 
4801 		pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
4802 		_rtw_memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
4803 		pwdinfo->nego_req_info.benable = _TRUE;
4804 
4805 		_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
4806 		if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
4807 			/*	Restore to the listen state if the current p2p state is not nego OK */
4808 			rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4809 		}
4810 
4811 		rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4812 		rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
4813 
4814 #ifdef CONFIG_CONCURRENT_MODE
4815 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
4816 			u8 union_ch = rtw_mi_get_union_chan(padapter);
4817 			u8 union_bw = rtw_mi_get_union_bw(padapter);
4818 			u8 union_offset = rtw_mi_get_union_offset(padapter);
4819 
4820 			set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
4821 			rtw_leave_opch(padapter);
4822 		}
4823 #endif /* CONFIG_CONCURRENT_MODE */
4824 
4825 		RTW_INFO("[%s] Start PreTx Procedure!\n", __FUNCTION__);
4826 		_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
4827 #ifdef CONFIG_CONCURRENT_MODE
4828 		if (rtw_mi_check_status(padapter, MI_LINKED))
4829 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT);
4830 		else
4831 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
4832 #else
4833 		_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
4834 #endif /* CONFIG_CONCURRENT_MODE		 */
4835 
4836 	} else {
4837 		RTW_INFO("[%s] Not Found in Scanning Queue~\n", __FUNCTION__);
4838 		ret = -1;
4839 	}
4840 
4841 	return ret;
4842 }
4843 
4844 static int rtw_p2p_invite_req(struct net_device *dev,
4845 			      struct iw_request_info *info,
4846 			      union iwreq_data *wrqu, char *extra)
4847 {
4848 
4849 	int ret = 0;
4850 	_adapter					*padapter = (_adapter *)rtw_netdev_priv(dev);
4851 	struct wifidirect_info		*pwdinfo = &(padapter->wdinfo);
4852 	int						jj, kk;
4853 	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
4854 	_list						*plist, *phead;
4855 	_queue					*queue	= &(pmlmepriv->scanned_queue);
4856 	struct	wlan_network		*pnetwork = NULL;
4857 	uint						uintPeerChannel = 0;
4858 	u8						attr_content[50] = { 0x00 };
4859 	u8						*p2pie;
4860 	uint						p2pielen = 0, attr_contentlen = 50;
4861 	_irqL					irqL;
4862 	struct tx_invite_req_info	*pinvite_req_info = &pwdinfo->invitereq_info;
4863 #ifdef CONFIG_CONCURRENT_MODE
4864 	struct roch_info			*prochinfo = &padapter->rochinfo;
4865 #endif
4866 
4867 	/*	Commented by Albert 20120321 */
4868 	/*	The input data contains two informations. */
4869 	/*	1. First information is the P2P device address which you want to send to.	 */
4870 	/*	2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
4871 	/*	Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
4872 	/*	Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
4873 
4874 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
4875 
4876 	if (wrqu->data.length <=  37) {
4877 		RTW_INFO("[%s] Wrong format!\n", __FUNCTION__);
4878 		return ret;
4879 	}
4880 
4881 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4882 		RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
4883 		return ret;
4884 	} else {
4885 		/*	Reset the content of struct tx_invite_req_info */
4886 		pinvite_req_info->benable = _FALSE;
4887 		_rtw_memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
4888 		_rtw_memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
4889 		pinvite_req_info->ssidlen = 0x00;
4890 		pinvite_req_info->operating_ch = pwdinfo->operating_channel;
4891 		_rtw_memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
4892 		pinvite_req_info->token = 3;
4893 	}
4894 
4895 	for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4896 		pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4897 
4898 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4899 
4900 	phead = get_list_head(queue);
4901 	plist = get_next(phead);
4902 
4903 	while (1) {
4904 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4905 			break;
4906 
4907 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4908 
4909 		/*	Commented by Albert 2011/05/18 */
4910 		/*	Match the device address located in the P2P IE */
4911 		/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
4912 
4913 		p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4914 		if (p2pie) {
4915 			/*	The P2P Device ID attribute is included in the Beacon frame. */
4916 			/*	The P2P Device Info attribute is included in the probe response frame. */
4917 
4918 			attr_contentlen = sizeof(attr_content);
4919 			if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
4920 				/*	Handle the P2P Device ID attribute of Beacon first */
4921 				if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
4922 					uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4923 					break;
4924 				}
4925 			} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
4926 				/*	Handle the P2P Device Info attribute of probe response */
4927 				if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
4928 					uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4929 					break;
4930 				}
4931 			}
4932 
4933 		}
4934 
4935 		plist = get_next(plist);
4936 
4937 	}
4938 
4939 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4940 
4941 #ifdef CONFIG_WFD
4942 	if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) {
4943 		struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
4944 		u8 *wfd_ie;
4945 		uint wfd_ielen = 0;
4946 
4947 		wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
4948 		if (wfd_ie) {
4949 			u8 *wfd_devinfo;
4950 			uint wfd_devlen;
4951 
4952 			RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
4953 			wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
4954 			if (wfd_devinfo) {
4955 				u16	wfd_devinfo_field = 0;
4956 
4957 				/*	Commented by Albert 20120319 */
4958 				/*	The first two bytes are the WFD device information field of WFD device information subelement. */
4959 				/*	In big endian format. */
4960 				wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
4961 				if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
4962 					pwfd_info->peer_session_avail = _TRUE;
4963 				else
4964 					pwfd_info->peer_session_avail = _FALSE;
4965 			}
4966 		}
4967 
4968 		if (_FALSE == pwfd_info->peer_session_avail) {
4969 			RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
4970 			goto exit;
4971 		}
4972 	}
4973 #endif /* CONFIG_WFD */
4974 
4975 	if (uintPeerChannel) {
4976 #ifdef CONFIG_CONCURRENT_MODE
4977 		if (rtw_mi_check_status(padapter, MI_LINKED))
4978 			_cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
4979 #endif /* CONFIG_CONCURRENT_MODE */
4980 
4981 		/*	Store the GO's bssid */
4982 		for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
4983 			pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4984 
4985 		/*	Store the GO's ssid */
4986 		pinvite_req_info->ssidlen = wrqu->data.length - 36;
4987 		_rtw_memcpy(pinvite_req_info->go_ssid, &extra[36], (u32) pinvite_req_info->ssidlen);
4988 		pinvite_req_info->benable = _TRUE;
4989 		pinvite_req_info->peer_ch = uintPeerChannel;
4990 
4991 		rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4992 		rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
4993 
4994 #ifdef CONFIG_CONCURRENT_MODE
4995 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
4996 			u8 union_ch = rtw_mi_get_union_chan(padapter);
4997 			u8 union_bw = rtw_mi_get_union_bw(padapter);
4998 			u8 union_offset = rtw_mi_get_union_offset(padapter);
4999 
5000 			set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5001 			rtw_leave_opch(padapter);
5002 
5003 		} else
5004 			set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5005 #else
5006 		set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5007 #endif/*CONFIG_CONCURRENT_MODE*/
5008 
5009 		_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5010 
5011 #ifdef CONFIG_CONCURRENT_MODE
5012 		if (rtw_mi_check_status(padapter, MI_LINKED))
5013 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT);
5014 		else
5015 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5016 #else
5017 		_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5018 #endif /* CONFIG_CONCURRENT_MODE		 */
5019 
5020 
5021 	} else
5022 		RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5023 exit:
5024 
5025 	return ret;
5026 
5027 }
5028 
5029 static int rtw_p2p_set_persistent(struct net_device *dev,
5030 				  struct iw_request_info *info,
5031 				  union iwreq_data *wrqu, char *extra)
5032 {
5033 
5034 	int ret = 0;
5035 	_adapter					*padapter = (_adapter *)rtw_netdev_priv(dev);
5036 	struct wifidirect_info		*pwdinfo = &(padapter->wdinfo);
5037 
5038 	/*	Commented by Albert 20120328 */
5039 	/*	The input data is 0 or 1 */
5040 	/*	0: disable persistent group functionality */
5041 	/*	1: enable persistent group founctionality */
5042 
5043 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5044 
5045 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5046 		RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5047 		return ret;
5048 	} else {
5049 		if (extra[0] == '0')	/*	Disable the persistent group function. */
5050 			pwdinfo->persistent_supported = _FALSE;
5051 		else if (extra[0] == '1')	/*	Enable the persistent group function. */
5052 			pwdinfo->persistent_supported = _TRUE;
5053 		else
5054 			pwdinfo->persistent_supported = _FALSE;
5055 	}
5056 	printk("[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported);
5057 
5058 	return ret;
5059 
5060 }
5061 
5062 static int uuid_str2bin(const char *str, u8 *bin)
5063 {
5064 	const char *pos;
5065 	u8 *opos;
5066 
5067 	pos = str;
5068 	opos = bin;
5069 
5070 	if (hexstr2bin(pos, opos, 4))
5071 		return -1;
5072 	pos += 8;
5073 	opos += 4;
5074 
5075 	if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5076 		return -1;
5077 	pos += 4;
5078 	opos += 2;
5079 
5080 	if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5081 		return -1;
5082 	pos += 4;
5083 	opos += 2;
5084 
5085 	if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5086 		return -1;
5087 	pos += 4;
5088 	opos += 2;
5089 
5090 	if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5091 		return -1;
5092 
5093 	return 0;
5094 }
5095 
5096 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5097 				struct iw_request_info *info,
5098 				union iwreq_data *wrqu, char *extra)
5099 {
5100 
5101 	int ret = 0;
5102 	_adapter				*padapter = (_adapter *)rtw_netdev_priv(dev);
5103 	struct wifidirect_info			*pwdinfo = &(padapter->wdinfo);
5104 
5105 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5106 
5107 	if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))
5108 		pwdinfo->external_uuid = 1;
5109 	else {
5110 		pwdinfo->external_uuid = 0;
5111 		ret = -EINVAL;
5112 	}
5113 
5114 	return ret;
5115 
5116 }
5117 #ifdef CONFIG_WFD
5118 static int rtw_p2p_set_pc(struct net_device *dev,
5119 			  struct iw_request_info *info,
5120 			  union iwreq_data *wrqu, char *extra)
5121 {
5122 
5123 	int ret = 0;
5124 	_adapter				*padapter = (_adapter *)rtw_netdev_priv(dev);
5125 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5126 	u8					peerMAC[ETH_ALEN] = { 0x00 };
5127 	int					jj, kk;
5128 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
5129 	_list					*plist, *phead;
5130 	_queue				*queue	= &(pmlmepriv->scanned_queue);
5131 	struct	wlan_network	*pnetwork = NULL;
5132 	u8					attr_content[50] = { 0x00 };
5133 	u8 *p2pie;
5134 	uint					p2pielen = 0, attr_contentlen = 50;
5135 	_irqL				irqL;
5136 	uint					uintPeerChannel = 0;
5137 
5138 	struct wifi_display_info	*pwfd_info = pwdinfo->wfd_info;
5139 
5140 	/*	Commented by Albert 20120512 */
5141 	/*	1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) */
5142 	/*	Format: 00:E0:4C:00:00:05 */
5143 
5144 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5145 
5146 	if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5147 		RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5148 		return ret;
5149 	}
5150 
5151 	for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5152 		peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5153 
5154 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5155 
5156 	phead = get_list_head(queue);
5157 	plist = get_next(phead);
5158 
5159 	while (1) {
5160 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5161 			break;
5162 
5163 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5164 
5165 		/*	Commented by Albert 2011/05/18 */
5166 		/*	Match the device address located in the P2P IE */
5167 		/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
5168 
5169 		p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5170 		if (p2pie) {
5171 			/*	The P2P Device ID attribute is included in the Beacon frame. */
5172 			/*	The P2P Device Info attribute is included in the probe response frame. */
5173 			printk("[%s] Got P2P IE\n", __FUNCTION__);
5174 			attr_contentlen = sizeof(attr_content);
5175 			if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5176 				/*	Handle the P2P Device ID attribute of Beacon first */
5177 				printk("[%s] P2P_ATTR_DEVICE_ID\n", __FUNCTION__);
5178 				if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5179 					uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5180 					break;
5181 				}
5182 			} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5183 				/*	Handle the P2P Device Info attribute of probe response */
5184 				printk("[%s] P2P_ATTR_DEVICE_INFO\n", __FUNCTION__);
5185 				if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5186 					uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5187 					break;
5188 				}
5189 			}
5190 
5191 		}
5192 
5193 		plist = get_next(plist);
5194 
5195 	}
5196 
5197 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5198 	printk("[%s] channel = %d\n", __FUNCTION__, uintPeerChannel);
5199 
5200 	if (uintPeerChannel) {
5201 		u8 *wfd_ie;
5202 		uint wfd_ielen = 0;
5203 
5204 		wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5205 		if (wfd_ie) {
5206 			u8 *wfd_devinfo;
5207 			uint wfd_devlen;
5208 
5209 			RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5210 			wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5211 			if (wfd_devinfo) {
5212 				u16	wfd_devinfo_field = 0;
5213 
5214 				/*	Commented by Albert 20120319 */
5215 				/*	The first two bytes are the WFD device information field of WFD device information subelement. */
5216 				/*	In big endian format. */
5217 				wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5218 				if (wfd_devinfo_field & WFD_DEVINFO_PC_TDLS)
5219 					pwfd_info->wfd_pc = _TRUE;
5220 				else
5221 					pwfd_info->wfd_pc = _FALSE;
5222 			}
5223 		}
5224 	} else
5225 		RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5226 
5227 	return ret;
5228 
5229 }
5230 
5231 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5232 				       struct iw_request_info *info,
5233 				       union iwreq_data *wrqu, char *extra)
5234 {
5235 
5236 	int ret = 0;
5237 	_adapter					*padapter = (_adapter *)rtw_netdev_priv(dev);
5238 	struct wifidirect_info		*pwdinfo = &(padapter->wdinfo);
5239 	struct wifi_display_info		*pwfd_info = pwdinfo->wfd_info;
5240 
5241 	/*	Commented by Albert 20120328 */
5242 	/*	The input data is 0 or 1 */
5243 	/*	0: specify to Miracast source device */
5244 	/*	1 or others: specify to Miracast sink device (display device) */
5245 
5246 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5247 
5248 	if (extra[0] == '0')	/*	Set to Miracast source device. */
5249 		pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5250 	else					/*	Set to Miracast sink device. */
5251 		pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5252 
5253 	return ret;
5254 
5255 }
5256 
5257 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
5258 				  struct iw_request_info *info,
5259 				  union iwreq_data *wrqu, char *extra)
5260 {
5261 	/*	Commented by Kurt 20121206
5262 	 *	This function is used to set wfd enabled */
5263 
5264 	int ret = 0;
5265 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5266 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5267 
5268 	if (*extra == '0')
5269 		rtw_wfd_enable(padapter, 0);
5270 	else if (*extra == '1')
5271 		rtw_wfd_enable(padapter, 1);
5272 
5273 	RTW_INFO("[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable);
5274 
5275 	return ret;
5276 
5277 }
5278 
5279 static int rtw_p2p_set_driver_iface(struct net_device *dev,
5280 				    struct iw_request_info *info,
5281 				    union iwreq_data *wrqu, char *extra)
5282 {
5283 	/*	Commented by Kurt 20121206
5284 	 *	This function is used to set driver iface is WEXT or CFG80211 */
5285 	int ret = 0;
5286 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5287 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5288 
5289 	if (*extra == '1') {
5290 		pwdinfo->driver_interface = DRIVER_WEXT;
5291 		RTW_INFO("[%s] driver_interface = WEXT\n", __FUNCTION__);
5292 	} else if (*extra == '2') {
5293 		pwdinfo->driver_interface = DRIVER_CFG80211;
5294 		RTW_INFO("[%s] driver_interface = CFG80211\n", __FUNCTION__);
5295 	}
5296 
5297 	return ret;
5298 
5299 }
5300 
5301 /*	To set the WFD session available to enable or disable */
5302 static int rtw_p2p_set_sa(struct net_device *dev,
5303 			  struct iw_request_info *info,
5304 			  union iwreq_data *wrqu, char *extra)
5305 {
5306 
5307 	int ret = 0;
5308 	_adapter					*padapter = (_adapter *)rtw_netdev_priv(dev);
5309 	struct wifidirect_info		*pwdinfo = &(padapter->wdinfo);
5310 
5311 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5312 
5313 	if (0) {
5314 		RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5315 		return ret;
5316 	} else {
5317 		if (extra[0] == '0')	/*	Disable the session available. */
5318 			pwdinfo->session_available = _FALSE;
5319 		else if (extra[0] == '1')	/*	Enable the session available. */
5320 			pwdinfo->session_available = _TRUE;
5321 		else
5322 			pwdinfo->session_available = _FALSE;
5323 	}
5324 	printk("[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available);
5325 
5326 	return ret;
5327 
5328 }
5329 #endif /* CONFIG_WFD */
5330 
5331 static int rtw_p2p_prov_disc(struct net_device *dev,
5332 			     struct iw_request_info *info,
5333 			     union iwreq_data *wrqu, char *extra)
5334 {
5335 	int ret = 0;
5336 	_adapter				*padapter = (_adapter *)rtw_netdev_priv(dev);
5337 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5338 	u8					peerMAC[ETH_ALEN] = { 0x00 };
5339 	int					jj, kk;
5340 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
5341 	_list					*plist, *phead;
5342 	_queue				*queue	= &(pmlmepriv->scanned_queue);
5343 	struct	wlan_network	*pnetwork = NULL;
5344 	uint					uintPeerChannel = 0;
5345 	u8					attr_content[100] = { 0x00 };
5346 	u8 *p2pie;
5347 	uint					p2pielen = 0, attr_contentlen = 100;
5348 	_irqL				irqL;
5349 #ifdef CONFIG_CONCURRENT_MODE
5350 	struct roch_info 		*prochinfo = &padapter->rochinfo;
5351 #endif
5352 
5353 	/*	Commented by Albert 20110301 */
5354 	/*	The input data contains two informations. */
5355 	/*	1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
5356 	/*	2. Second information is the WPS configuration method which wants to discovery */
5357 	/*	Format: 00:E0:4C:00:00:05_display */
5358 	/*	Format: 00:E0:4C:00:00:05_keypad */
5359 	/*	Format: 00:E0:4C:00:00:05_pbc */
5360 	/*	Format: 00:E0:4C:00:00:05_label */
5361 
5362 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5363 
5364 	if (pwdinfo->p2p_state == P2P_STATE_NONE) {
5365 		RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5366 		return ret;
5367 	} else {
5368 		/*	Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
5369 		_rtw_memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
5370 		_rtw_memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
5371 		_rtw_memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(NDIS_802_11_SSID));
5372 		pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
5373 		pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
5374 		pwdinfo->tx_prov_disc_info.benable = _FALSE;
5375 	}
5376 
5377 	for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5378 		peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5379 
5380 	if (_rtw_memcmp(&extra[18], "display", 7))
5381 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
5382 	else if (_rtw_memcmp(&extra[18], "keypad", 7))
5383 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
5384 	else if (_rtw_memcmp(&extra[18], "pbc", 3))
5385 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
5386 	else if (_rtw_memcmp(&extra[18], "label", 5))
5387 		pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
5388 	else {
5389 		RTW_INFO("[%s] Unknown WPS config methodn", __FUNCTION__);
5390 		return ret ;
5391 	}
5392 
5393 	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5394 
5395 	phead = get_list_head(queue);
5396 	plist = get_next(phead);
5397 
5398 	while (1) {
5399 		if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5400 			break;
5401 
5402 		if (uintPeerChannel != 0)
5403 			break;
5404 
5405 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5406 
5407 		/*	Commented by Albert 2011/05/18 */
5408 		/*	Match the device address located in the P2P IE */
5409 		/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
5410 
5411 		p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5412 		if (p2pie) {
5413 			while (p2pie) {
5414 				/*	The P2P Device ID attribute is included in the Beacon frame. */
5415 				/*	The P2P Device Info attribute is included in the probe response frame. */
5416 				attr_contentlen = sizeof(attr_content);
5417 				if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5418 					/*	Handle the P2P Device ID attribute of Beacon first */
5419 					if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5420 						uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5421 						break;
5422 					}
5423 				} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5424 					/*	Handle the P2P Device Info attribute of probe response */
5425 					if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5426 						uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5427 						break;
5428 					}
5429 				}
5430 
5431 				/* Get the next P2P IE */
5432 				p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5433 			}
5434 
5435 		}
5436 
5437 		plist = get_next(plist);
5438 
5439 	}
5440 
5441 	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5442 
5443 	if (uintPeerChannel) {
5444 #ifdef CONFIG_WFD
5445 		if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5446 			struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5447 			u8 *wfd_ie;
5448 			uint wfd_ielen = 0;
5449 
5450 			wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5451 			if (wfd_ie) {
5452 				u8 *wfd_devinfo;
5453 				uint wfd_devlen;
5454 
5455 				RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5456 				wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5457 				if (wfd_devinfo) {
5458 					u16	wfd_devinfo_field = 0;
5459 
5460 					/*	Commented by Albert 20120319 */
5461 					/*	The first two bytes are the WFD device information field of WFD device information subelement. */
5462 					/*	In big endian format. */
5463 					wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5464 					if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
5465 						pwfd_info->peer_session_avail = _TRUE;
5466 					else
5467 						pwfd_info->peer_session_avail = _FALSE;
5468 				}
5469 			}
5470 
5471 			if (_FALSE == pwfd_info->peer_session_avail) {
5472 				RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
5473 				goto exit;
5474 			}
5475 		}
5476 #endif /* CONFIG_WFD */
5477 
5478 		RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel);
5479 #ifdef CONFIG_CONCURRENT_MODE
5480 		if (rtw_mi_check_status(padapter, MI_LINKED))
5481 			_cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
5482 #endif /* CONFIG_CONCURRENT_MODE */
5483 		_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
5484 		_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
5485 		pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16) uintPeerChannel;
5486 		pwdinfo->tx_prov_disc_info.benable = _TRUE;
5487 		rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5488 		rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
5489 
5490 		if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
5491 			_rtw_memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));
5492 		else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5493 			_rtw_memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
5494 			pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
5495 		}
5496 
5497 #ifdef CONFIG_CONCURRENT_MODE
5498 		if (rtw_mi_check_status(padapter, MI_LINKED)) {
5499 			u8 union_ch = rtw_mi_get_union_chan(padapter);
5500 			u8 union_bw = rtw_mi_get_union_bw(padapter);
5501 			u8 union_offset = rtw_mi_get_union_offset(padapter);
5502 
5503 			set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5504 			rtw_leave_opch(padapter);
5505 
5506 		} else
5507 			set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5508 #else
5509 		set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5510 #endif
5511 
5512 		_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5513 
5514 #ifdef CONFIG_CONCURRENT_MODE
5515 		if (rtw_mi_check_status(padapter, MI_LINKED))
5516 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT);
5517 		else
5518 			_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
5519 #else
5520 		_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
5521 #endif /* CONFIG_CONCURRENT_MODE		 */
5522 
5523 	} else {
5524 		RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5525 	}
5526 exit:
5527 
5528 	return ret;
5529 
5530 }
5531 
5532 /*	Added by Albert 20110328
5533  *	This function is used to inform the driver the user had specified the pin code value or pbc
5534  *	to application. */
5535 
5536 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
5537 			       struct iw_request_info *info,
5538 			       union iwreq_data *wrqu, char *extra)
5539 {
5540 
5541 	int ret = 0;
5542 	_adapter				*padapter = (_adapter *)rtw_netdev_priv(dev);
5543 	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
5544 
5545 
5546 	RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5547 	/*	Added by Albert 20110328 */
5548 	/*	if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
5549 	/*	if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
5550 	/*	if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
5551 	/*	if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
5552 
5553 	if (*extra == '0')
5554 		pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5555 	else if (*extra == '1')
5556 		pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
5557 	else if (*extra == '2')
5558 		pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
5559 	else if (*extra == '3')
5560 		pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
5561 	else
5562 		pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5563 
5564 	return ret;
5565 
5566 }
5567 
5568 #endif /* CONFIG_P2P */
5569 
5570 static int rtw_p2p_set(struct net_device *dev,
5571 		       struct iw_request_info *info,
5572 		       union iwreq_data *wrqu, char *extra)
5573 {
5574 	int ret = 0;
5575 #ifdef CONFIG_P2P
5576 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5577 
5578 	RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
5579 
5580 	if (_rtw_memcmp(extra, "enable=", 7))
5581 		rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
5582 	else if (_rtw_memcmp(extra, "setDN=", 6)) {
5583 		wrqu->data.length -= 6;
5584 		rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
5585 	} else if (_rtw_memcmp(extra, "profilefound=", 13)) {
5586 		wrqu->data.length -= 13;
5587 		rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
5588 	} else if (_rtw_memcmp(extra, "prov_disc=", 10)) {
5589 		wrqu->data.length -= 10;
5590 		rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
5591 	} else if (_rtw_memcmp(extra, "nego=", 5)) {
5592 		wrqu->data.length -= 5;
5593 		rtw_p2p_connect(dev, info, wrqu, &extra[5]);
5594 	} else if (_rtw_memcmp(extra, "intent=", 7)) {
5595 		/*	Commented by Albert 2011/03/23 */
5596 		/*	The wrqu->data.length will include the null character */
5597 		/*	So, we will decrease 7 + 1 */
5598 		wrqu->data.length -= 8;
5599 		rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
5600 	} else if (_rtw_memcmp(extra, "ssid=", 5)) {
5601 		wrqu->data.length -= 5;
5602 		rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
5603 	} else if (_rtw_memcmp(extra, "got_wpsinfo=", 12)) {
5604 		wrqu->data.length -= 12;
5605 		rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
5606 	} else if (_rtw_memcmp(extra, "listen_ch=", 10)) {
5607 		/*	Commented by Albert 2011/05/24 */
5608 		/*	The wrqu->data.length will include the null character */
5609 		/*	So, we will decrease (10 + 1)	 */
5610 		wrqu->data.length -= 11;
5611 		rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
5612 	} else if (_rtw_memcmp(extra, "op_ch=", 6)) {
5613 		/*	Commented by Albert 2011/05/24 */
5614 		/*	The wrqu->data.length will include the null character */
5615 		/*	So, we will decrease (6 + 1)	 */
5616 		wrqu->data.length -= 7;
5617 		rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
5618 	} else if (_rtw_memcmp(extra, "invite=", 7)) {
5619 		wrqu->data.length -= 8;
5620 		rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
5621 	} else if (_rtw_memcmp(extra, "persistent=", 11)) {
5622 		wrqu->data.length -= 11;
5623 		rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
5624 	} else if (_rtw_memcmp(extra, "uuid=", 5)) {
5625 		wrqu->data.length -= 5;
5626 		ret = rtw_p2p_set_wps_uuid(dev, info, wrqu, &extra[5]);
5627 	}
5628 
5629 #ifdef CONFIG_WFD
5630 	if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5631 		if (_rtw_memcmp(extra, "sa=", 3)) {
5632 			/* sa: WFD Session Available information */
5633 			wrqu->data.length -= 3;
5634 			rtw_p2p_set_sa(dev, info, wrqu, &extra[3]);
5635 		} else if (_rtw_memcmp(extra, "pc=", 3)) {
5636 			/* pc: WFD Preferred Connection */
5637 			wrqu->data.length -= 3;
5638 			rtw_p2p_set_pc(dev, info, wrqu, &extra[3]);
5639 		} else if (_rtw_memcmp(extra, "wfd_type=", 9)) {
5640 			wrqu->data.length -= 9;
5641 			rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]);
5642 		} else if (_rtw_memcmp(extra, "wfd_enable=", 11)) {
5643 			wrqu->data.length -= 11;
5644 			rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]);
5645 		} else if (_rtw_memcmp(extra, "driver_iface=", 13)) {
5646 			wrqu->data.length -= 13;
5647 			rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]);
5648 		}
5649 	}
5650 #endif /* CONFIG_WFD */
5651 
5652 #endif /* CONFIG_P2P */
5653 
5654 	return ret;
5655 
5656 }
5657 
5658 static int rtw_p2p_get(struct net_device *dev,
5659 		       struct iw_request_info *info,
5660 		       union iwreq_data *wrqu, char *extra)
5661 {
5662 	int ret = 0;
5663 #ifdef CONFIG_P2P
5664 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5665 
5666 	if (padapter->bShowGetP2PState)
5667 		RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
5668 
5669 	if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
5670 		rtw_p2p_get_status(dev, info, wrqu, extra);
5671 	else if (_rtw_memcmp(wrqu->data.pointer, "role", 4))
5672 		rtw_p2p_get_role(dev, info, wrqu, extra);
5673 	else if (_rtw_memcmp(wrqu->data.pointer, "peer_ifa", 8))
5674 		rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
5675 	else if (_rtw_memcmp(wrqu->data.pointer, "req_cm", 6))
5676 		rtw_p2p_get_req_cm(dev, info, wrqu, extra);
5677 	else if (_rtw_memcmp(wrqu->data.pointer, "peer_deva", 9)) {
5678 		/*	Get the P2P device address when receiving the provision discovery request frame. */
5679 		rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
5680 	} else if (_rtw_memcmp(wrqu->data.pointer, "group_id", 8))
5681 		rtw_p2p_get_groupid(dev, info, wrqu, extra);
5682 	else if (_rtw_memcmp(wrqu->data.pointer, "inv_peer_deva", 13)) {
5683 		/*	Get the P2P device address when receiving the P2P Invitation request frame. */
5684 		rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
5685 	} else if (_rtw_memcmp(wrqu->data.pointer, "op_ch", 5))
5686 		rtw_p2p_get_op_ch(dev, info, wrqu, extra);
5687 
5688 #ifdef CONFIG_WFD
5689 	if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5690 		if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9))
5691 			rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra);
5692 		else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6))
5693 			rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra);
5694 		else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6))
5695 			rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra);
5696 	}
5697 #endif /* CONFIG_WFD */
5698 
5699 #endif /* CONFIG_P2P */
5700 
5701 	return ret;
5702 
5703 }
5704 
5705 static int rtw_p2p_get2(struct net_device *dev,
5706 			struct iw_request_info *info,
5707 			union iwreq_data *wrqu, char *extra)
5708 {
5709 
5710 	int ret = 0;
5711 
5712 #ifdef CONFIG_P2P
5713 
5714 	int length = wrqu->data.length;
5715 	char *buffer = (u8 *)rtw_malloc(length);
5716 
5717 	if (buffer == NULL) {
5718 		ret = -ENOMEM;
5719 		goto bad;
5720 	}
5721 
5722 	if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) {
5723 		ret = -EFAULT;
5724 		goto bad;
5725 	}
5726 
5727 	RTW_INFO("[%s] buffer = %s\n", __FUNCTION__, buffer);
5728 
5729 	if (_rtw_memcmp(buffer, "wpsCM=", 6))
5730 		ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
5731 	else if (_rtw_memcmp(buffer, "devN=", 5))
5732 		ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
5733 	else if (_rtw_memcmp(buffer, "dev_type=", 9))
5734 		ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
5735 	else if (_rtw_memcmp(buffer, "go_devadd=", 10))
5736 		ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
5737 	else if (_rtw_memcmp(buffer, "InvProc=", 8))
5738 		ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
5739 	else {
5740 		snprintf(extra, sizeof("Command not found."), "Command not found.");
5741 		wrqu->data.length = strlen(extra);
5742 	}
5743 
5744 bad:
5745 	if (buffer)
5746 		rtw_mfree(buffer, length);
5747 
5748 #endif /* CONFIG_P2P */
5749 
5750 	return ret;
5751 
5752 }
5753 
5754 #ifdef CONFIG_MP_INCLUDED
5755 static int rtw_cta_test_start(struct net_device *dev,
5756 			      struct iw_request_info *info,
5757 			      union iwreq_data *wrqu, char *extra)
5758 {
5759 	int ret = 0;
5760 	_adapter	*padapter = (_adapter *)rtw_netdev_priv(dev);
5761 	HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
5762 
5763 	RTW_INFO("%s %s\n", __func__, extra);
5764 	if (!strcmp(extra, "1"))
5765 		hal_data->in_cta_test = 1;
5766 	else
5767 		hal_data->in_cta_test = 0;
5768 
5769 	rtw_hal_rcr_set_chk_bssid(padapter, MLME_ACTION_NONE);
5770 
5771 	return ret;
5772 }
5773 #endif
5774 
5775 #ifdef CONFIG_IOL
5776 #include <rtw_iol.h>
5777 #endif
5778 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
5779 #include "../../hal/hal_dm_acs.h"
5780 #endif
5781 #ifdef DBG_CMD_QUEUE
5782 u8 dump_cmd_id = 0;
5783 #endif
5784 
5785 static int rtw_dbg_port(struct net_device *dev,
5786 			struct iw_request_info *info,
5787 			union iwreq_data *wrqu, char *extra)
5788 {
5789 	int ret = 0;
5790 #ifdef CONFIG_RTW_DEBUG
5791 	_irqL irqL;
5792 	u8 major_cmd, minor_cmd;
5793 	u16 arg;
5794 	u32 extra_arg, *pdata, val32;
5795 	struct sta_info *psta;
5796 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5797 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5798 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
5799 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
5800 	struct security_priv *psecuritypriv = &padapter->securitypriv;
5801 	struct wlan_network *cur_network = &(pmlmepriv->cur_network);
5802 	struct sta_priv *pstapriv = &padapter->stapriv;
5803 
5804 
5805 	pdata = (u32 *)&wrqu->data;
5806 
5807 	val32 = *pdata;
5808 	arg = (u16)(val32 & 0x0000ffff);
5809 	major_cmd = (u8)(val32 >> 24);
5810 	minor_cmd = (u8)((val32 >> 16) & 0x00ff);
5811 
5812 	extra_arg = *(pdata + 1);
5813 
5814 	switch (major_cmd) {
5815 	case 0x70: /* read_reg */
5816 		switch (minor_cmd) {
5817 		case 1:
5818 			RTW_INFO("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5819 			break;
5820 		case 2:
5821 			RTW_INFO("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5822 			break;
5823 		case 4:
5824 			RTW_INFO("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5825 			break;
5826 		}
5827 		break;
5828 	case 0x71: /* write_reg */
5829 		switch (minor_cmd) {
5830 		case 1:
5831 			rtw_write8(padapter, arg, extra_arg);
5832 			RTW_INFO("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5833 			break;
5834 		case 2:
5835 			rtw_write16(padapter, arg, extra_arg);
5836 			RTW_INFO("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5837 			break;
5838 		case 4:
5839 			rtw_write32(padapter, arg, extra_arg);
5840 			RTW_INFO("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5841 			break;
5842 		}
5843 		break;
5844 	case 0x72: /* read_bb */
5845 		RTW_INFO("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5846 		break;
5847 	case 0x73: /* write_bb */
5848 		rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
5849 		RTW_INFO("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5850 		break;
5851 	case 0x74: /* read_rf */
5852 		RTW_INFO("read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
5853 		break;
5854 	case 0x75: /* write_rf */
5855 		rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
5856 		RTW_INFO("write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
5857 		break;
5858 
5859 	case 0x76:
5860 		switch (minor_cmd) {
5861 		case 0x00: /* normal mode, */
5862 			padapter->recvpriv.is_signal_dbg = 0;
5863 			break;
5864 		case 0x01: /* dbg mode */
5865 			padapter->recvpriv.is_signal_dbg = 1;
5866 			extra_arg = extra_arg > 100 ? 100 : extra_arg;
5867 			padapter->recvpriv.signal_strength_dbg = extra_arg;
5868 			break;
5869 		}
5870 		break;
5871 	case 0x78: /* IOL test */
5872 		switch (minor_cmd) {
5873 		#ifdef CONFIG_IOL
5874 		case 0x04: { /* LLT table initialization test */
5875 			u8 page_boundary = 0xf9;
5876 			{
5877 				struct xmit_frame	*xmit_frame;
5878 
5879 				xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5880 				if (xmit_frame == NULL) {
5881 					ret = -ENOMEM;
5882 					break;
5883 				}
5884 
5885 				rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
5886 
5887 
5888 				if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))
5889 					ret = -EPERM;
5890 			}
5891 		}
5892 			break;
5893 		case 0x05: { /* blink LED test */
5894 			u16 reg = 0x4c;
5895 			u32 blink_num = 50;
5896 			u32 blink_delay_ms = 200;
5897 			int i;
5898 
5899 			{
5900 				struct xmit_frame	*xmit_frame;
5901 
5902 				xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5903 				if (xmit_frame == NULL) {
5904 					ret = -ENOMEM;
5905 					break;
5906 				}
5907 
5908 				for (i = 0; i < blink_num; i++) {
5909 					#ifdef CONFIG_IOL_NEW_GENERATION
5910 					rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
5911 					rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5912 					rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
5913 					rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5914 					#else
5915 					rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
5916 					rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5917 					rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
5918 					rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5919 					#endif
5920 				}
5921 				if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0))
5922 					ret = -EPERM;
5923 			}
5924 		}
5925 			break;
5926 
5927 		case 0x06: { /* continuous wirte byte test */
5928 			u16 reg = arg;
5929 			u16 start_value = 0;
5930 			u32 write_num = extra_arg;
5931 			int i;
5932 			u8 final;
5933 
5934 			{
5935 				struct xmit_frame	*xmit_frame;
5936 
5937 				xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5938 				if (xmit_frame == NULL) {
5939 					ret = -ENOMEM;
5940 					break;
5941 				}
5942 
5943 				for (i = 0; i < write_num; i++) {
5944 					#ifdef CONFIG_IOL_NEW_GENERATION
5945 					rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
5946 					#else
5947 					rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value);
5948 					#endif
5949 				}
5950 				if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
5951 					ret = -EPERM;
5952 			}
5953 
5954 			final = rtw_read8(padapter, reg);
5955 			if (start_value + write_num - 1 == final)
5956 				RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
5957 			else
5958 				RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
5959 		}
5960 			break;
5961 
5962 		case 0x07: { /* continuous wirte word test */
5963 			u16 reg = arg;
5964 			u16 start_value = 200;
5965 			u32 write_num = extra_arg;
5966 
5967 			int i;
5968 			u16 final;
5969 
5970 			{
5971 				struct xmit_frame	*xmit_frame;
5972 
5973 				xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5974 				if (xmit_frame == NULL) {
5975 					ret = -ENOMEM;
5976 					break;
5977 				}
5978 
5979 				for (i = 0; i < write_num; i++) {
5980 					#ifdef CONFIG_IOL_NEW_GENERATION
5981 					rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
5982 					#else
5983 					rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value);
5984 					#endif
5985 				}
5986 				if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
5987 					ret = -EPERM;
5988 			}
5989 
5990 			final = rtw_read16(padapter, reg);
5991 			if (start_value + write_num - 1 == final)
5992 				RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
5993 			else
5994 				RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
5995 		}
5996 			break;
5997 
5998 		case 0x08: { /* continuous wirte dword test */
5999 			u16 reg = arg;
6000 			u32 start_value = 0x110000c7;
6001 			u32 write_num = extra_arg;
6002 
6003 			int i;
6004 			u32 final;
6005 
6006 			{
6007 				struct xmit_frame	*xmit_frame;
6008 
6009 				xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6010 				if (xmit_frame == NULL) {
6011 					ret = -ENOMEM;
6012 					break;
6013 				}
6014 
6015 				for (i = 0; i < write_num; i++) {
6016 					#ifdef CONFIG_IOL_NEW_GENERATION
6017 					rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
6018 					#else
6019 					rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value);
6020 					#endif
6021 				}
6022 				if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6023 					ret = -EPERM;
6024 
6025 			}
6026 
6027 			final = rtw_read32(padapter, reg);
6028 			if (start_value + write_num - 1 == final)
6029 				RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6030 			else
6031 				RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6032 		}
6033 			break;
6034 		#endif /* CONFIG_IOL */
6035 		}
6036 		break;
6037 	case 0x79: {
6038 		/*
6039 		* dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
6040 		* dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
6041 		*/
6042 		u8 value =  extra_arg & 0x0f;
6043 		u8 sign = minor_cmd;
6044 		u16 write_value = 0;
6045 
6046 		RTW_INFO("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
6047 
6048 		if (sign)
6049 			value = value | 0x10;
6050 
6051 		write_value = value | (value << 5);
6052 		rtw_write16(padapter, 0x6d9, write_value);
6053 	}
6054 		break;
6055 	case 0x7a:
6056 		receive_disconnect(padapter, pmlmeinfo->network.MacAddress
6057 				   , WLAN_REASON_EXPIRATION_CHK, _FALSE);
6058 		break;
6059 	case 0x7F:
6060 		switch (minor_cmd) {
6061 		case 0x0:
6062 			RTW_INFO("fwstate=0x%x\n", get_fwstate(pmlmepriv));
6063 			break;
6064 		case 0x01:
6065 			RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
6066 				psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
6067 				psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
6068 			break;
6069 		case 0x03:
6070 			RTW_INFO("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
6071 #ifdef CONFIG_80211N_HT
6072 			RTW_INFO("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
6073 #endif /* CONFIG_80211N_HT */
6074 			break;
6075 		case 0x04:
6076 			RTW_INFO("cur_ch=%d\n", pmlmeext->cur_channel);
6077 			RTW_INFO("cur_bw=%d\n", pmlmeext->cur_bwmode);
6078 			RTW_INFO("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
6079 
6080 			RTW_INFO("oper_ch=%d\n", rtw_get_oper_ch(padapter));
6081 			RTW_INFO("oper_bw=%d\n", rtw_get_oper_bw(padapter));
6082 			RTW_INFO("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
6083 
6084 			break;
6085 		case 0x05:
6086 			psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
6087 			if (psta) {
6088 				RTW_INFO("SSID=%s\n", cur_network->network.Ssid.Ssid);
6089 				RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
6090 				RTW_INFO("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
6091 				RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6092 				RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",
6093 					psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);
6094 #ifdef CONFIG_80211N_HT
6095 				RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6096 				RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n"
6097 					, psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
6098 				RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6099 				RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6100 #endif /* CONFIG_80211N_HT */
6101 
6102 				sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6103 			} else
6104 				RTW_INFO("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
6105 			break;
6106 		case 0x06: {
6107 				u64 tsf = 0;
6108 
6109 				tsf = rtw_hal_get_tsftr_by_port(padapter, extra_arg);
6110 				RTW_INFO(" PORT-%d TSF :%21lld\n", extra_arg, tsf);
6111 		}
6112 			break;
6113 		case 0x07:
6114 			RTW_INFO("bSurpriseRemoved=%s, bDriverStopped=%s\n"
6115 				, rtw_is_surprise_removed(padapter) ? "True" : "False"
6116 				, rtw_is_drv_stopped(padapter) ? "True" : "False");
6117 			break;
6118 		case 0x08: {
6119 			struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6120 			struct recv_priv  *precvpriv = &padapter->recvpriv;
6121 
6122 			RTW_INFO("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
6123 				", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
6124 				 ", free_recvframe_cnt=%d\n",
6125 				pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
6126 				pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
6127 				 precvpriv->free_recvframe_cnt);
6128 #ifdef CONFIG_USB_HCI
6129 			RTW_INFO("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt)));
6130 #endif
6131 		}
6132 			break;
6133 		case 0x09: {
6134 			int i;
6135 			_list	*plist, *phead;
6136 
6137 #ifdef CONFIG_AP_MODE
6138 			RTW_INFO_DUMP("sta_dz_bitmap:", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len);
6139 			RTW_INFO_DUMP("tim_bitmap:", pstapriv->tim_bitmap, pstapriv->aid_bmp_len);
6140 #endif
6141 			_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6142 
6143 			for (i = 0; i < NUM_STA; i++) {
6144 				phead = &(pstapriv->sta_hash[i]);
6145 				plist = get_next(phead);
6146 
6147 				while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
6148 					psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
6149 
6150 					plist = get_next(plist);
6151 
6152 					if (extra_arg == psta->cmn.aid) {
6153 						RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
6154 						RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6155 						RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",
6156 							psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);
6157 #ifdef CONFIG_80211N_HT
6158 						RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6159 						RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n",
6160 							psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m,
6161 							psta->htpriv.sgi_40m);
6162 						RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6163 						RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6164 #endif /* CONFIG_80211N_HT */
6165 
6166 #ifdef CONFIG_AP_MODE
6167 						RTW_INFO("capability=0x%x\n", psta->capability);
6168 						RTW_INFO("flags=0x%x\n", psta->flags);
6169 						RTW_INFO("wpa_psk=0x%x\n", psta->wpa_psk);
6170 						RTW_INFO("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
6171 						RTW_INFO("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
6172 						RTW_INFO("qos_info=0x%x\n", psta->qos_info);
6173 #endif
6174 						RTW_INFO("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
6175 
6176 						sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6177 					}
6178 
6179 				}
6180 			}
6181 
6182 			_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6183 
6184 		}
6185 			break;
6186 
6187 		case 0x0b: { /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6188 			/* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6189 			/* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
6190 
6191 			if (arg == 0) {
6192 				RTW_INFO("disable driver ctrl vcs\n");
6193 				padapter->driver_vcs_en = 0;
6194 			} else if (arg == 1) {
6195 				RTW_INFO("enable driver ctrl vcs = %d\n", extra_arg);
6196 				padapter->driver_vcs_en = 1;
6197 
6198 				if (extra_arg > 2)
6199 					padapter->driver_vcs_type = 1;
6200 				else
6201 					padapter->driver_vcs_type = extra_arg;
6202 			}
6203 		}
6204 			break;
6205 		case 0x0c: { /* dump rx/tx packet */
6206 			if (arg == 0) {
6207 				RTW_INFO("dump rx packet (%d)\n", extra_arg);
6208 				/* pHalData->bDumpRxPkt =extra_arg;						 */
6209 				rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
6210 			} else if (arg == 1) {
6211 				RTW_INFO("dump tx packet (%d)\n", extra_arg);
6212 				rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
6213 			}
6214 		}
6215 			break;
6216 		case 0x0e: {
6217 			if (arg == 0) {
6218 				RTW_INFO("disable driver ctrl rx_ampdu_factor\n");
6219 				padapter->driver_rx_ampdu_factor = 0xFF;
6220 			} else if (arg == 1) {
6221 
6222 				RTW_INFO("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
6223 
6224 				if (extra_arg > 0x03)
6225 					padapter->driver_rx_ampdu_factor = 0xFF;
6226 				else
6227 					padapter->driver_rx_ampdu_factor = extra_arg;
6228 			}
6229 		}
6230 			break;
6231 		#ifdef DBG_CONFIG_ERROR_DETECT
6232 		case 0x0f: {
6233 			if (extra_arg == 0) {
6234 				RTW_INFO("###### silent reset test.......#####\n");
6235 				rtw_hal_sreset_reset(padapter);
6236 			} else {
6237 				HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
6238 				struct sreset_priv *psrtpriv = &pHalData->srestpriv;
6239 				psrtpriv->dbg_trigger_point = extra_arg;
6240 			}
6241 
6242 		}
6243 			break;
6244 		case 0x15: {
6245 			struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6246 			RTW_INFO("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
6247 		}
6248 			break;
6249 
6250 		#endif
6251 
6252 		case 0x10: /* driver version display */
6253 			dump_drv_version(RTW_DBGDUMP);
6254 			break;
6255 		case 0x11: { /* dump linked status */
6256 			int pre_mode;
6257 			pre_mode = padapter->bLinkInfoDump;
6258 			/* linked_info_dump(padapter,extra_arg); */
6259 			if (extra_arg == 1 || (extra_arg == 0 && pre_mode == 1)) /* not consider pwr_saving 0: */
6260 				padapter->bLinkInfoDump = extra_arg;
6261 
6262 			else if ((extra_arg == 2) || (extra_arg == 0 && pre_mode == 2)) { /* consider power_saving */
6263 				/* RTW_INFO("linked_info_dump =%s\n", (padapter->bLinkInfoDump)?"enable":"disable") */
6264 				linked_info_dump(padapter, extra_arg);
6265 			}
6266 
6267 
6268 
6269 		}
6270 			break;
6271 #ifdef CONFIG_80211N_HT
6272 		case 0x12: { /* set rx_stbc */
6273 			struct registry_priv	*pregpriv = &padapter->registrypriv;
6274 			/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
6275 			/* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
6276 			if (pregpriv && (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3)) {
6277 				pregpriv->rx_stbc = extra_arg;
6278 				RTW_INFO("set rx_stbc=%d\n", pregpriv->rx_stbc);
6279 			} else
6280 				RTW_INFO("get rx_stbc=%d\n", pregpriv->rx_stbc);
6281 
6282 		}
6283 			break;
6284 		case 0x13: { /* set ampdu_enable */
6285 			struct registry_priv	*pregpriv = &padapter->registrypriv;
6286 			/* 0: disable, 0x1:enable */
6287 			if (pregpriv && extra_arg < 2) {
6288 				pregpriv->ampdu_enable = extra_arg;
6289 				RTW_INFO("set ampdu_enable=%d\n", pregpriv->ampdu_enable);
6290 			} else
6291 				RTW_INFO("get ampdu_enable=%d\n", pregpriv->ampdu_enable);
6292 
6293 		}
6294 			break;
6295 #endif
6296 		case 0x14: { /* get wifi_spec */
6297 			struct registry_priv	*pregpriv = &padapter->registrypriv;
6298 			RTW_INFO("get wifi_spec=%d\n", pregpriv->wifi_spec);
6299 
6300 		}
6301 			break;
6302 
6303 #ifdef DBG_FIXED_CHAN
6304 		case 0x17: {
6305 			struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
6306 			printk("===>  Fixed channel to %d\n", extra_arg);
6307 			pmlmeext->fixed_chan = extra_arg;
6308 
6309 		}
6310 			break;
6311 #endif
6312 #ifdef CONFIG_80211N_HT
6313 		case 0x19: {
6314 			struct registry_priv	*pregistrypriv = &padapter->registrypriv;
6315 			/* extra_arg : */
6316 			/* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */
6317 			/* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */
6318 			if (arg == 0) {
6319 				RTW_INFO("driver disable LDPC\n");
6320 				pregistrypriv->ldpc_cap = 0x00;
6321 			} else if (arg == 1) {
6322 				RTW_INFO("driver set LDPC cap = 0x%x\n", extra_arg);
6323 				pregistrypriv->ldpc_cap = (u8)(extra_arg & 0x33);
6324 			}
6325 		}
6326 			break;
6327 		case 0x1a: {
6328 			struct registry_priv	*pregistrypriv = &padapter->registrypriv;
6329 			/* extra_arg : */
6330 			/* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */
6331 			/* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */
6332 			if (arg == 0) {
6333 				RTW_INFO("driver disable STBC\n");
6334 				pregistrypriv->stbc_cap = 0x00;
6335 			} else if (arg == 1) {
6336 				RTW_INFO("driver set STBC cap = 0x%x\n", extra_arg);
6337 				pregistrypriv->stbc_cap = (u8)(extra_arg & 0x33);
6338 			}
6339 		}
6340 			break;
6341 #endif /* CONFIG_80211N_HT */
6342 		case 0x1b: {
6343 			struct registry_priv	*pregistrypriv = &padapter->registrypriv;
6344 
6345 			if (arg == 0) {
6346 				RTW_INFO("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
6347 				init_mlme_default_rate_set(padapter);
6348 #ifdef CONFIG_80211N_HT
6349 				pregistrypriv->ht_enable = (u8)rtw_ht_enable;
6350 #endif /* CONFIG_80211N_HT */
6351 			} else if (arg == 1) {
6352 
6353 				int i;
6354 				u8 max_rx_rate;
6355 
6356 				RTW_INFO("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
6357 
6358 				max_rx_rate = (u8)extra_arg;
6359 
6360 				if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0->B or G -> disable HT */
6361 #ifdef CONFIG_80211N_HT
6362 					pregistrypriv->ht_enable = 0;
6363 #endif /* CONFIG_80211N_HT */
6364 					for (i = 0; i < NumRates; i++) {
6365 						if (pmlmeext->datarate[i] > max_rx_rate)
6366 							pmlmeext->datarate[i] = 0xff;
6367 					}
6368 
6369 				}
6370 #ifdef CONFIG_80211N_HT
6371 				else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */
6372 					u32 mcs_bitmap = 0x0;
6373 
6374 					for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++)
6375 						mcs_bitmap |= BIT(i);
6376 
6377 					set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
6378 				}
6379 #endif /* CONFIG_80211N_HT							 */
6380 			}
6381 		}
6382 			break;
6383 		case 0x1c: { /* enable/disable driver control AMPDU Density for peer sta's rx */
6384 			if (arg == 0) {
6385 				RTW_INFO("disable driver ctrl ampdu density\n");
6386 				padapter->driver_ampdu_spacing = 0xFF;
6387 			} else if (arg == 1) {
6388 
6389 				RTW_INFO("enable driver ctrl ampdu density = %d\n", extra_arg);
6390 
6391 				if (extra_arg > 0x07)
6392 					padapter->driver_ampdu_spacing = 0xFF;
6393 				else
6394 					padapter->driver_ampdu_spacing = extra_arg;
6395 			}
6396 		}
6397 			break;
6398 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
6399 		case 0x1e: {
6400 			RTW_INFO("===========================================\n");
6401 			rtw_noise_measure_curchan(padapter);
6402 			RTW_INFO("===========================================\n");
6403 		}
6404 			break;
6405 #endif
6406 
6407 
6408 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)
6409 		case 0x1f:
6410 			{
6411 				int i, j = 0, test_cnts = 0;
6412 				static u8 test_code = 0x5A;
6413 				static u32 data_misatch_cnt = 0, d_acc_err_cnt = 0;
6414 
6415 				u32 d_data, i_data;
6416 				u32 imr;
6417 
6418 				test_cnts = extra_arg;
6419 				for (i = 0; i < test_cnts; i++) {
6420 					if (RTW_CANNOT_IO(padapter))
6421 						break;
6422 
6423 					rtw_write8(padapter, 0x07, test_code);
6424 
6425 					d_data = rtw_read32(padapter, 0x04);
6426 					imr =  rtw_read32(padapter, 0x10250014);
6427 					rtw_write32(padapter, 0x10250014, 0);
6428 					rtw_msleep_os(50);
6429 
6430 					i_data = rtw_sd_iread32(padapter, 0x04);
6431 
6432 					rtw_write32(padapter, 0x10250014, imr);
6433 
6434 					if (d_data != i_data) {
6435 						data_misatch_cnt++;
6436 						RTW_ERR("d_data :0x%08x, i_data : 0x%08x\n", d_data, i_data);
6437 					}
6438 
6439 					if (test_code != (i_data >> 24)) {
6440 						d_acc_err_cnt++;
6441 						rtw_write8(padapter, 0x07, 0xAA);
6442 						RTW_ERR("test_code :0x%02x, i_data : 0x%08x\n", test_code, i_data);
6443 					}
6444 					if ((j++) == 100) {
6445 						rtw_msleep_os(2000);
6446 						RTW_INFO(" Indirect access testing..........%d/%d\n", i, test_cnts);
6447 						j = 0;
6448 					}
6449 
6450 					test_code = ~test_code;
6451 					rtw_msleep_os(50);
6452 				}
6453 				RTW_INFO("========Indirect access test=========\n");
6454 				RTW_INFO(" test_cnts = %d\n", test_cnts);
6455 				RTW_INFO(" direct & indirect read32 data missatch cnts = %d\n", data_misatch_cnt);
6456 				RTW_INFO(" indirect rdata is not equal to wdata cnts = %d\n", d_acc_err_cnt);
6457 				RTW_INFO("========Indirect access test=========\n\n");
6458 				data_misatch_cnt = d_acc_err_cnt = 0;
6459 
6460 			}
6461 			break;
6462 #endif
6463 		case 0x20:
6464 			{
6465 				if (arg == 0xAA) {
6466 					u8 page_offset, page_num;
6467 
6468 					page_offset = (u8)(extra_arg >> 16);
6469 					page_num = (u8)(extra_arg & 0xFF);
6470 					rtw_dump_rsvd_page(RTW_DBGDUMP, padapter, page_offset, page_num);
6471 				}
6472 #ifdef CONFIG_SUPPORT_FIFO_DUMP
6473 				else {
6474 					u8 fifo_sel;
6475 					u32 addr, size;
6476 
6477 					fifo_sel = (u8)(arg & 0x0F);
6478 					addr = (extra_arg >> 16) & 0xFFFF;
6479 					size = extra_arg & 0xFFFF;
6480 					rtw_dump_fifo(RTW_DBGDUMP, padapter, fifo_sel, addr, size);
6481 				}
6482 #endif
6483 			}
6484 			break;
6485 
6486 		case 0x23: {
6487 			RTW_INFO("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
6488 			padapter->bNotifyChannelChange = extra_arg;
6489 			break;
6490 		}
6491 		case 0x24: {
6492 #ifdef CONFIG_P2P
6493 			RTW_INFO("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
6494 			padapter->bShowGetP2PState = extra_arg;
6495 #endif /* CONFIG_P2P */
6496 			break;
6497 		}
6498 #ifdef CONFIG_GPIO_API
6499 		case 0x25: { /* Get GPIO register */
6500 			/*
6501 			* dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
6502 			*/
6503 
6504 			u8 value;
6505 			RTW_INFO("Read GPIO Value  extra_arg = %d\n", extra_arg);
6506 			value = rtw_hal_get_gpio(padapter, extra_arg);
6507 			RTW_INFO("Read GPIO Value = %d\n", value);
6508 			break;
6509 		}
6510 		case 0x26: { /* Set GPIO direction */
6511 
6512 			/* dbg 0x7f26000x [y], Set gpio direction,
6513 			* x: gpio_num,4~7  y: indicate direction, 0~1
6514 			*/
6515 
6516 			int value;
6517 			RTW_INFO("Set GPIO Direction! arg = %d ,extra_arg=%d\n", arg , extra_arg);
6518 			value = rtw_hal_config_gpio(padapter, arg, extra_arg);
6519 			RTW_INFO("Set GPIO Direction %s\n", (value == -1) ? "Fail!!!" : "Success");
6520 			break;
6521 		}
6522 		case 0x27: { /* Set GPIO output direction value */
6523 			/*
6524 			* dbg 0x7f27000x [y], Set gpio output direction value,
6525 			* x: gpio_num,4~7  y: indicate direction, 0~1
6526 			*/
6527 
6528 			int value;
6529 			RTW_INFO("Set GPIO Value! arg = %d ,extra_arg=%d\n", arg , extra_arg);
6530 			value = rtw_hal_set_gpio_output_value(padapter, arg, extra_arg);
6531 			RTW_INFO("Set GPIO Value %s\n", (value == -1) ? "Fail!!!" : "Success");
6532 			break;
6533 		}
6534 #endif
6535 #ifdef DBG_CMD_QUEUE
6536 		case 0x28: {
6537 			dump_cmd_id = extra_arg;
6538 			RTW_INFO("dump_cmd_id:%d\n", dump_cmd_id);
6539 		}
6540 			break;
6541 #endif /* DBG_CMD_QUEUE */
6542 		case 0xaa: {
6543 			if ((extra_arg & 0x7F) > 0x3F)
6544 				extra_arg = 0xFF;
6545 			RTW_INFO("chang data rate to :0x%02x\n", extra_arg);
6546 			padapter->fix_rate = extra_arg;
6547 		}
6548 			break;
6549 		case 0xdd: { /* registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg */
6550 			if (extra_arg == 0)
6551 				mac_reg_dump(RTW_DBGDUMP, padapter);
6552 			else if (extra_arg == 1)
6553 				bb_reg_dump(RTW_DBGDUMP, padapter);
6554 			else if (extra_arg == 2)
6555 				rf_reg_dump(RTW_DBGDUMP, padapter);
6556 			else if (extra_arg == 11)
6557 				bb_reg_dump_ex(RTW_DBGDUMP, padapter);
6558 		}
6559 			break;
6560 
6561 		case 0xee: {
6562 			RTW_INFO(" === please control /proc  to trun on/off PHYDM func ===\n");
6563 		}
6564 			break;
6565 
6566 		case 0xfd:
6567 			rtw_write8(padapter, 0xc50, arg);
6568 			RTW_INFO("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6569 			rtw_write8(padapter, 0xc58, arg);
6570 			RTW_INFO("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6571 			break;
6572 		case 0xfe:
6573 			RTW_INFO("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6574 			RTW_INFO("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6575 			break;
6576 		case 0xff: {
6577 			RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
6578 			RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
6579 			RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
6580 			RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
6581 			RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
6582 
6583 			RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
6584 
6585 
6586 			RTW_INFO("\n");
6587 
6588 			RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
6589 			RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
6590 
6591 			RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
6592 
6593 			RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
6594 
6595 			RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
6596 			RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
6597 
6598 			RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
6599 			RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
6600 			RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
6601 			RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
6602 		}
6603 			break;
6604 		}
6605 		break;
6606 	default:
6607 		RTW_INFO("error dbg cmd!\n");
6608 		break;
6609 	}
6610 
6611 #endif
6612 	return ret;
6613 
6614 }
6615 
6616 #ifdef CONFIG_IOCTL_WEXT
6617 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
6618 {
6619 	uint ret = 0;
6620 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6621 
6622 	switch (name) {
6623 	case IEEE_PARAM_WPA_ENABLED:
6624 
6625 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
6626 
6627 		/* ret = ieee80211_wpa_enable(ieee, value); */
6628 
6629 		switch ((value) & 0xff) {
6630 		case 1: /* WPA */
6631 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
6632 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
6633 			break;
6634 		case 2: /* WPA2 */
6635 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
6636 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
6637 			break;
6638 		}
6639 
6640 
6641 		break;
6642 
6643 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
6644 		/* ieee->tkip_countermeasures=value; */
6645 		break;
6646 
6647 	case IEEE_PARAM_DROP_UNENCRYPTED: {
6648 		/* HACK:
6649 		 *
6650 		 * wpa_supplicant calls set_wpa_enabled when the driver
6651 		 * is loaded and unloaded, regardless of if WPA is being
6652 		 * used.  No other calls are made which can be used to
6653 		 * determine if encryption will be used or not prior to
6654 		 * association being expected.  If encryption is not being
6655 		 * used, drop_unencrypted is set to false, else true -- we
6656 		 * can use this to determine if the CAP_PRIVACY_ON bit should
6657 		 * be set.
6658 		 */
6659 
6660 #if 0
6661 		struct ieee80211_security sec = {
6662 			.flags = SEC_ENABLED,
6663 			.enabled = value,
6664 		};
6665 		ieee->drop_unencrypted = value;
6666 		/* We only change SEC_LEVEL for open mode. Others
6667 		 * are set by ipw_wpa_set_encryption.
6668 		 */
6669 		if (!value) {
6670 			sec.flags |= SEC_LEVEL;
6671 			sec.level = SEC_LEVEL_0;
6672 		} else {
6673 			sec.flags |= SEC_LEVEL;
6674 			sec.level = SEC_LEVEL_1;
6675 		}
6676 		if (ieee->set_security)
6677 			ieee->set_security(ieee->dev, &sec);
6678 #endif
6679 		break;
6680 
6681 	}
6682 	case IEEE_PARAM_PRIVACY_INVOKED:
6683 
6684 		/* ieee->privacy_invoked=value; */
6685 
6686 		break;
6687 
6688 	case IEEE_PARAM_AUTH_ALGS:
6689 
6690 		ret = wpa_set_auth_algs(dev, value);
6691 
6692 		break;
6693 
6694 	case IEEE_PARAM_IEEE_802_1X:
6695 
6696 		/* ieee->ieee802_1x=value;		 */
6697 
6698 		break;
6699 
6700 	case IEEE_PARAM_WPAX_SELECT:
6701 
6702 		/* added for WPA2 mixed mode */
6703 		/*RTW_WARN("------------------------>wpax value = %x\n", value);*/
6704 		/*
6705 		spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
6706 		ieee->wpax_type_set = 1;
6707 		ieee->wpax_type_notify = value;
6708 		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
6709 		*/
6710 
6711 		break;
6712 
6713 	default:
6714 
6715 
6716 
6717 		ret = -EOPNOTSUPP;
6718 
6719 
6720 		break;
6721 
6722 	}
6723 
6724 	return ret;
6725 
6726 }
6727 
6728 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
6729 {
6730 	int ret = 0;
6731 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6732 
6733 	switch (command) {
6734 	case IEEE_MLME_STA_DEAUTH:
6735 
6736 		if (!rtw_set_802_11_disassociate(padapter))
6737 			ret = -1;
6738 
6739 		break;
6740 
6741 	case IEEE_MLME_STA_DISASSOC:
6742 
6743 		if (!rtw_set_802_11_disassociate(padapter))
6744 			ret = -1;
6745 
6746 		break;
6747 
6748 	default:
6749 		ret = -EOPNOTSUPP;
6750 		break;
6751 	}
6752 #ifdef CONFIG_RTW_REPEATER_SON
6753 	rtw_rson_do_disconnect(padapter);
6754 #endif
6755 	return ret;
6756 
6757 }
6758 
6759 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
6760 {
6761 	struct ieee_param *param;
6762 	uint ret = 0;
6763 
6764 	/* down(&ieee->wx_sem);	 */
6765 
6766 	if (p->length < sizeof(struct ieee_param) || !p->pointer) {
6767 		ret = -EINVAL;
6768 		goto out;
6769 	}
6770 
6771 	param = (struct ieee_param *)rtw_malloc(p->length);
6772 	if (param == NULL) {
6773 		ret = -ENOMEM;
6774 		goto out;
6775 	}
6776 
6777 	if (copy_from_user(param, p->pointer, p->length)) {
6778 		rtw_mfree((u8 *)param, p->length);
6779 		ret = -EFAULT;
6780 		goto out;
6781 	}
6782 
6783 	switch (param->cmd) {
6784 
6785 	case IEEE_CMD_SET_WPA_PARAM:
6786 		ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
6787 		break;
6788 
6789 	case IEEE_CMD_SET_WPA_IE:
6790 		/* ret = wpa_set_wpa_ie(dev, param, p->length); */
6791 		ret =  rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
6792 		break;
6793 
6794 	case IEEE_CMD_SET_ENCRYPTION:
6795 		ret = wpa_set_encryption(dev, param, p->length);
6796 		break;
6797 
6798 	case IEEE_CMD_MLME:
6799 		ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
6800 		break;
6801 
6802 	default:
6803 		RTW_INFO("Unknown WPA supplicant request: %d\n", param->cmd);
6804 		ret = -EOPNOTSUPP;
6805 		break;
6806 
6807 	}
6808 
6809 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6810 		ret = -EFAULT;
6811 
6812 	rtw_mfree((u8 *)param, p->length);
6813 
6814 out:
6815 
6816 	/* up(&ieee->wx_sem); */
6817 
6818 	return ret;
6819 
6820 }
6821 
6822 #ifdef CONFIG_AP_MODE
6823 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
6824 {
6825 	int ret = 0;
6826 	u32 wep_key_idx, wep_key_len, wep_total_len;
6827 	NDIS_802_11_WEP	*pwep = NULL;
6828 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
6829 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6830 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
6831 	struct security_priv *psecuritypriv = &(padapter->securitypriv);
6832 	struct sta_priv *pstapriv = &padapter->stapriv;
6833 
6834 	RTW_INFO("%s\n", __FUNCTION__);
6835 
6836 	param->u.crypt.err = 0;
6837 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
6838 
6839 	/* sizeof(struct ieee_param) = 64 bytes; */
6840 	/* if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
6841 	if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
6842 		ret =  -EINVAL;
6843 		goto exit;
6844 	}
6845 
6846 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6847 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6848 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6849 		if (param->u.crypt.idx >= WEP_KEYS
6850 #ifdef CONFIG_IEEE80211W
6851 		    && param->u.crypt.idx > BIP_MAX_KEYID
6852 #endif /* CONFIG_IEEE80211W */
6853 		   ) {
6854 			ret = -EINVAL;
6855 			goto exit;
6856 		}
6857 	} else {
6858 		psta = rtw_get_stainfo(pstapriv, param->sta_addr);
6859 		if (!psta) {
6860 			/* ret = -EINVAL; */
6861 			RTW_INFO("rtw_set_encryption(), sta has already been removed or never been added\n");
6862 			goto exit;
6863 		}
6864 	}
6865 
6866 	if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
6867 		/* todo:clear default encryption keys */
6868 
6869 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
6870 		psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
6871 		psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
6872 		psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
6873 
6874 		RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
6875 
6876 		goto exit;
6877 	}
6878 
6879 
6880 	if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
6881 		RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
6882 
6883 		wep_key_idx = param->u.crypt.idx;
6884 		wep_key_len = param->u.crypt.key_len;
6885 
6886 		RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
6887 
6888 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
6889 			ret = -EINVAL;
6890 			goto exit;
6891 		}
6892 
6893 
6894 		if (wep_key_len > 0) {
6895 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
6896 			wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
6897 			pwep = (NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
6898 			if (pwep == NULL) {
6899 				RTW_INFO(" r871x_set_encryption: pwep allocate fail !!!\n");
6900 				goto exit;
6901 			}
6902 
6903 			_rtw_memset(pwep, 0, wep_total_len);
6904 
6905 			pwep->KeyLength = wep_key_len;
6906 			pwep->Length = wep_total_len;
6907 
6908 		}
6909 
6910 		pwep->KeyIndex = wep_key_idx;
6911 
6912 		_rtw_memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
6913 
6914 		if (param->u.crypt.set_tx) {
6915 			RTW_INFO("wep, set_tx=1\n");
6916 
6917 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
6918 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
6919 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
6920 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6921 
6922 			if (pwep->KeyLength == 13) {
6923 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
6924 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
6925 			}
6926 
6927 
6928 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
6929 
6930 			_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6931 
6932 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6933 
6934 			rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
6935 		} else {
6936 			RTW_INFO("wep, set_tx=0\n");
6937 
6938 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and  */
6939 			/* "psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam */
6940 
6941 			_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6942 
6943 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6944 
6945 			rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
6946 		}
6947 
6948 		goto exit;
6949 
6950 	}
6951 
6952 
6953 	if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /*  */ { /* group key */
6954 		if (param->u.crypt.set_tx == 1) {
6955 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
6956 				RTW_INFO(FUNC_ADPT_FMT" set WEP TX GTK idx:%u, len:%u\n"
6957 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6958 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6959 				psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6960 				if (param->u.crypt.key_len == 13)
6961 					psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
6962 
6963 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
6964 				RTW_INFO(FUNC_ADPT_FMT" set TKIP TX GTK idx:%u, len:%u\n"
6965 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6966 				psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
6967 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6968 				/* set mic key */
6969 				_rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
6970 				_rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
6971 				psecuritypriv->busetkipkey = _TRUE;
6972 
6973 			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
6974 				RTW_INFO(FUNC_ADPT_FMT" set CCMP TX GTK idx:%u, len:%u\n"
6975 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6976 				psecuritypriv->dot118021XGrpPrivacy = _AES_;
6977 				_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6978 
6979 			#ifdef CONFIG_IEEE80211W
6980 			} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
6981 				RTW_INFO(FUNC_ADPT_FMT" set TX IGTK idx:%u, len:%u\n"
6982 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6983 				_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6984 				psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
6985 				psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
6986 				psecuritypriv->binstallBIPkey = _TRUE;
6987 				goto exit;
6988 			#endif /* CONFIG_IEEE80211W */
6989 
6990 			} else if (strcmp(param->u.crypt.alg, "none") == 0) {
6991 				RTW_INFO(FUNC_ADPT_FMT" clear group key, idx:%u\n"
6992 					, FUNC_ADPT_ARG(padapter), param->u.crypt.idx);
6993 				psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
6994 			} else {
6995 				RTW_WARN(FUNC_ADPT_FMT" set group key, not support\n"
6996 					, FUNC_ADPT_ARG(padapter));
6997 				goto exit;
6998 			}
6999 
7000 			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7001 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7002 			if (pbcmc_sta) {
7003 				pbcmc_sta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
7004 				pbcmc_sta->ieee8021x_blocked = _FALSE;
7005 				pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy			 */
7006 			}
7007 			psecuritypriv->binstallGrpkey = _TRUE;
7008 			psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
7009 
7010 			rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7011 		}
7012 
7013 		goto exit;
7014 
7015 	}
7016 
7017 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
7018 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
7019 			if (param->u.crypt.set_tx == 1) {
7020 				_rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
7021 
7022 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
7023 					RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n"
7024 						, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7025 						, param->u.crypt.idx, param->u.crypt.key_len);
7026 					psta->dot118021XPrivacy = _WEP40_;
7027 					if (param->u.crypt.key_len == 13)
7028 						psta->dot118021XPrivacy = _WEP104_;
7029 
7030 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7031 					RTW_INFO(FUNC_ADPT_FMT" set TKIP PTK of "MAC_FMT" idx:%u, len:%u\n"
7032 						, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7033 						, param->u.crypt.idx, param->u.crypt.key_len);
7034 					psta->dot118021XPrivacy = _TKIP_;
7035 					/* set mic key */
7036 					_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7037 					_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7038 					psecuritypriv->busetkipkey = _TRUE;
7039 
7040 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7041 					RTW_INFO(FUNC_ADPT_FMT" set CCMP PTK of "MAC_FMT" idx:%u, len:%u\n"
7042 						, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7043 						, param->u.crypt.idx, param->u.crypt.key_len);
7044 					psta->dot118021XPrivacy = _AES_;
7045 
7046 				} else if (strcmp(param->u.crypt.alg, "none") == 0) {
7047 					RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n"
7048 						, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7049 						, param->u.crypt.idx);
7050 					psta->dot118021XPrivacy = _NO_PRIVACY_;
7051 
7052 				} else {
7053 					RTW_WARN(FUNC_ADPT_FMT" set pairwise key of "MAC_FMT", not support\n"
7054 						, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
7055 					goto exit;
7056 				}
7057 
7058 				psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
7059 				psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
7060 				psta->ieee8021x_blocked = _FALSE;
7061 
7062 				if (psta->dot118021XPrivacy != _NO_PRIVACY_) {
7063 					psta->bpairwise_key_installed = _TRUE;
7064 
7065 					/* WPA2 key-handshake has completed */
7066 					if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
7067 						psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
7068 				}
7069 
7070 				rtw_ap_set_pairwise_key(padapter, psta);
7071 			} else {
7072 				RTW_WARN(FUNC_ADPT_FMT" set group key of "MAC_FMT", not support\n"
7073 					, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
7074 				goto exit;
7075 			}
7076 
7077 		}
7078 
7079 	}
7080 
7081 exit:
7082 
7083 	if (pwep)
7084 		rtw_mfree((u8 *)pwep, wep_total_len);
7085 
7086 	return ret;
7087 
7088 }
7089 
7090 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
7091 {
7092 	int ret = 0;
7093 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7094 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7095 	struct sta_priv *pstapriv = &padapter->stapriv;
7096 	unsigned char *pbuf = param->u.bcn_ie.buf;
7097 
7098 
7099 	RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7100 
7101 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7102 		return -EINVAL;
7103 
7104 	_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
7105 
7106 	if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
7107 		pstapriv->max_num_sta = NUM_STA;
7108 
7109 
7110 	if (rtw_check_beacon_data(padapter, pbuf, (len - 12 - 2)) == _SUCCESS) /* 12 = param header, 2:no packed */
7111 		ret = 0;
7112 	else
7113 		ret = -EINVAL;
7114 
7115 
7116 	return ret;
7117 
7118 }
7119 
7120 static int rtw_hostapd_sta_flush(struct net_device *dev)
7121 {
7122 	/* _irqL irqL; */
7123 	/* _list	*phead, *plist; */
7124 	int ret = 0;
7125 	/* struct sta_info *psta = NULL; */
7126 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7127 	/* struct sta_priv *pstapriv = &padapter->stapriv; */
7128 
7129 	RTW_INFO("%s\n", __FUNCTION__);
7130 
7131 	flush_all_cam_entry(padapter);	/* clear CAM */
7132 #ifdef CONFIG_AP_MODE
7133 	ret = rtw_sta_flush(padapter, _TRUE);
7134 #endif
7135 	return ret;
7136 
7137 }
7138 
7139 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
7140 {
7141 	int ret = 0;
7142 	struct sta_info *psta = NULL;
7143 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7144 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7145 	struct sta_priv *pstapriv = &padapter->stapriv;
7146 
7147 	RTW_INFO("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
7148 
7149 	if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7150 		return -EINVAL;
7151 
7152 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7153 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7154 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7155 		return -EINVAL;
7156 
7157 #if 0
7158 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7159 	if (psta) {
7160 		RTW_INFO("rtw_add_sta(), free has been added psta=%p\n", psta);
7161 		/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);		 */
7162 		rtw_free_stainfo(padapter,  psta);
7163 		/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7164 
7165 		psta = NULL;
7166 	}
7167 #endif
7168 	/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
7169 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7170 	if (psta) {
7171 		int flags = param->u.add_sta.flags;
7172 
7173 		/* RTW_INFO("rtw_add_sta(), init sta's variables, psta=%p\n", psta); */
7174 
7175 		psta->cmn.aid = param->u.add_sta.aid;/* aid=1~2007 */
7176 
7177 		_rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
7178 
7179 
7180 		/* check wmm cap. */
7181 		if (WLAN_STA_WME & flags)
7182 			psta->qos_option = 1;
7183 		else
7184 			psta->qos_option = 0;
7185 
7186 		if (pmlmepriv->qospriv.qos_option == 0)
7187 			psta->qos_option = 0;
7188 
7189 
7190 #ifdef CONFIG_80211N_HT
7191 		/* chec 802.11n ht cap. */
7192 		if (padapter->registrypriv.ht_enable &&
7193 			is_supported_ht(padapter->registrypriv.wireless_mode) &&
7194 			(WLAN_STA_HT & flags)) {
7195 			psta->htpriv.ht_option = _TRUE;
7196 			psta->qos_option = 1;
7197 			_rtw_memcpy((void *)&psta->htpriv.ht_cap, (void *)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7198 		} else
7199 			psta->htpriv.ht_option = _FALSE;
7200 
7201 		if (pmlmepriv->htpriv.ht_option == _FALSE)
7202 			psta->htpriv.ht_option = _FALSE;
7203 
7204 #endif
7205 
7206 
7207 		update_sta_info_apmode(padapter, psta);
7208 
7209 
7210 	} else
7211 		ret = -ENOMEM;
7212 
7213 	return ret;
7214 
7215 }
7216 
7217 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
7218 {
7219 	_irqL irqL;
7220 	int ret = 0;
7221 	struct sta_info *psta = NULL;
7222 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7223 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7224 	struct sta_priv *pstapriv = &padapter->stapriv;
7225 
7226 	RTW_INFO("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
7227 
7228 	if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7229 		return -EINVAL;
7230 
7231 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7232 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7233 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7234 		return -EINVAL;
7235 
7236 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7237 	if (psta) {
7238 		u8 updated = _FALSE;
7239 
7240 		/* RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid); */
7241 
7242 		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7243 		if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
7244 			rtw_list_delete(&psta->asoc_list);
7245 			pstapriv->asoc_list_cnt--;
7246 			#ifdef CONFIG_RTW_TOKEN_BASED_XMIT
7247 			if (psta->tbtx_enable)
7248 				pstapriv->tbtx_asoc_list_cnt--;
7249 			#endif
7250 			updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
7251 
7252 		}
7253 		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7254 
7255 		associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
7256 
7257 		psta = NULL;
7258 
7259 	} else {
7260 		RTW_INFO("rtw_del_sta(), sta has already been removed or never been added\n");
7261 
7262 		/* ret = -1; */
7263 	}
7264 
7265 
7266 	return ret;
7267 
7268 }
7269 
7270 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
7271 {
7272 	int ret = 0;
7273 	struct sta_info *psta = NULL;
7274 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7275 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7276 	struct sta_priv *pstapriv = &padapter->stapriv;
7277 	struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
7278 	struct sta_data *psta_data = (struct sta_data *)param_ex->data;
7279 
7280 	RTW_INFO("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
7281 
7282 	if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7283 		return -EINVAL;
7284 
7285 	if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
7286 	    param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
7287 	    param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
7288 		return -EINVAL;
7289 
7290 	psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
7291 	if (psta) {
7292 #if 0
7293 		struct {
7294 			u16 aid;
7295 			u16 capability;
7296 			int flags;
7297 			u32 sta_set;
7298 			u8 tx_supp_rates[16];
7299 			u32 tx_supp_rates_len;
7300 			struct rtw_ieee80211_ht_cap ht_cap;
7301 			u64	rx_pkts;
7302 			u64	rx_bytes;
7303 			u64	rx_drops;
7304 			u64	tx_pkts;
7305 			u64	tx_bytes;
7306 			u64	tx_drops;
7307 		} get_sta;
7308 #endif
7309 		psta_data->aid = (u16)psta->cmn.aid;
7310 		psta_data->capability = psta->capability;
7311 		psta_data->flags = psta->flags;
7312 
7313 		/*
7314 				nonerp_set : BIT(0)
7315 				no_short_slot_time_set : BIT(1)
7316 				no_short_preamble_set : BIT(2)
7317 				no_ht_gf_set : BIT(3)
7318 				no_ht_set : BIT(4)
7319 				ht_20mhz_set : BIT(5)
7320 		*/
7321 
7322 		psta_data->sta_set = ((psta->nonerp_set) |
7323 				      (psta->no_short_slot_time_set << 1) |
7324 				      (psta->no_short_preamble_set << 2) |
7325 				      (psta->no_ht_gf_set << 3) |
7326 				      (psta->no_ht_set << 4) |
7327 				      (psta->ht_20mhz_set << 5));
7328 
7329 		psta_data->tx_supp_rates_len =  psta->bssratelen;
7330 		_rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
7331 #ifdef CONFIG_80211N_HT
7332 		if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))
7333 			_rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7334 #endif /* CONFIG_80211N_HT */
7335 		psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
7336 		psta_data->rx_bytes = psta->sta_stats.rx_bytes;
7337 		psta_data->rx_drops = psta->sta_stats.rx_drops;
7338 
7339 		psta_data->tx_pkts = psta->sta_stats.tx_pkts;
7340 		psta_data->tx_bytes = psta->sta_stats.tx_bytes;
7341 		psta_data->tx_drops = psta->sta_stats.tx_drops;
7342 
7343 
7344 	} else
7345 		ret = -1;
7346 
7347 	return ret;
7348 
7349 }
7350 
7351 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
7352 {
7353 	int ret = 0;
7354 	struct sta_info *psta = NULL;
7355 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7356 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7357 	struct sta_priv *pstapriv = &padapter->stapriv;
7358 
7359 	RTW_INFO("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
7360 
7361 	if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7362 		return -EINVAL;
7363 
7364 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7365 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7366 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7367 		return -EINVAL;
7368 
7369 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7370 	if (psta) {
7371 		if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
7372 			int wpa_ie_len;
7373 			int copy_len;
7374 
7375 			wpa_ie_len = psta->wpa_ie[1];
7376 
7377 			copy_len = ((wpa_ie_len + 2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len + 2);
7378 
7379 			param->u.wpa_ie.len = copy_len;
7380 
7381 			_rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
7382 		} else {
7383 			/* ret = -1; */
7384 			RTW_INFO("sta's wpa_ie is NONE\n");
7385 		}
7386 	} else
7387 		ret = -1;
7388 
7389 	return ret;
7390 
7391 }
7392 
7393 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
7394 {
7395 	int ret = 0;
7396 	unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
7397 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7398 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7399 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
7400 	int ie_len;
7401 
7402 	RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7403 
7404 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7405 		return -EINVAL;
7406 
7407 	ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7408 
7409 
7410 	if (pmlmepriv->wps_beacon_ie) {
7411 		rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7412 		pmlmepriv->wps_beacon_ie = NULL;
7413 	}
7414 
7415 	if (ie_len > 0) {
7416 		pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
7417 		pmlmepriv->wps_beacon_ie_len = ie_len;
7418 		if (pmlmepriv->wps_beacon_ie == NULL) {
7419 			RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7420 			return -EINVAL;
7421 		}
7422 
7423 		_rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
7424 
7425 		update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, 0);
7426 
7427 		pmlmeext->bstart_bss = _TRUE;
7428 
7429 	}
7430 
7431 
7432 	return ret;
7433 
7434 }
7435 
7436 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
7437 {
7438 	int ret = 0;
7439 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7440 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7441 	int ie_len;
7442 
7443 	RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7444 
7445 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7446 		return -EINVAL;
7447 
7448 	ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7449 
7450 
7451 	if (pmlmepriv->wps_probe_resp_ie) {
7452 		rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
7453 		pmlmepriv->wps_probe_resp_ie = NULL;
7454 	}
7455 
7456 	if (ie_len > 0) {
7457 		pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
7458 		pmlmepriv->wps_probe_resp_ie_len = ie_len;
7459 		if (pmlmepriv->wps_probe_resp_ie == NULL) {
7460 			RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7461 			return -EINVAL;
7462 		}
7463 		_rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
7464 	}
7465 
7466 
7467 	return ret;
7468 
7469 }
7470 
7471 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
7472 {
7473 	int ret = 0;
7474 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7475 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7476 	int ie_len;
7477 
7478 	RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7479 
7480 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7481 		return -EINVAL;
7482 
7483 	ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7484 
7485 
7486 	if (pmlmepriv->wps_assoc_resp_ie) {
7487 		rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
7488 		pmlmepriv->wps_assoc_resp_ie = NULL;
7489 	}
7490 
7491 	if (ie_len > 0) {
7492 		pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
7493 		pmlmepriv->wps_assoc_resp_ie_len = ie_len;
7494 		if (pmlmepriv->wps_assoc_resp_ie == NULL) {
7495 			RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7496 			return -EINVAL;
7497 		}
7498 
7499 		_rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
7500 	}
7501 
7502 
7503 	return ret;
7504 
7505 }
7506 
7507 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
7508 {
7509 	int ret = 0;
7510 	_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
7511 	struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
7512 	struct mlme_ext_priv	*mlmeext = &(adapter->mlmeextpriv);
7513 	struct mlme_ext_info	*mlmeinfo = &(mlmeext->mlmext_info);
7514 	int ie_len;
7515 	u8 *ssid_ie;
7516 	char ssid[NDIS_802_11_LENGTH_SSID + 1];
7517 	sint ssid_len = 0;
7518 	u8 ignore_broadcast_ssid;
7519 
7520 	if (check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
7521 		return -EPERM;
7522 
7523 	if (param->u.bcn_ie.reserved[0] != 0xea)
7524 		return -EINVAL;
7525 
7526 	mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
7527 
7528 	ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7529 	ssid_ie = rtw_get_ie(param->u.bcn_ie.buf,  WLAN_EID_SSID, &ssid_len, ie_len);
7530 
7531 	if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
7532 		WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
7533 		WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
7534 
7535 		_rtw_memcpy(ssid, ssid_ie + 2, ssid_len);
7536 		ssid[ssid_len] = 0x0;
7537 
7538 		if (0)
7539 			RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7540 				ssid, ssid_len,
7541 				pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7542 				pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7543 
7544 		_rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
7545 		pbss_network->Ssid.SsidLength = ssid_len;
7546 		_rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
7547 		pbss_network_ext->Ssid.SsidLength = ssid_len;
7548 
7549 		if (0)
7550 			RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7551 				pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7552 				pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7553 	}
7554 
7555 	RTW_INFO(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
7556 		ignore_broadcast_ssid, ssid, ssid_len);
7557 
7558 	return ret;
7559 }
7560 
7561 #if CONFIG_RTW_MACADDR_ACL
7562 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
7563 {
7564 	int ret = 0;
7565 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7566 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7567 
7568 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7569 		return -EINVAL;
7570 
7571 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7572 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7573 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7574 		return -EINVAL;
7575 
7576 	ret = rtw_acl_remove_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);
7577 
7578 	return ret;
7579 
7580 }
7581 
7582 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
7583 {
7584 	int ret = 0;
7585 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7586 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7587 
7588 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7589 		return -EINVAL;
7590 
7591 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7592 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7593 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7594 		return -EINVAL;
7595 
7596 	ret = rtw_acl_add_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);
7597 
7598 	return ret;
7599 
7600 }
7601 
7602 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
7603 {
7604 	int ret = 0;
7605 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7606 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7607 
7608 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7609 		return -EINVAL;
7610 
7611 	rtw_set_macaddr_acl(padapter, RTW_ACL_PERIOD_BSS, param->u.mlme.command);
7612 
7613 	return ret;
7614 }
7615 #endif /* CONFIG_RTW_MACADDR_ACL */
7616 
7617 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
7618 {
7619 	struct ieee_param *param;
7620 	int ret = 0;
7621 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7622 
7623 	/* RTW_INFO("%s\n", __FUNCTION__); */
7624 
7625 	/*
7626 	* this function is expect to call in master mode, which allows no power saving
7627 	* so, we just check hw_init_completed
7628 	*/
7629 
7630 	if (!rtw_is_hw_init_completed(padapter)) {
7631 		ret = -EPERM;
7632 		goto out;
7633 	}
7634 
7635 
7636 	/* if (p->length < sizeof(struct ieee_param) || !p->pointer){ */
7637 	if (!p->pointer) {
7638 		ret = -EINVAL;
7639 		goto out;
7640 	}
7641 
7642 	param = (struct ieee_param *)rtw_malloc(p->length);
7643 	if (param == NULL) {
7644 		ret = -ENOMEM;
7645 		goto out;
7646 	}
7647 
7648 	if (copy_from_user(param, p->pointer, p->length)) {
7649 		rtw_mfree((u8 *)param, p->length);
7650 		ret = -EFAULT;
7651 		goto out;
7652 	}
7653 
7654 	/* RTW_INFO("%s, cmd=%d\n", __FUNCTION__, param->cmd); */
7655 
7656 	switch (param->cmd) {
7657 	case RTL871X_HOSTAPD_FLUSH:
7658 
7659 		ret = rtw_hostapd_sta_flush(dev);
7660 
7661 		break;
7662 
7663 	case RTL871X_HOSTAPD_ADD_STA:
7664 
7665 		ret = rtw_add_sta(dev, param);
7666 
7667 		break;
7668 
7669 	case RTL871X_HOSTAPD_REMOVE_STA:
7670 
7671 		ret = rtw_del_sta(dev, param);
7672 
7673 		break;
7674 
7675 	case RTL871X_HOSTAPD_SET_BEACON:
7676 
7677 		ret = rtw_set_beacon(dev, param, p->length);
7678 
7679 		break;
7680 
7681 	case RTL871X_SET_ENCRYPTION:
7682 
7683 		ret = rtw_set_encryption(dev, param, p->length);
7684 
7685 		break;
7686 
7687 	case RTL871X_HOSTAPD_GET_WPAIE_STA:
7688 
7689 		ret = rtw_get_sta_wpaie(dev, param);
7690 
7691 		break;
7692 
7693 	case RTL871X_HOSTAPD_SET_WPS_BEACON:
7694 
7695 		ret = rtw_set_wps_beacon(dev, param, p->length);
7696 
7697 		break;
7698 
7699 	case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
7700 
7701 		ret = rtw_set_wps_probe_resp(dev, param, p->length);
7702 
7703 		break;
7704 
7705 	case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
7706 
7707 		ret = rtw_set_wps_assoc_resp(dev, param, p->length);
7708 
7709 		break;
7710 
7711 	case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
7712 
7713 		ret = rtw_set_hidden_ssid(dev, param, p->length);
7714 
7715 		break;
7716 
7717 	case RTL871X_HOSTAPD_GET_INFO_STA:
7718 
7719 		ret = rtw_ioctl_get_sta_data(dev, param, p->length);
7720 
7721 		break;
7722 
7723 #if CONFIG_RTW_MACADDR_ACL
7724 	case RTL871X_HOSTAPD_SET_MACADDR_ACL:
7725 		ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
7726 		break;
7727 	case RTL871X_HOSTAPD_ACL_ADD_STA:
7728 		ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
7729 		break;
7730 	case RTL871X_HOSTAPD_ACL_REMOVE_STA:
7731 		ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
7732 		break;
7733 #endif /* CONFIG_RTW_MACADDR_ACL */
7734 
7735 	default:
7736 		RTW_INFO("Unknown hostapd request: %d\n", param->cmd);
7737 		ret = -EOPNOTSUPP;
7738 		break;
7739 
7740 	}
7741 
7742 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7743 		ret = -EFAULT;
7744 
7745 
7746 	rtw_mfree((u8 *)param, p->length);
7747 
7748 out:
7749 
7750 	return ret;
7751 
7752 }
7753 #endif	/*	CONFIG_AP_MODE	*/
7754 
7755 static int rtw_wx_set_priv(struct net_device *dev,
7756 			   struct iw_request_info *info,
7757 			   union iwreq_data *awrq,
7758 			   char *extra)
7759 {
7760 
7761 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7762 	char *ext_dbg;
7763 #endif
7764 
7765 	int ret = 0;
7766 	int len = 0;
7767 	char *ext;
7768 #ifdef CONFIG_RTW_ANDROID
7769 	int i;
7770 #endif
7771 
7772 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7773 	struct iw_point *dwrq = (struct iw_point *)awrq;
7774 
7775 	if (dwrq->length == 0)
7776 		return -EFAULT;
7777 
7778 	len = dwrq->length;
7779 	ext = rtw_vmalloc(len);
7780 	if (!ext)
7781 		return -ENOMEM;
7782 
7783 	if (copy_from_user(ext, dwrq->pointer, len)) {
7784 		rtw_vmfree(ext, len);
7785 		return -EFAULT;
7786 	}
7787 
7788 
7789 
7790 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7791 	ext_dbg = rtw_vmalloc(len);
7792 	if (!ext_dbg) {
7793 		rtw_vmfree(ext, len);
7794 		return -ENOMEM;
7795 	}
7796 
7797 	_rtw_memcpy(ext_dbg, ext, len);
7798 #endif
7799 
7800 	/* added for wps2.0 @20110524 */
7801 	if (dwrq->flags == 0x8766 && len > 8) {
7802 		u32 cp_sz;
7803 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7804 		u8 *probereq_wpsie = ext;
7805 		int probereq_wpsie_len = len;
7806 		u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
7807 
7808 		if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
7809 		    (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) == _TRUE)) {
7810 			cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
7811 
7812 			if (pmlmepriv->wps_probe_req_ie) {
7813 				u32 free_len = pmlmepriv->wps_probe_req_ie_len;
7814 				pmlmepriv->wps_probe_req_ie_len = 0;
7815 				rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
7816 				pmlmepriv->wps_probe_req_ie = NULL;
7817 			}
7818 
7819 			pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
7820 			if (pmlmepriv->wps_probe_req_ie == NULL) {
7821 				printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7822 				ret =  -EINVAL;
7823 				goto FREE_EXT;
7824 
7825 			}
7826 
7827 			_rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
7828 			pmlmepriv->wps_probe_req_ie_len = cp_sz;
7829 
7830 		}
7831 
7832 		goto FREE_EXT;
7833 
7834 	}
7835 
7836 	if (len >= WEXT_CSCAN_HEADER_SIZE
7837 		&& _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
7838 	) {
7839 		ret = rtw_wx_set_scan(dev, info, awrq, ext);
7840 		goto FREE_EXT;
7841 	}
7842 
7843 #ifdef CONFIG_RTW_ANDROID
7844 	/* RTW_INFO("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); */
7845 
7846 	i = rtw_android_cmdstr_to_num(ext);
7847 
7848 	switch (i) {
7849 	case ANDROID_WIFI_CMD_START:
7850 		indicate_wx_custom_event(padapter, "START");
7851 		break;
7852 	case ANDROID_WIFI_CMD_STOP:
7853 		indicate_wx_custom_event(padapter, "STOP");
7854 		break;
7855 	case ANDROID_WIFI_CMD_RSSI: {
7856 		struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
7857 		struct	wlan_network	*pcur_network = &pmlmepriv->cur_network;
7858 
7859 		if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
7860 			sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
7861 		else
7862 			sprintf(ext, "OK");
7863 	}
7864 		break;
7865 	case ANDROID_WIFI_CMD_LINKSPEED: {
7866 		u16 mbps = rtw_get_cur_max_rate(padapter) / 10;
7867 		sprintf(ext, "LINKSPEED %d", mbps);
7868 	}
7869 		break;
7870 	case ANDROID_WIFI_CMD_MACADDR:
7871 		sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
7872 		break;
7873 	case ANDROID_WIFI_CMD_SCAN_ACTIVE: {
7874 		/* rtw_set_scan_mode(padapter, SCAN_ACTIVE); */
7875 		sprintf(ext, "OK");
7876 	}
7877 		break;
7878 	case ANDROID_WIFI_CMD_SCAN_PASSIVE: {
7879 		/* rtw_set_scan_mode(padapter, SCAN_PASSIVE); */
7880 		sprintf(ext, "OK");
7881 	}
7882 		break;
7883 
7884 	case ANDROID_WIFI_CMD_COUNTRY: {
7885 		char country_code[10];
7886 		sscanf(ext, "%*s %s", country_code);
7887 		rtw_set_country(padapter, country_code, RTW_REGD_SET_BY_USER);
7888 		sprintf(ext, "OK");
7889 	}
7890 		break;
7891 	default:
7892 		#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7893 		RTW_INFO("%s: %s unknowned req=%s\n", __FUNCTION__,
7894 			dev->name, ext_dbg);
7895 		#endif
7896 
7897 		sprintf(ext, "OK");
7898 
7899 	}
7900 
7901 	if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext) + 1))))
7902 		ret = -EFAULT;
7903 
7904 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7905 	RTW_INFO("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
7906 		dev->name, ext_dbg , ext, dwrq->length, (u16)(strlen(ext) + 1));
7907 #endif
7908 #endif /* end of CONFIG_ANDROID */
7909 
7910 
7911 FREE_EXT:
7912 
7913 	rtw_vmfree(ext, len);
7914 	#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7915 	rtw_vmfree(ext_dbg, len);
7916 	#endif
7917 
7918 	/* RTW_INFO("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n",  */
7919 	/*		dev->name, ret); */
7920 
7921 	return ret;
7922 
7923 }
7924 #endif	/*CONFIG_IOCTL_WEXT*/
7925 
7926 #ifdef CONFIG_WOWLAN
7927 static int rtw_wowlan_ctrl(struct net_device *dev,
7928 			   struct iw_request_info *info,
7929 			   union iwreq_data *wrqu, char *extra)
7930 {
7931 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7932 	struct wowlan_ioctl_param poidparam;
7933 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
7934 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7935 	int ret = 0;
7936 	systime start_time = rtw_get_current_time();
7937 	poidparam.subcode = 0;
7938 
7939 	RTW_INFO("+rtw_wowlan_ctrl: %s\n", extra);
7940 
7941 	if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE) &&
7942 		check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
7943 		!WOWLAN_IS_STA_MIX_MODE(padapter)) {
7944 #ifdef CONFIG_PNO_SUPPORT
7945 		pwrctrlpriv->wowlan_pno_enable = _TRUE;
7946 #else
7947 		RTW_INFO("[%s] WARNING: Please Connect With AP First!!\n", __func__);
7948 		goto _rtw_wowlan_ctrl_exit_free;
7949 #endif /* CONFIG_PNO_SUPPORT */
7950 	}
7951 
7952 	if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY))
7953 		rtw_scan_abort(padapter);
7954 
7955 	if (_rtw_memcmp(extra, "enable", 6))
7956 
7957 
7958 		rtw_suspend_common(padapter);
7959 
7960 	else if (_rtw_memcmp(extra, "disable", 7)) {
7961 #ifdef CONFIG_USB_HCI
7962 		RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
7963 		RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
7964 #endif
7965 		rtw_resume_common(padapter);
7966 
7967 #ifdef CONFIG_PNO_SUPPORT
7968 		pwrctrlpriv->wowlan_pno_enable = _FALSE;
7969 #endif /* CONFIG_PNO_SUPPORT */
7970 
7971 	} else {
7972 		RTW_INFO("[%s] Invalid Parameter.\n", __func__);
7973 		goto _rtw_wowlan_ctrl_exit_free;
7974 	}
7975 	/* mutex_lock(&ioctl_mutex); */
7976 _rtw_wowlan_ctrl_exit_free:
7977 	RTW_INFO("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
7978 	RTW_PRINT("%s in %d ms\n", __func__,
7979 		  rtw_get_passing_time_ms(start_time));
7980 	return ret;
7981 }
7982 
7983 /*
7984  * IP filter This pattern if for a frame containing a ip packet:
7985  * AA:AA:AA:AA:AA:AA:BB:BB:BB:BB:BB:BB:CC:CC:DD:-:-:-:-:-:-:-:-:EE:-:-:FF:FF:FF:FF:GG:GG:GG:GG:HH:HH:II:II
7986  *
7987  * A: Ethernet destination address
7988  * B: Ethernet source address
7989  * C: Ethernet protocol type
7990  * D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20)
7991  * E: IP protocol
7992  * F: IP source address ( 192.168.0.4: C0:A8:00:2C )
7993  * G: IP destination address ( 192.168.0.4: C0:A8:00:2C )
7994  * H: Source port (1024: 04:00)
7995  * I: Destination port (1024: 04:00)
7996  */
7997 
7998 static int rtw_wowlan_set_pattern(struct net_device *dev,
7999 				  struct iw_request_info *info,
8000 				  union iwreq_data *wrqu, char *extra)
8001 {
8002 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8003 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8004 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8005 	struct wowlan_ioctl_param poidparam;
8006 	int ret = 0;
8007 	u8 input[MAX_IN_PATTERN_SIZE];
8008 	u8 index = 0;
8009 
8010 	poidparam.subcode = 0;
8011 
8012 	if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE) &&
8013 	    check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
8014 		ret = -EFAULT;
8015 		RTW_INFO("Please Connect With AP First!!\n");
8016 		goto _rtw_wowlan_set_pattern_exit;
8017 	}
8018 
8019 	if ((wrqu->data.length <= 0) || (wrqu->data.length > MAX_IN_PATTERN_SIZE)) {
8020 		ret = -EFAULT;
8021 		RTW_INFO("ERROR: parameter length error, len=%d\n", wrqu->data.length);
8022 		goto _rtw_wowlan_set_pattern_exit;
8023 	} else {
8024 		/* set pattern */
8025 		if (copy_from_user(input,
8026 				   wrqu->data.pointer, wrqu->data.length))
8027 			return -EFAULT;
8028 		/* leave PS first */
8029 		rtw_ps_deny(padapter, PS_DENY_IOCTL);
8030 		LeaveAllPowerSaveModeDirect(padapter);
8031 		if ((strncmp(input, "pattern=", 8) == 0) ||(strncmp(input, "ack_pattern=", 12) == 0)) {
8032 			if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_CAM_NUM) {
8033 				RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n",
8034 					 pwrpriv->wowlan_pattern_idx);
8035 				RTW_INFO("WARNING: please clean priv-pattern first\n");
8036 				ret = -EINVAL;
8037 				goto _rtw_wowlan_set_pattern_exit;
8038 			} else {
8039 				index = pwrpriv->wowlan_pattern_idx;
8040 				ret = rtw_wowlan_parser_pattern_cmd(input,
8041 					    pwrpriv->patterns[index].content,
8042 					    &pwrpriv->patterns[index].len,
8043 					    pwrpriv->patterns[index].mask);
8044 
8045 				if (ret == _TRUE) {
8046 					#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8047 					if(strncmp(input, "ack_pattern=", 12) == 0)
8048 						pwrpriv->wowlan_keep_alive_ack_index = index;
8049 					else
8050 						pwrpriv->wowlan_wake_pattern_index = index;
8051 					RTW_INFO("pwrpriv->wowlan_keep_alive_ack_index =%d\n",pwrpriv->wowlan_keep_alive_ack_index);
8052 					RTW_INFO("pwrpriv->wowlan_wake_pattern_index =%d\n",pwrpriv->wowlan_wake_pattern_index);
8053 					#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8054 					pwrpriv->wowlan_pattern_idx++;
8055 				}
8056 			}
8057 		} else if (strncmp(input, "clean", 5) == 0) {
8058 			poidparam.subcode = WOWLAN_PATTERN_CLEAN;
8059 			#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8060 			pwrpriv->wowlan_wake_pattern_index = 0xFF;
8061 			pwrpriv->wowlan_keep_alive_ack_index = 0xFF;
8062 			#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8063 
8064 			rtw_hal_set_hwreg(padapter,
8065 					  HW_VAR_WOWLAN, (u8 *)&poidparam);
8066 		} else if (strncmp(input, "show", 4) == 0) {
8067 			rtw_wow_pattern_cam_dump(padapter);
8068 			rtw_wow_pattern_sw_dump(padapter);
8069 		} else {
8070 			RTW_INFO("ERROR: incorrect parameter!\n");
8071 			ret = -EINVAL;
8072 		}
8073 		rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
8074 	}
8075 _rtw_wowlan_set_pattern_exit:
8076 	return ret;
8077 }
8078 
8079 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8080 static int rtw_wowlan_set_keep_alive_pattern(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8081 {
8082 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8083 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8084 
8085 	int ret = 0,totoal_len=0,i=0,len=0;
8086 	char *cp = NULL;
8087 	u32	mode = 0xFF;  /*para1*/
8088 	u16 period = 15*10; /* para2;units:100ms,default 15s*/
8089 	char tx_pattern[512];	   /*para3*/
8090 	u32   retry_intervel = 2*10; /* para4;units:100ms,default 2s*/
8091 	u32	retry_limit_count = 5; /*para5*/
8092 
8093 	ret = sscanf(extra, "%d %hu %s %d %d", &mode , &period, tx_pattern, &retry_intervel, &retry_limit_count);
8094 	pwrpriv->wowlan_keep_alive_mode = mode;
8095 
8096 	RTW_INFO("[%s] ret =%d \n", __func__ ,ret);
8097 	totoal_len = strlen(tx_pattern);
8098 	RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len);
8099 
8100 	 if (mode && (ret < 3))
8101                 return  -EINVAL;
8102 
8103 	 if (((mode ==2) ||(mode ==3)) && ((retry_intervel*retry_limit_count) > period)) {
8104 		RTW_INFO("[%s]  retry_intervel*retry_limit_count need smaller than period\n", __func__ );
8105 		return  -EINVAL;
8106 	 }
8107 
8108 	switch(mode){
8109 		case wow_keep_alive_pattern_disable:
8110 			/*disable this feature*/
8111 			pwrpriv->keep_alive_pattern_loc = 0;
8112 			pwrpriv->keep_alive_pattern_len = 0;
8113 			pwrpriv->wowlan_keep_alive_period = 0;
8114 			pwrpriv->wowlan_keep_alive_ack_index = 0xFF;
8115 			pwrpriv->wowlan_wake_pattern_index = 0xFF;
8116 			pwrpriv->wowlan_keep_alive_retry_interval = 0;
8117 			pwrpriv->wowlan_keep_alive_retry_counter = 0;
8118 			_rtw_memset(pwrpriv->keep_alive_pattern,0,WLAN_MAX_KEEP_ALIVE_IE_LEN);
8119 			RTW_INFO("[%s] clear pattern \n", __func__ );
8120 			ret = _SUCCESS;
8121 			break;
8122 		case wow_keep_alive_pattern_tx:
8123 			/*only tx udp packet*/
8124 			pwrpriv->wowlan_keep_alive_period = period;
8125 			pwrpriv->wowlan_keep_alive_retry_interval = 0;
8126 			pwrpriv->wowlan_keep_alive_retry_counter = 0;
8127 			RTW_INFO("[%s] wow_keep_alive_pattern_tx \n", __func__ );
8128 			break;
8129 		case wow_keep_alive_pattern_trx:
8130 			/*trx+no need wakeup*/
8131 			pwrpriv->wowlan_keep_alive_period = period;
8132 			pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel;
8133 			pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count;
8134 			RTW_INFO("[%s] wow_keep_alive_pattern_trx \n", __func__ );
8135 			break;
8136 		case wow_keep_alive_pattern_trx_with_ack:
8137 			/*trx+need wakeup*/
8138 			pwrpriv->wowlan_keep_alive_period = period;
8139 			pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel;
8140 			pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count;
8141 			RTW_INFO("[%s] wow_keep_alive_pattern_trx_with_ack \n", __func__ );
8142 			break;
8143 		default:
8144 			RTW_INFO("[%s] please setting valid mode \n", __func__ );
8145 			ret = -EINVAL;
8146 			break;
8147 
8148 	}
8149 
8150 	if((mode == 0) || (mode > 4))
8151 		return ret;
8152 
8153 	totoal_len = strlen(tx_pattern);
8154 	RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len);
8155 	if (totoal_len > WLAN_MAX_KEEP_ALIVE_IE_LEN*2) {
8156 		RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_KEEP_ALIVE_IE_LEN);
8157 		return -EFAULT;
8158 	}
8159 	RTW_INFO("[%s] period = %hu ,ie = %s , len = %d\n", __func__ , period , tx_pattern  , totoal_len);
8160 
8161 
8162 	if (totoal_len > 0) {
8163 		RTW_INFO("[%s] pwrpriv->keep_alive_pattern==========> \n", __func__ );
8164 		for (i = 0  ; i <totoal_len ; i += 2) {
8165 			pwrpriv->keep_alive_pattern[len] = key_2char2num(tx_pattern[i], tx_pattern[i + 1]);
8166 			RTW_INFO("[0x%x] ",pwrpriv->keep_alive_pattern[len]);
8167 			len++;
8168 		}
8169 		RTW_INFO(" \n" );
8170 		pwrpriv->keep_alive_pattern_len = len;
8171 	}
8172 
8173 	return ret;
8174 }
8175 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8176 
8177 #endif /* CONFIG_WOWLAN */
8178 
8179 #ifdef CONFIG_AP_WOWLAN
8180 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
8181 			      struct iw_request_info *info,
8182 			      union iwreq_data *wrqu, char *extra)
8183 {
8184 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8185 	struct wowlan_ioctl_param poidparam;
8186 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8187 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8188 	struct sta_info	*psta = NULL;
8189 	int ret = 0;
8190 	systime start_time = rtw_get_current_time();
8191 	poidparam.subcode = 0;
8192 
8193 	RTW_INFO("+rtw_ap_wowlan_ctrl: %s\n", extra);
8194 
8195 	if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
8196 		RTW_INFO("[%s] It is not AP mode!!\n", __func__);
8197 		goto _rtw_ap_wowlan_ctrl_exit_free;
8198 	}
8199 
8200 	if (_rtw_memcmp(extra, "enable", 6)) {
8201 
8202 		pwrctrlpriv->wowlan_ap_mode = _TRUE;
8203 
8204 		rtw_suspend_common(padapter);
8205 	} else if (_rtw_memcmp(extra, "disable", 7)) {
8206 #ifdef CONFIG_USB_HCI
8207 		RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
8208 		RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
8209 #endif
8210 		rtw_resume_common(padapter);
8211 	} else {
8212 		RTW_INFO("[%s] Invalid Parameter.\n", __func__);
8213 		goto _rtw_ap_wowlan_ctrl_exit_free;
8214 	}
8215 	/* mutex_lock(&ioctl_mutex); */
8216 _rtw_ap_wowlan_ctrl_exit_free:
8217 	RTW_INFO("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8218 	RTW_PRINT("%s in %d ms\n", __func__,
8219 		  rtw_get_passing_time_ms(start_time));
8220 _rtw_ap_wowlan_ctrl_exit:
8221 	return ret;
8222 }
8223 #endif /* CONFIG_AP_WOWLAN */
8224 
8225 static int rtw_pm_set(struct net_device *dev,
8226 		      struct iw_request_info *info,
8227 		      union iwreq_data *wrqu, char *extra)
8228 {
8229 	int ret = 0;
8230 	unsigned	mode = 0;
8231 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8232 
8233 	RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
8234 
8235 	if (_rtw_memcmp(extra, "lps=", 4)) {
8236 		sscanf(extra + 4, "%u", &mode);
8237 		ret = rtw_pm_set_lps(padapter, mode);
8238 	} else if (_rtw_memcmp(extra, "ips=", 4)) {
8239 		sscanf(extra + 4, "%u", &mode);
8240 		ret = rtw_pm_set_ips(padapter, mode);
8241 	} else if (_rtw_memcmp(extra, "lps_level=", 10)) {
8242 		if (sscanf(extra + 10, "%u", &mode) > 0)
8243 			ret = rtw_pm_set_lps_level(padapter, mode);
8244 #ifdef CONFIG_LPS_1T1R
8245 	} else if (_rtw_memcmp(extra, "lps_1t1r=", 9)) {
8246 		if (sscanf(extra + 9, "%u", &mode) > 0)
8247 			ret = rtw_pm_set_lps_1t1r(padapter, mode);
8248 #endif
8249 	}
8250 #ifdef CONFIG_WOWLAN
8251 	else if (_rtw_memcmp(extra, "wow_lps=", 8)) {
8252 		sscanf(extra + 8, "%u", &mode);
8253 		ret = rtw_pm_set_wow_lps(padapter, mode);
8254 	} else if (_rtw_memcmp(extra, "wow_lps_level=", 14)) {
8255 		if (sscanf(extra + 14, "%u", &mode) > 0)
8256 			ret = rtw_pm_set_wow_lps_level(padapter, mode);
8257 	#ifdef CONFIG_LPS_1T1R
8258 	} else if (_rtw_memcmp(extra, "wow_lps_1t1r=", 13)) {
8259 		if (sscanf(extra + 13, "%u", &mode) > 0)
8260 			ret = rtw_pm_set_wow_lps_1t1r(padapter, mode);
8261 	#endif
8262 	}
8263 #endif /* CONFIG_WOWLAN */
8264 	else
8265 		ret = -EINVAL;
8266 
8267 	return ret;
8268 }
8269 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8270 
8271 int rtw_vendor_ie_get_raw_data(struct net_device *dev, u32 vendor_ie_num,
8272 							   char *extra, u32 length)
8273 {
8274 	int j;
8275 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8276 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8277 	u32 vendor_ie_mask = 0;
8278 	char *pstring;
8279 
8280 	if (vendor_ie_num >= WLAN_MAX_VENDOR_IE_NUM) {
8281 		RTW_INFO("[%s] only support %d vendor ie\n", __func__ ,
8282 				 WLAN_MAX_VENDOR_IE_NUM);
8283 		return -EFAULT;
8284 	}
8285 
8286 	if (pmlmepriv->vendor_ielen[vendor_ie_num] == 0) {
8287 		RTW_INFO("[%s]  Fail, vendor_ie_num: %d is not set\n", __func__,
8288 				 vendor_ie_num);
8289 		return -EFAULT;
8290 	}
8291 
8292 	if (length < 2 * pmlmepriv->vendor_ielen[vendor_ie_num] + 5) {
8293 		RTW_INFO("[%s]  Fail, buffer size is too small\n", __func__);
8294 		return -EFAULT;
8295 	}
8296 
8297 	vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8298 	_rtw_memset(extra, 0, length);
8299 
8300 	pstring = extra;
8301 	pstring += sprintf(pstring, "%d,%x,", vendor_ie_num, vendor_ie_mask);
8302 
8303 	for (j = 0; j < pmlmepriv->vendor_ielen[vendor_ie_num]; j++)
8304 		pstring += sprintf(pstring, "%02x", pmlmepriv->vendor_ie[vendor_ie_num][j]);
8305 
8306 	length = pstring - extra;
8307 	return length;
8308 }
8309 
8310 int rtw_vendor_ie_get_data(struct net_device *dev, int vendor_ie_num, char *extra)
8311 {
8312 	int j;
8313 	char *pstring;
8314 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8315 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8316 	u32 vendor_ie_mask = 0;
8317 	__u16 length = 0;
8318 
8319 	vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8320 	pstring = extra;
8321 	pstring += sprintf(pstring , "\nVendor IE num %d , Mask:%x " , vendor_ie_num , vendor_ie_mask);
8322 
8323 	if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8324 		pstring += sprintf(pstring , "[Beacon]");
8325 	if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8326 		pstring += sprintf(pstring , "[Probe Req]");
8327 	if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8328 		pstring += sprintf(pstring , "[Probe Resp]");
8329 	if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8330 		pstring += sprintf(pstring , "[Assoc Req]");
8331 	if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8332 		pstring += sprintf(pstring , "[Assoc Resp]");
8333 #ifdef CONFIG_P2P
8334 	if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)
8335 		pstring += sprintf(pstring , "[P2P_Probe Req]");
8336 	if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)
8337 		pstring += sprintf(pstring , "[P2P_Probe Resp]");
8338 #endif
8339 
8340 	pstring += sprintf(pstring , "\nVendor IE:\n");
8341 	for (j = 0 ; j < pmlmepriv->vendor_ielen[vendor_ie_num]  ; j++)
8342 		pstring += sprintf(pstring , "%02x" , pmlmepriv->vendor_ie[vendor_ie_num][j]);
8343 
8344 	length = pstring - extra;
8345 	return length;
8346 
8347 }
8348 
8349 int rtw_vendor_ie_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8350 {
8351 	int ret = 0, vendor_ie_num = 0, cmdlen;
8352 	struct iw_point *p;
8353 	u8 *ptmp;
8354 
8355 	p = &wrqu->data;
8356 	cmdlen = p->length;
8357 	if (0 == cmdlen)
8358 		return -EINVAL;
8359 
8360 	ptmp = (u8 *)rtw_malloc(cmdlen);
8361 	if (NULL == ptmp)
8362 		return -ENOMEM;
8363 
8364 	if (copy_from_user(ptmp, p->pointer, cmdlen)) {
8365 		ret = -EFAULT;
8366 		goto exit;
8367 	}
8368 	ret = sscanf(ptmp , "%d", &vendor_ie_num);
8369 	if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8370 		ret = -EFAULT;
8371 		goto exit;
8372 	}
8373 
8374 	wrqu->data.length = rtw_vendor_ie_get_data(dev, vendor_ie_num, extra);
8375 
8376 exit:
8377 	rtw_mfree(ptmp, cmdlen);
8378 
8379 	return 0;
8380 }
8381 
8382 int rtw_vendor_ie_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8383 {
8384 	int ret = 0, i , len = 0 , totoal_ie_len = 0 , total_ie_len_byte = 0;
8385 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8386 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8387 	u32 vendor_ie_mask = 0;
8388 	u32 vendor_ie_num = 0;
8389 	u32 vendor_ie_mask_max = BIT(WLAN_MAX_VENDOR_IE_MASK_MAX) - 1;
8390 	u32 id, elen;
8391 
8392 	ret = sscanf(extra, "%d,%x,%*s", &vendor_ie_num , &vendor_ie_mask);
8393 	if (strrchr(extra , ','))
8394 		extra = strrchr(extra , ',') + 1;
8395 	else
8396 		return -EINVAL;
8397 	totoal_ie_len = strlen(extra);
8398 	RTW_INFO("[%s] vendor_ie_num = %d , vendor_ie_mask = 0x%x , vendor_ie = %s , len = %d\n", __func__ , vendor_ie_num , vendor_ie_mask , extra  , totoal_ie_len);
8399 
8400 	if (vendor_ie_num  > WLAN_MAX_VENDOR_IE_NUM - 1) {
8401 		RTW_INFO("[%s] Fail, only support %d vendor ie\n", __func__ , WLAN_MAX_VENDOR_IE_NUM);
8402 		return -EFAULT;
8403 	}
8404 
8405 	if (totoal_ie_len > WLAN_MAX_VENDOR_IE_LEN) {
8406 		RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_VENDOR_IE_LEN);
8407 		return -EFAULT;
8408 	}
8409 
8410 	if (vendor_ie_mask > vendor_ie_mask_max) {
8411 		RTW_INFO("[%s] Fail, not support vendor_ie_mask more than 0x%x\n", __func__ , vendor_ie_mask_max);
8412 		return -EFAULT;
8413 	}
8414 
8415 	if (vendor_ie_mask == 0) {
8416 		RTW_INFO("[%s] Clear vendor_ie_num %d group\n", __func__ , vendor_ie_num);
8417 		goto _clear_path;
8418 	}
8419 
8420 	if (totoal_ie_len % 2 != 0) {
8421 		RTW_INFO("[%s]  Fail , IE length = %zu is odd\n" , __func__ , strlen(extra));
8422 		return -EFAULT;
8423 	}
8424 
8425 	if (totoal_ie_len > 0) {
8426 		for (i = 0  ; i < strlen(extra) ; i += 2) {
8427 			pmlmepriv->vendor_ie[vendor_ie_num][len] = key_2char2num(extra[i] , extra[i + 1]);
8428 			if (len == 0) {
8429 				id = pmlmepriv->vendor_ie[vendor_ie_num][len];
8430 				if (id != WLAN_EID_VENDOR_SPECIFIC) {
8431 					RTW_INFO("[%s] Fail , VENDOR SPECIFIC IE ID \"%x\" was not correct\n", __func__ , id);
8432 					goto _clear_path;
8433 				}
8434 			} else if (len == 1) {
8435 				total_ie_len_byte = (totoal_ie_len / 2) - 2;
8436 				elen = pmlmepriv->vendor_ie[vendor_ie_num][len];
8437 				if (elen != total_ie_len_byte) {
8438 					RTW_INFO("[%s] Fail , Input IE length = \"%d\"(hex:%x) bytes , not match input total IE context length \"%d\" bytes\n", __func__ , elen , elen ,
8439 						 total_ie_len_byte);
8440 					goto _clear_path;
8441 				}
8442 			}
8443 			len++;
8444 		}
8445 		pmlmepriv->vendor_ielen[vendor_ie_num] = len;
8446 	} else
8447 		pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
8448 
8449 
8450 
8451 	if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8452 		RTW_INFO("[%s] Beacon append vendor ie\n", __func__);
8453 	if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8454 		RTW_INFO("[%s] Probe Req append vendor ie\n", __func__);
8455 	if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8456 		RTW_INFO("[%s] Probe Resp append vendor ie\n", __func__);
8457 	if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8458 		RTW_INFO("[%s] Assoc Req append vendor ie\n", __func__);
8459 	if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8460 		RTW_INFO("[%s] Assoc Resp append vendor ie\n", __func__);
8461 #ifdef CONFIG_P2P
8462 	if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)
8463 		RTW_INFO("[%s] P2P Probe Req append vendor ie\n", __func__);
8464 	if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)
8465 		RTW_INFO("[%s] P2P Probe Resp append vendor ie\n", __func__);
8466 #endif
8467 
8468 	pmlmepriv->vendor_ie_mask[vendor_ie_num] = vendor_ie_mask;
8469 
8470 	return ret;
8471 
8472 _clear_path:
8473 	_rtw_memset(pmlmepriv->vendor_ie[vendor_ie_num] , 0 , sizeof(u32) * WLAN_MAX_VENDOR_IE_LEN);
8474 	pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
8475 	pmlmepriv->vendor_ie_mask[vendor_ie_num] = 0;
8476 	return -EFAULT;
8477 }
8478 #endif
8479 
8480 static int rtw_get_ic_type(struct net_device *dev,
8481 				struct iw_request_info *info,
8482 				union iwreq_data *wrqu, char *extra)
8483 {
8484 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8485 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8486 	char *pstring = extra;
8487 	u8 regdata;
8488 
8489 	_rtw_memset(pstring, 0, wrqu->data.length);
8490 
8491 	regdata = (rtw_read32(padapter, 0xF0) & 0xf000) >> 12;
8492 	RTW_INFO("%s: f0[15:12]= 0x%x\n", __FUNCTION__, regdata);
8493 
8494 	if (regdata == 0x04)
8495 		pstring += sprintf(pstring , ":%s\n" ,"rtl8822c-vbs");
8496 	else
8497 		pstring += sprintf(pstring , ":%s\n" ,"rtl8822c-vs");
8498 
8499 	wrqu->data.length = strlen(extra);
8500 
8501 	return 0;
8502 }
8503 
8504 static int rtw_mp_efuse_get(struct net_device *dev,
8505 			    struct iw_request_info *info,
8506 			    union iwreq_data *wdata, char *extra)
8507 {
8508 	PADAPTER padapter = rtw_netdev_priv(dev);
8509 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
8510 
8511 	PEFUSE_HAL pEfuseHal;
8512 	struct iw_point *wrqu;
8513 
8514 	u8 ips_mode = IPS_NUM; /* init invalid value */
8515 	u8 lps_mode = PS_MODE_NUM; /* init invalid value */
8516 	struct pwrctrl_priv *pwrctrlpriv ;
8517 	u8 *data = NULL;
8518 	u8 *rawdata = NULL;
8519 	char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
8520 	u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;
8521 	u16 max_available_len = 0, raw_cursize = 0, raw_maxsize = 0;
8522 	u16 mask_len;
8523 	u8 mask_buf[64] = "";
8524 	int err;
8525 	char *pextra = NULL;
8526 #ifdef CONFIG_IOL
8527 	u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
8528 #endif
8529 
8530 	wrqu = (struct iw_point *)wdata;
8531 	pwrctrlpriv = adapter_to_pwrctl(padapter);
8532 	pEfuseHal = &pHalData->EfuseHal;
8533 
8534 	err = 0;
8535 	data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
8536 	if (data == NULL) {
8537 		err = -ENOMEM;
8538 		goto exit;
8539 	}
8540 	rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
8541 	if (rawdata == NULL) {
8542 		err = -ENOMEM;
8543 		goto exit;
8544 	}
8545 
8546 	if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {
8547 		err = -EFAULT;
8548 		goto exit;
8549 	}
8550 
8551 	*(extra + wrqu->length) = '\0';
8552 
8553 #ifdef CONFIG_LPS
8554 	lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
8555 	rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
8556 #endif
8557 
8558 #ifdef CONFIG_IPS
8559 	ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
8560 	rtw_pm_set_ips(padapter, IPS_NONE);
8561 #endif
8562 
8563 	pch = extra;
8564 	RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
8565 
8566 	i = 0;
8567 	/* mac 16 "00e04c871200" rmap,00,2 */
8568 	while ((token = strsep(&pch, ",")) != NULL) {
8569 		if (i > 2)
8570 			break;
8571 		tmp[i] = token;
8572 		i++;
8573 	}
8574 #ifdef CONFIG_IOL
8575 	padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */
8576 #endif
8577 
8578 	if (strcmp(tmp[0], "status") == 0) {
8579 		sprintf(extra, "Load File efuse=%s,Load File MAC=%s"
8580 			, pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK"
8581 			, pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK"
8582 		       );
8583 		goto exit;
8584 	} else if (strcmp(tmp[0], "drvmap") == 0) {
8585 		static u8 drvmaporder = 0;
8586 		u8 *efuse;
8587 		u32 shift, cnt;
8588 		u32 blksz = 0x200; /* The size of one time show, default 512 */
8589 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
8590 
8591 		efuse = pHalData->efuse_eeprom_data;
8592 
8593 		shift = blksz * drvmaporder;
8594 		efuse += shift;
8595 		cnt = mapLen - shift;
8596 
8597 		if (cnt > blksz) {
8598 			cnt = blksz;
8599 			drvmaporder++;
8600 		} else
8601 			drvmaporder = 0;
8602 
8603 		sprintf(extra, "\n");
8604 		for (i = 0; i < cnt; i += 16) {
8605 			pextra = extra + strlen(extra);
8606 			pextra += sprintf(pextra, "0x%02x\t", shift + i);
8607 			for (j = 0; j < 8; j++)
8608 				pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8609 			pextra += sprintf(pextra, "\t");
8610 			for (; j < 16; j++)
8611 				pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8612 			pextra += sprintf(pextra, "\n");
8613 		}
8614 		if ((shift + cnt) < mapLen)
8615 			pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8616 
8617 	} else if (strcmp(tmp[0], "realmap") == 0) {
8618 		static u8 order = 0;
8619 		u8 *efuse;
8620 		u32 shift, cnt;
8621 		u32 blksz = 0x200; /* The size of one time show, default 512 */
8622 
8623 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
8624 		efuse = pEfuseHal->fakeEfuseInitMap;
8625 		if (rtw_efuse_mask_map_read(padapter, 0, mapLen, efuse) == _FAIL) {
8626 			RTW_INFO("%s: read realmap Fail!!\n", __FUNCTION__);
8627 			err = -EFAULT;
8628 			goto exit;
8629 		}
8630 
8631 #if 0
8632 		RTW_INFO("OFFSET\tVALUE(hex)\n");
8633 		for (i = 0; i < mapLen; i += 16) {
8634 			RTW_INFO("0x%02x\t", i);
8635 			for (j = 0; j < 8; j++)
8636 				RTW_INFO("%02X ", efuse[i + j]);
8637 			RTW_INFO("\t");
8638 			for (; j < 16; j++)
8639 				RTW_INFO("%02X ", efuse[i + j]);
8640 			RTW_INFO("\n");
8641 		}
8642 		RTW_INFO("\n");
8643 #endif
8644 
8645 		shift = blksz * order;
8646 		efuse += shift;
8647 		cnt = mapLen - shift;
8648 		if (cnt > blksz) {
8649 			cnt = blksz;
8650 			order++;
8651 		} else
8652 			order = 0;
8653 
8654 		sprintf(extra, "\n");
8655 		for (i = 0; i < cnt; i += 16) {
8656 			pextra = extra + strlen(extra);
8657 			pextra += sprintf(pextra, "0x%02x\t", shift + i);
8658 			for (j = 0; j < 8; j++)
8659 				pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8660 			pextra += sprintf(pextra, "\t");
8661 			for (; j < 16; j++)
8662 				pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8663 			pextra += sprintf(pextra, "\n");
8664 		}
8665 		if ((shift + cnt) < mapLen)
8666 			pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8667 	} else if (strcmp(tmp[0], "rmap") == 0) {
8668 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8669 			RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
8670 			err = -EINVAL;
8671 			goto exit;
8672 		}
8673 
8674 		/* rmap addr cnts */
8675 		addr = simple_strtoul(tmp[1], &ptmp, 16);
8676 		RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
8677 
8678 		cnts = simple_strtoul(tmp[2], &ptmp, 10);
8679 		if (cnts == 0) {
8680 			RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
8681 			err = -EINVAL;
8682 			goto exit;
8683 		}
8684 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
8685 
8686 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&max_available_len, _FALSE);
8687 		if ((addr + cnts) > max_available_len) {
8688 			RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8689 			err = -EINVAL;
8690 			goto exit;
8691 		}
8692 
8693 		if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8694 			RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
8695 			err = -EFAULT;
8696 			goto exit;
8697 		}
8698 
8699 		/*		RTW_INFO("%s: data={", __FUNCTION__); */
8700 		*extra = 0;
8701 		pextra = extra;
8702 		for (i = 0; i < cnts; i++) {
8703 			/*			RTW_INFO("0x%02x ", data[i]); */
8704 			pextra += sprintf(pextra, "0x%02X ", data[i]);
8705 		}
8706 		/*		RTW_INFO("}\n"); */
8707 	} else if (strcmp(tmp[0], "realraw") == 0) {
8708 		static u8 raw_order = 0;
8709 		u32 shift, cnt;
8710 		u32 blksz = 0x200; /* The size of one time show, default 512 */
8711 
8712 		addr = 0;
8713 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN , (void *)&mapLen, _FALSE);
8714 		RTW_INFO("Real content len = %d\n",mapLen );
8715 
8716 		if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
8717 			RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8718 			err = -EFAULT;
8719 			goto exit;
8720 		}
8721 
8722 		_rtw_memset(extra, '\0', strlen(extra));
8723 
8724 		shift = blksz * raw_order;
8725 		rawdata += shift;
8726 		cnt = mapLen - shift;
8727 		if (cnt > blksz) {
8728 			cnt = blksz;
8729 			raw_order++;
8730 		} else
8731 			raw_order = 0;
8732 
8733 		sprintf(extra, "\n");
8734 		for (i = 0; i < cnt; i += 16) {
8735 			pextra = extra + strlen(extra);
8736 			pextra += sprintf(pextra, "0x%02x\t", shift + i);
8737 			for (j = 0; j < 8; j++)
8738 				pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8739 			pextra += sprintf(pextra, "\t");
8740 			for (; j < 16; j++)
8741 				pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8742 			pextra += sprintf(pextra, "\n");
8743 		}
8744 		if ((shift + cnt) < mapLen)
8745 			pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8746 
8747 	} else if (strcmp(tmp[0], "btrealraw") == 0) {
8748 		static u8 bt_raw_order = 0;
8749 		u32 shift, cnt;
8750 		u32 blksz = 0x200; /* The size of one time show, default 512 */
8751 
8752 		addr = 0;
8753 		EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&mapLen, _FALSE);
8754 		RTW_INFO("Real content len = %d\n", mapLen);
8755 #ifdef RTW_HALMAC
8756 		if (rtw_efuse_bt_access(padapter, _FALSE, 0, mapLen, rawdata) == _FAIL) {
8757 			RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8758 			err = -EFAULT;
8759 			goto exit;
8760 		}
8761 #else
8762 		rtw_write8(padapter, 0x35, 0x1);
8763 
8764 		if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
8765 			RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8766 			err = -EFAULT;
8767 			goto exit;
8768 		}
8769 #endif
8770 		_rtw_memset(extra, '\0', strlen(extra));
8771 
8772 		shift = blksz * bt_raw_order;
8773 		rawdata += shift;
8774 		cnt = mapLen - shift;
8775 		if (cnt > blksz) {
8776 			cnt = blksz;
8777 			bt_raw_order++;
8778 		} else
8779 			bt_raw_order = 0;
8780 
8781 		sprintf(extra, "\n");
8782 		for (i = 0; i < cnt; i += 16) {
8783 			pextra = extra + strlen(extra);
8784 			pextra += sprintf(pextra, "0x%02x\t", shift + i);
8785 			for (j = 0; j < 8; j++)
8786 				pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8787 			pextra += sprintf(pextra, "\t");
8788 			for (; j < 16; j++)
8789 				pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8790 			pextra += sprintf(pextra, "\n");
8791 		}
8792 		if ((shift + cnt) < mapLen)
8793 			pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8794 
8795 	} else if (strcmp(tmp[0], "mac") == 0) {
8796 		if (hal_efuse_macaddr_offset(padapter) == -1) {
8797 			err = -EFAULT;
8798 			goto exit;
8799 		}
8800 
8801 		addr = hal_efuse_macaddr_offset(padapter);
8802 		cnts = 6;
8803 
8804 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8805 		if ((addr + cnts) > max_available_len) {
8806 			RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8807 			err = -EFAULT;
8808 			goto exit;
8809 		}
8810 
8811 		if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8812 			RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
8813 			err = -EFAULT;
8814 			goto exit;
8815 		}
8816 
8817 		/*		RTW_INFO("%s: MAC address={", __FUNCTION__); */
8818 		*extra = 0;
8819 		pextra = extra;
8820 		for (i = 0; i < cnts; i++) {
8821 			/*			RTW_INFO("%02X", data[i]); */
8822 			pextra += sprintf(pextra, "%02X", data[i]);
8823 			if (i != (cnts - 1)) {
8824 				/*				RTW_INFO(":"); */
8825 				pextra += sprintf(pextra, ":");
8826 			}
8827 		}
8828 		/*		RTW_INFO("}\n"); */
8829 	} else if (strcmp(tmp[0], "vidpid") == 0) {
8830 #ifdef CONFIG_RTL8188E
8831 #ifdef CONFIG_USB_HCI
8832 		addr = EEPROM_VID_88EU;
8833 #endif
8834 #ifdef CONFIG_PCI_HCI
8835 		addr = EEPROM_VID_88EE;
8836 #endif
8837 #endif /* CONFIG_RTL8188E */
8838 
8839 #ifdef CONFIG_RTL8192E
8840 #ifdef CONFIG_USB_HCI
8841 		addr = EEPROM_VID_8192EU;
8842 #endif
8843 #ifdef CONFIG_PCI_HCI
8844 		addr = EEPROM_VID_8192EE;
8845 #endif
8846 #endif /* CONFIG_RTL8192E */
8847 #ifdef CONFIG_RTL8723B
8848 		addr = EEPROM_VID_8723BU;
8849 #endif /* CONFIG_RTL8192E */
8850 
8851 #ifdef CONFIG_RTL8188F
8852 		addr = EEPROM_VID_8188FU;
8853 #endif /* CONFIG_RTL8188F */
8854 
8855 #ifdef CONFIG_RTL8188GTV
8856 		addr = EEPROM_VID_8188GTVU;
8857 #endif
8858 
8859 #ifdef CONFIG_RTL8703B
8860 #ifdef CONFIG_USB_HCI
8861 		addr = EEPROM_VID_8703BU;
8862 #endif
8863 #endif /* CONFIG_RTL8703B */
8864 
8865 #ifdef CONFIG_RTL8723D
8866 #ifdef CONFIG_USB_HCI
8867 		addr = EEPROM_VID_8723DU;
8868 #endif /* CONFIG_USB_HCI */
8869 #endif /* CONFIG_RTL8723D */
8870 
8871 		cnts = 4;
8872 
8873 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8874 		if ((addr + cnts) > max_available_len) {
8875 			RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8876 			err = -EFAULT;
8877 			goto exit;
8878 		}
8879 		if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8880 			RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
8881 			err = -EFAULT;
8882 			goto exit;
8883 		}
8884 
8885 		/*		RTW_INFO("%s: {VID,PID}={", __FUNCTION__); */
8886 		*extra = 0;
8887 		pextra = extra;
8888 		for (i = 0; i < cnts; i++) {
8889 			/*			RTW_INFO("0x%02x", data[i]); */
8890 			pextra += sprintf(pextra, "0x%02X", data[i]);
8891 			if (i != (cnts - 1)) {
8892 				/*				RTW_INFO(","); */
8893 				pextra += sprintf(pextra, ",");
8894 			}
8895 		}
8896 		/*		RTW_INFO("}\n"); */
8897 	} else if (strcmp(tmp[0], "ableraw") == 0) {
8898 #ifdef RTW_HALMAC
8899 		raw_maxsize = efuse_GetavailableSize(padapter);
8900 #else
8901 		efuse_GetCurrentSize(padapter, &raw_cursize);
8902 		raw_maxsize = efuse_GetMaxSize(padapter);
8903 #endif
8904 		sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
8905 	} else if (strcmp(tmp[0], "btableraw") == 0) {
8906 		efuse_bt_GetCurrentSize(padapter, &raw_cursize);
8907 		raw_maxsize = efuse_bt_GetMaxSize(padapter);
8908 		sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
8909 	} else if (strcmp(tmp[0], "btfmap") == 0) {
8910 
8911 		BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8912 
8913 		mapLen = EFUSE_BT_MAX_MAP_LEN;
8914 		if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
8915 			RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
8916 			err = -EFAULT;
8917 			goto exit;
8918 		}
8919 
8920 		/*		RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8921 		sprintf(extra, "\n");
8922 		for (i = 0; i < 512; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */
8923 			/*			RTW_INFO("0x%03x\t", i); */
8924 			pextra = extra + strlen(extra);
8925 			pextra += sprintf(pextra, "0x%03x\t", i);
8926 			for (j = 0; j < 8; j++) {
8927 				/*				RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
8928 				pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8929 			}
8930 			/*			RTW_INFO("\t"); */
8931 			pextra += sprintf(pextra, "\t");
8932 			for (; j < 16; j++) {
8933 				/*				RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
8934 				pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8935 			}
8936 			/*			RTW_INFO("\n"); */
8937 			pextra += sprintf(pextra, "\n");
8938 		}
8939 		/*		RTW_INFO("\n"); */
8940 	} else if (strcmp(tmp[0], "btbmap") == 0) {
8941 		BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8942 
8943 		mapLen = EFUSE_BT_MAX_MAP_LEN;
8944 		if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
8945 			RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
8946 			err = -EFAULT;
8947 			goto exit;
8948 		}
8949 
8950 		/*		RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8951 		sprintf(extra, "\n");
8952 		for (i = 512; i < 1024 ; i += 16) {
8953 			/*			RTW_INFO("0x%03x\t", i); */
8954 			pextra = extra + strlen(extra);
8955 			pextra += sprintf(pextra, "0x%03x\t", i);
8956 			for (j = 0; j < 8; j++) {
8957 				/*				RTW_INFO("%02X ", data[i+j]); */
8958 				pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8959 			}
8960 			/*			RTW_INFO("\t"); */
8961 			pextra += sprintf(pextra, "\t");
8962 			for (; j < 16; j++) {
8963 				/*				RTW_INFO("%02X ", data[i+j]); */
8964 				pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8965 			}
8966 			/*			RTW_INFO("\n"); */
8967 			pextra += sprintf(pextra, "\n");
8968 		}
8969 		/*		RTW_INFO("\n"); */
8970 	} else if (strcmp(tmp[0], "btrmap") == 0) {
8971 		u8 BTStatus;
8972 
8973 		rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
8974 		BTStatus = rtw_read8(padapter, 0xa0);
8975 
8976 		RTW_INFO("%s: Check 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
8977 		if (BTStatus != 0x04) {
8978 			sprintf(extra, "BT Status not Active ,can't to read BT eFuse\n");
8979 			goto exit;
8980 		}
8981 
8982 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8983 			err = -EINVAL;
8984 			goto exit;
8985 		}
8986 
8987 		BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8988 
8989 		/* rmap addr cnts */
8990 		addr = simple_strtoul(tmp[1], &ptmp, 16);
8991 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
8992 
8993 		cnts = simple_strtoul(tmp[2], &ptmp, 10);
8994 		if (cnts == 0) {
8995 			RTW_INFO("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
8996 			err = -EINVAL;
8997 			goto exit;
8998 		}
8999 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9000 #ifndef RTW_HALMAC
9001 		EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9002 		if ((addr + cnts) > max_available_len) {
9003 			RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9004 			err = -EFAULT;
9005 			goto exit;
9006 		}
9007 #endif
9008 		if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
9009 			RTW_INFO("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
9010 			err = -EFAULT;
9011 			goto exit;
9012 		}
9013 
9014 		*extra = 0;
9015 		pextra = extra;
9016 		/*		RTW_INFO("%s: bt efuse data={", __FUNCTION__); */
9017 		for (i = 0; i < cnts; i++) {
9018 			/*			RTW_INFO("0x%02x ", data[i]); */
9019 			pextra += sprintf(pextra, " 0x%02X ", data[i]);
9020 		}
9021 		/*		RTW_INFO("}\n"); */
9022 		RTW_INFO(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
9023 	} else if (strcmp(tmp[0], "btffake") == 0) {
9024 		/*		RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9025 		sprintf(extra, "\n");
9026 		for (i = 0; i < 512; i += 16) {
9027 			/*			RTW_INFO("0x%03x\t", i); */
9028 			pextra = extra + strlen(extra);
9029 			pextra += sprintf(pextra, "0x%03x\t", i);
9030 			for (j = 0; j < 8; j++) {
9031 				/*				RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9032 				pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9033 			}
9034 			/*			RTW_INFO("\t"); */
9035 			pextra += sprintf(pextra, "\t");
9036 			for (; j < 16; j++) {
9037 				/*				RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9038 				pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9039 			}
9040 			/*			RTW_INFO("\n"); */
9041 			pextra += sprintf(pextra, "\n");
9042 		}
9043 		/*		RTW_INFO("\n"); */
9044 	} else if (strcmp(tmp[0], "btbfake") == 0) {
9045 		/*		RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9046 		sprintf(extra, "\n");
9047 		for (i = 512; i < 1024; i += 16) {
9048 			/*			RTW_INFO("0x%03x\t", i); */
9049 			pextra = extra + strlen(extra);
9050 			pextra += sprintf(pextra, "0x%03x\t", i);
9051 			for (j = 0; j < 8; j++) {
9052 				/*				RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9053 				pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9054 			}
9055 			/*			RTW_INFO("\t"); */
9056 			pextra += sprintf(pextra, "\t");
9057 			for (; j < 16; j++) {
9058 				/*				RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9059 				pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9060 			}
9061 			/*			RTW_INFO("\n"); */
9062 			pextra += sprintf(pextra, "\n");
9063 		}
9064 		/*		RTW_INFO("\n"); */
9065 	} else if (strcmp(tmp[0], "wlrfkmap") == 0) {
9066 		static u8 fk_order = 0;
9067 		u8 *efuse;
9068 		u32 shift, cnt;
9069 		u32 blksz = 0x200; /* The size of one time show, default 512 */
9070 
9071 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
9072 		efuse = pEfuseHal->fakeEfuseModifiedMap;
9073 
9074 		shift = blksz * fk_order;
9075 		efuse += shift;
9076 		cnt = mapLen - shift;
9077 		if (cnt > blksz) {
9078 			cnt = blksz;
9079 			fk_order++;
9080 		} else
9081 			fk_order = 0;
9082 
9083 		sprintf(extra, "\n");
9084 		for (i = 0; i < cnt; i += 16) {
9085 			pextra = extra + strlen(extra);
9086 			pextra += sprintf(pextra, "0x%02x\t", shift + i);
9087 			for (j = 0; j < 8; j++)
9088 				pextra += sprintf(pextra, "%02X ", efuse[i + j]);
9089 			pextra += sprintf(pextra, "\t");
9090 			for (; j < 16; j++)
9091 				pextra += sprintf(pextra, "%02X ", efuse[i + j]);
9092 			pextra += sprintf(pextra, "\n");
9093 		}
9094 		if ((shift + cnt) < mapLen)
9095 			pextra += sprintf(pextra, "\t...more\n");
9096 
9097 	} else if (strcmp(tmp[0], "wlrfkrmap") == 0) {
9098 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9099 			RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9100 			err = -EINVAL;
9101 			goto exit;
9102 		}
9103 		/* rmap addr cnts */
9104 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9105 		RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9106 
9107 		cnts = simple_strtoul(tmp[2], &ptmp, 10);
9108 		if (cnts == 0) {
9109 			RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9110 			err = -EINVAL;
9111 			goto exit;
9112 		}
9113 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9114 
9115 		/*		RTW_INFO("%s: data={", __FUNCTION__); */
9116 		*extra = 0;
9117 		pextra = extra;
9118 		for (i = 0; i < cnts; i++) {
9119 			RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9120 			pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9121 		}
9122 	} else if (strcmp(tmp[0], "btrfkrmap") == 0) {
9123 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9124 			RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9125 			err = -EINVAL;
9126 			goto exit;
9127 		}
9128 		/* rmap addr cnts */
9129 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9130 		RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9131 
9132 		cnts = simple_strtoul(tmp[2], &ptmp, 10);
9133 		if (cnts == 0) {
9134 			RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9135 			err = -EINVAL;
9136 			goto exit;
9137 		}
9138 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9139 
9140 		/*		RTW_INFO("%s: data={", __FUNCTION__); */
9141 		*extra = 0;
9142 		pextra = extra;
9143 		for (i = 0; i < cnts; i++) {
9144 			RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeBTEfuseModifiedMap[addr + i]);
9145 			pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9146 		}
9147 	} else if (strcmp(tmp[0], "mask") == 0) {
9148 		*extra = 0;
9149 		mask_len = sizeof(u8) * rtw_get_efuse_mask_arraylen(padapter);
9150 		rtw_efuse_mask_array(padapter, mask_buf);
9151 
9152 		if (padapter->registrypriv.bFileMaskEfuse == _TRUE)
9153 			_rtw_memcpy(mask_buf, maskfileBuffer, mask_len);
9154 
9155 		sprintf(extra, "\n");
9156 		pextra = extra + strlen(extra);
9157 		for (i = 0; i < mask_len; i++)
9158 			pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);
9159 
9160 	} else if (strcmp(tmp[0], "btmask") == 0) {
9161 		*extra = 0;
9162 		mask_len = sizeof(u8) * rtw_get_bt_efuse_mask_arraylen(padapter);
9163 		rtw_bt_efuse_mask_array(padapter, mask_buf);
9164 
9165 		if (padapter->registrypriv.bBTFileMaskEfuse == _TRUE)
9166 			_rtw_memcpy(mask_buf, btmaskfileBuffer, mask_len);
9167 
9168 		sprintf(extra, "\n");
9169 		pextra = extra + strlen(extra);
9170 		for (i = 0; i < mask_len; i++)
9171 			pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);
9172 
9173 	} else
9174 		sprintf(extra, "Command not found!");
9175 
9176 exit:
9177 	if (data)
9178 		rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9179 	if (rawdata)
9180 		rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9181 	if (!err)
9182 		wrqu->length = strlen(extra);
9183 
9184 	if (padapter->registrypriv.mp_mode == 0) {
9185 #ifdef CONFIG_IPS
9186 		rtw_pm_set_ips(padapter, ips_mode);
9187 #endif /* CONFIG_IPS */
9188 
9189 #ifdef CONFIG_LPS
9190 		rtw_pm_set_lps(padapter, lps_mode);
9191 #endif /* CONFIG_LPS */
9192 	}
9193 
9194 #ifdef CONFIG_IOL
9195 	padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
9196 #endif
9197 	return err;
9198 }
9199 
9200 
9201 #ifdef CONFIG_MP_INCLUDED
9202 static int rtw_mp_efuse_set(struct net_device *dev,
9203 			    struct iw_request_info *info,
9204 			    union iwreq_data *wdata, char *extra)
9205 {
9206 	struct iw_point *wrqu;
9207 	PADAPTER padapter;
9208 	struct pwrctrl_priv *pwrctrlpriv ;
9209 	PHAL_DATA_TYPE pHalData;
9210 	PEFUSE_HAL pEfuseHal;
9211 	struct hal_ops *pHalFunc;
9212 	struct mp_priv *pmp_priv;
9213 
9214 	u8 ips_mode = IPS_NUM; /* init invalid value */
9215 	u8 lps_mode = PS_MODE_NUM; /* init invalid value */
9216 	u32 i = 0, j = 0, jj, kk;
9217 	u8 *setdata = NULL;
9218 	u8 *ShadowMapBT = NULL;
9219 	u8 *ShadowMapWiFi = NULL;
9220 	u8 *setrawdata = NULL;
9221 	char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
9222 	u16 addr = 0xFF, cnts = 0, BTStatus = 0 , max_available_len = 0;
9223 	u16 wifimaplen;
9224 	int err;
9225 	boolean bcmpchk = _TRUE;
9226 
9227 
9228 	wrqu = (struct iw_point *)wdata;
9229 	padapter = rtw_netdev_priv(dev);
9230 	pwrctrlpriv = adapter_to_pwrctl(padapter);
9231 	pHalData = GET_HAL_DATA(padapter);
9232 	pEfuseHal = &pHalData->EfuseHal;
9233 	pHalFunc = &padapter->hal_func;
9234 	pmp_priv = &padapter->mppriv;
9235 
9236 	err = 0;
9237 
9238 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9239 		return -EFAULT;
9240 #ifdef CONFIG_RTL8822C
9241 	rtw_pre_bt_efuse(padapter);
9242 #endif
9243 	*(extra + wrqu->length) = '\0';
9244 
9245 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&wifimaplen, _FALSE);
9246 
9247 	setdata = rtw_zmalloc(1024);
9248 	if (setdata == NULL) {
9249 		err = -ENOMEM;
9250 		goto exit;
9251 	}
9252 	ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9253 	if (ShadowMapBT == NULL) {
9254 		err = -ENOMEM;
9255 		goto exit;
9256 	}
9257 	ShadowMapWiFi = rtw_malloc(wifimaplen);
9258 	if (ShadowMapWiFi == NULL) {
9259 		err = -ENOMEM;
9260 		goto exit;
9261 	}
9262 	setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9263 	if (setrawdata == NULL) {
9264 		err = -ENOMEM;
9265 		goto exit;
9266 	}
9267 
9268 #ifdef CONFIG_LPS
9269 	lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
9270 	rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
9271 #endif
9272 
9273 #ifdef CONFIG_IPS
9274 	ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
9275 	rtw_pm_set_ips(padapter, IPS_NONE);
9276 #endif
9277 
9278 	pch = extra;
9279 	RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
9280 
9281 	i = 0;
9282 	while ((token = strsep(&pch, ",")) != NULL) {
9283 		if (i > 2)
9284 			break;
9285 		tmp[i] = token;
9286 		i++;
9287 	}
9288 
9289 	/* tmp[0],[1],[2] */
9290 	/* wmap,addr,00e04c871200 */
9291 	if (strcmp(tmp[0], "wmap") == 0) {
9292 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9293 			err = -EINVAL;
9294 			goto exit;
9295 		}
9296 
9297 #ifndef RTW_HALMAC
9298 		/* unknown bug workaround, need to fix later */
9299 		addr = 0x1ff;
9300 		rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9301 		rtw_msleep_os(10);
9302 		rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9303 		rtw_msleep_os(10);
9304 		rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9305 		rtw_msleep_os(10);
9306 		rtw_read8(padapter, EFUSE_CTRL);
9307 #endif /* RTW_HALMAC */
9308 
9309 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9310 		addr &= 0xFFF;
9311 
9312 		cnts = strlen(tmp[2]);
9313 		if (cnts % 2) {
9314 			err = -EINVAL;
9315 			goto exit;
9316 		}
9317 		cnts /= 2;
9318 		if (cnts == 0) {
9319 			err = -EINVAL;
9320 			goto exit;
9321 		}
9322 
9323 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9324 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9325 		RTW_INFO("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9326 
9327 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9328 			setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9329 
9330 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9331 
9332 		if ((addr + cnts) > max_available_len) {
9333 			RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9334 			err = -EFAULT;
9335 			goto exit;
9336 		}
9337 
9338 		if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9339 			RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9340 			err = -EFAULT;
9341 			goto exit;
9342 		}
9343 		*extra = 0;
9344 		RTW_INFO("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__);
9345 		if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS) {
9346 			if (_rtw_memcmp((void *)ShadowMapWiFi , (void *)setdata, cnts)) {
9347 				RTW_INFO("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9348 				sprintf(extra, "WiFi write map compare OK\n");
9349 				err = 0;
9350 				goto exit;
9351 			} else {
9352 				sprintf(extra, "WiFi write map compare FAIL\n");
9353 				RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9354 				err = 0;
9355 				goto exit;
9356 			}
9357 		}
9358 	} else if (strcmp(tmp[0], "wraw") == 0) {
9359 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9360 			err = -EINVAL;
9361 			goto exit;
9362 		}
9363 
9364 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9365 		addr &= 0xFFF;
9366 
9367 		cnts = strlen(tmp[2]);
9368 		if (cnts % 2) {
9369 			err = -EINVAL;
9370 			goto exit;
9371 		}
9372 		cnts /= 2;
9373 		if (cnts == 0) {
9374 			err = -EINVAL;
9375 			goto exit;
9376 		}
9377 
9378 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9379 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9380 		RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9381 
9382 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9383 			setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9384 
9385 		if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9386 			RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9387 			err = -EFAULT;
9388 			goto exit;
9389 		}
9390 	} else if (strcmp(tmp[0], "btwraw") == 0) {
9391 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9392 			err = -EINVAL;
9393 			goto exit;
9394 		}
9395 
9396 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9397 		addr &= 0xFFF;
9398 
9399 		cnts = strlen(tmp[2]);
9400 		if (cnts % 2) {
9401 			err = -EINVAL;
9402 			goto exit;
9403 		}
9404 		cnts /= 2;
9405 		if (cnts == 0) {
9406 			err = -EINVAL;
9407 			goto exit;
9408 		}
9409 
9410 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9411 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9412 		RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9413 
9414 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9415 			setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9416 #ifdef RTW_HALMAC
9417 		if (rtw_efuse_bt_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9418 			RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9419 			err = -EFAULT;
9420 			goto exit;
9421 		}
9422 #else
9423 		rtw_write8(padapter, 0x35, 1); /* switch bank 1 (BT)*/
9424 		if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9425 			RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9426 			rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9427 			err = -EFAULT;
9428 			goto exit;
9429 		}
9430 		rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9431 #endif
9432 	} else if (strcmp(tmp[0], "mac") == 0) {
9433 		if (tmp[1] == NULL) {
9434 			err = -EINVAL;
9435 			goto exit;
9436 		}
9437 
9438 		/* mac,00e04c871200 */
9439 
9440 		if (hal_efuse_macaddr_offset(padapter) == -1) {
9441 			err = -EFAULT;
9442 			goto exit;
9443 		}
9444 
9445 		addr = hal_efuse_macaddr_offset(padapter);
9446 		cnts = strlen(tmp[1]);
9447 		if (cnts % 2) {
9448 			err = -EINVAL;
9449 			goto exit;
9450 		}
9451 		cnts /= 2;
9452 		if (cnts == 0) {
9453 			err = -EINVAL;
9454 			goto exit;
9455 		}
9456 		if (cnts > 6) {
9457 			RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9458 			err = -EFAULT;
9459 			goto exit;
9460 		}
9461 
9462 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9463 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9464 		RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9465 
9466 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9467 			setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9468 
9469 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9470 
9471 		if ((addr + cnts) > max_available_len) {
9472 			RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9473 			err = -EFAULT;
9474 			goto exit;
9475 		}
9476 
9477 		if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9478 			RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9479 			err = -EFAULT;
9480 			goto exit;
9481 		}
9482 	} else if (strcmp(tmp[0], "vidpid") == 0) {
9483 		if (tmp[1] == NULL) {
9484 			err = -EINVAL;
9485 			goto exit;
9486 		}
9487 
9488 		/* pidvid,da0b7881		 */
9489 #ifdef CONFIG_RTL8188E
9490 #ifdef CONFIG_USB_HCI
9491 		addr = EEPROM_VID_88EU;
9492 #endif
9493 #ifdef CONFIG_PCI_HCI
9494 		addr = EEPROM_VID_88EE;
9495 #endif
9496 #endif /* CONFIG_RTL8188E */
9497 
9498 #ifdef CONFIG_RTL8192E
9499 #ifdef CONFIG_USB_HCI
9500 		addr = EEPROM_VID_8192EU;
9501 #endif
9502 #ifdef CONFIG_PCI_HCI
9503 		addr = EEPROM_VID_8192EE;
9504 #endif
9505 #endif /* CONFIG_RTL8188E */
9506 
9507 #ifdef CONFIG_RTL8723B
9508 		addr = EEPROM_VID_8723BU;
9509 #endif
9510 
9511 #ifdef CONFIG_RTL8188F
9512 		addr = EEPROM_VID_8188FU;
9513 #endif
9514 
9515 #ifdef CONFIG_RTL8188GTV
9516 		addr = EEPROM_VID_8188GTVU;
9517 #endif
9518 
9519 #ifdef CONFIG_RTL8703B
9520 #ifdef CONFIG_USB_HCI
9521 		addr = EEPROM_VID_8703BU;
9522 #endif /* CONFIG_USB_HCI */
9523 #endif /* CONFIG_RTL8703B */
9524 
9525 #ifdef CONFIG_RTL8723D
9526 #ifdef CONFIG_USB_HCI
9527 		addr = EEPROM_VID_8723DU;
9528 #endif /* CONFIG_USB_HCI */
9529 #endif /* CONFIG_RTL8723D */
9530 
9531 		cnts = strlen(tmp[1]);
9532 		if (cnts % 2) {
9533 			err = -EINVAL;
9534 			goto exit;
9535 		}
9536 		cnts /= 2;
9537 		if (cnts == 0) {
9538 			err = -EINVAL;
9539 			goto exit;
9540 		}
9541 
9542 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9543 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9544 		RTW_INFO("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
9545 
9546 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9547 			setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9548 
9549 		EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9550 		if ((addr + cnts) > max_available_len) {
9551 			RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9552 			err = -EFAULT;
9553 			goto exit;
9554 		}
9555 
9556 		if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9557 			RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9558 			err = -EFAULT;
9559 			goto exit;
9560 		}
9561 	} else if (strcmp(tmp[0], "wldumpfake") == 0) {
9562 		if (wifimaplen > EFUSE_MAX_MAP_LEN)
9563 			cnts = EFUSE_MAX_MAP_LEN;
9564 		else
9565 			cnts = wifimaplen;
9566 		if (rtw_efuse_mask_map_read(padapter, 0, cnts, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS)
9567 			RTW_INFO("%s: WiFi hw efuse dump to Fake map success\n", __func__);
9568 		else {
9569 			RTW_INFO("%s: WiFi hw efuse dump to Fake map Fail\n", __func__);
9570 			err = -EFAULT;
9571 		}
9572 	} else if (strcmp(tmp[0], "btwmap") == 0) {
9573 		rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
9574 		BTStatus = rtw_read8(padapter, 0xa0);
9575 		RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9576 		if (BTStatus != 0x04) {
9577 			sprintf(extra, "BT Status not Active ,can't do Write\n");
9578 			goto exit;
9579 		}
9580 
9581 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9582 			err = -EINVAL;
9583 			goto exit;
9584 		}
9585 
9586 #ifndef RTW_HALMAC
9587 		BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9588 		addr = 0x1ff;
9589 		rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9590 		rtw_msleep_os(10);
9591 		rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9592 		rtw_msleep_os(10);
9593 		rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9594 		rtw_msleep_os(10);
9595 		rtw_read8(padapter, EFUSE_CTRL);
9596 		BTEfuse_PowerSwitch(padapter, 1, _FALSE);
9597 #endif /* RTW_HALMAC */
9598 
9599 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9600 		addr &= 0xFFF;
9601 
9602 		cnts = strlen(tmp[2]);
9603 		if (cnts % 2) {
9604 			err = -EINVAL;
9605 			goto exit;
9606 		}
9607 		cnts /= 2;
9608 		if (cnts == 0) {
9609 			err = -EINVAL;
9610 			goto exit;
9611 		}
9612 
9613 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9614 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9615 		RTW_INFO("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
9616 
9617 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9618 			setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9619 #ifndef RTW_HALMAC
9620 		EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9621 		if ((addr + cnts) > max_available_len) {
9622 			RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9623 			err = -EFAULT;
9624 			goto exit;
9625 		}
9626 #endif
9627 		if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9628 			RTW_INFO("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
9629 			sprintf(extra, "BT write FAIL !!!\n");
9630 			err = -EFAULT;
9631 			goto exit;
9632 		}
9633 		*extra = 0;
9634 		RTW_INFO("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __FUNCTION__);
9635 		if ((rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT) == _SUCCESS)) {
9636 			if (_rtw_memcmp((void *)ShadowMapBT , (void *)setdata, cnts)) {
9637 				RTW_INFO("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9638 				sprintf(extra, "BT write map compare OK");
9639 				err = 0;
9640 				goto exit;
9641 			} else {
9642 				sprintf(extra, "BT write map compare FAIL");
9643 				RTW_INFO("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9644 				err = 0;
9645 				goto exit;
9646 			}
9647 		}
9648 	} else if (strcmp(tmp[0], "btwfake") == 0) {
9649 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9650 			err = -EINVAL;
9651 			goto exit;
9652 		}
9653 		if (pmp_priv->bprocess_mp_mode != _TRUE) {
9654 			RTW_INFO("%s: btwfake not to be exec, please first to mp_start\n", __FUNCTION__);
9655 			sprintf(extra, "Error, btwfake cant to be exec, please first to mp_start !!!!\n");
9656 			err = 0;
9657 			goto exit;
9658 		}
9659 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9660 		addr &= 0xFFF;
9661 
9662 		cnts = strlen(tmp[2]);
9663 		if (cnts % 2) {
9664 			err = -EINVAL;
9665 			goto exit;
9666 		}
9667 		cnts /= 2;
9668 		if (cnts == 0) {
9669 			err = -EINVAL;
9670 			goto exit;
9671 		}
9672 
9673 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9674 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9675 		RTW_INFO("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
9676 
9677 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9678 			pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9679 	} else if (strcmp(tmp[0], "btdumpfake") == 0) {
9680 		if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS)
9681 			RTW_INFO("%s: BT read all map success\n", __FUNCTION__);
9682 		else {
9683 			RTW_INFO("%s: BT read all map Fail!\n", __FUNCTION__);
9684 			err = -EFAULT;
9685 		}
9686 	} else if (strcmp(tmp[0], "btfk2map") == 0) {
9687 #ifdef CONFIG_BT_EFUSE_MASK
9688 		if (padapter->registrypriv.bBTFileMaskEfuse != _TRUE && pmp_priv->bloadBTefusemap == _TRUE) {
9689 			RTW_INFO("%s: File BT eFuse mask file not to be loaded\n", __FUNCTION__);
9690 			sprintf(extra, "Not load BT eFuse mask file yet, Please advance to use [ efuse_bt_mask ], now remove the Adapter.!!!!\n");
9691 			rtw_set_surprise_removed(padapter);
9692 			err = 0;
9693 			goto exit;
9694 		}
9695 #endif
9696 		rtw_write8(padapter, 0xa3, 0x05);
9697 		BTStatus = rtw_read8(padapter, 0xa0);
9698 		RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9699 		if (BTStatus != 0x04) {
9700 			sprintf(extra, "BT Status not Active Write FAIL\n");
9701 			goto exit;
9702 		}
9703 		if (pmp_priv->bprocess_mp_mode != _TRUE) {
9704 			RTW_INFO("%s: btfk2map not to be exec, please first to mp_start\n", __FUNCTION__);
9705 			sprintf(extra, "Error, btfk2map cant to be exec, please first to mp_start !!!!\n");
9706 			err = 0;
9707 			goto exit;
9708 		}
9709 #ifndef RTW_HALMAC
9710 		BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9711 		addr = 0x1ff;
9712 		rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9713 		rtw_msleep_os(10);
9714 		rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9715 		rtw_msleep_os(10);
9716 		rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9717 		rtw_msleep_os(10);
9718 		rtw_read8(padapter, EFUSE_CTRL);
9719 		BTEfuse_PowerSwitch(padapter, 1, _FALSE);
9720 #endif /* RTW_HALMAC */
9721 
9722 		if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {
9723 			RTW_INFO("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
9724 			sprintf(extra, "BT write FAIL !!!\n");
9725 			err = -EFAULT;
9726 			goto exit;
9727 		}
9728 
9729 		RTW_INFO("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
9730 		for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
9731 			printk("0x%02x\t", i);
9732 			for (j = 0; j < 8; j++)
9733 				printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9734 			printk("\t");
9735 
9736 			for (; j < 16; j++)
9737 				printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9738 			printk("\n");
9739 		}
9740 		printk("\n");
9741 #if 1
9742 		err = -EFAULT;
9743 		RTW_INFO("%s: rtw_BT_efuse_map_read _rtw_memcmp\n", __FUNCTION__);
9744 		if ((rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)) {
9745 			if (_rtw_memcmp((void *)pEfuseHal->fakeBTEfuseModifiedMap, (void *)pEfuseHal->fakeBTEfuseInitMap, EFUSE_BT_MAX_MAP_LEN)) {
9746 				sprintf(extra, "BT write map compare OK");
9747 				RTW_INFO("%s: BT write map afterf compare success BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9748 				err = 0;
9749 				goto exit;
9750 			} else {
9751 				sprintf(extra, "BT write map compare FAIL");
9752 				if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
9753 					RTW_INFO("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__, i);
9754 
9755 				if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS) {
9756 					RTW_INFO("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
9757 
9758 					for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
9759 						printk("0x%02x\t", i);
9760 						for (j = 0; j < 8; j++)
9761 							printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
9762 						printk("\t");
9763 						for (; j < 16; j++)
9764 							printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
9765 						printk("\n");
9766 					}
9767 					printk("\n");
9768 				}
9769 				RTW_INFO("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9770 				goto exit;
9771 			}
9772 		}
9773 #endif
9774 
9775 	} else if (strcmp(tmp[0], "wlfk2map") == 0) {
9776 		*extra = 0;
9777 
9778 		if (padapter->registrypriv.bFileMaskEfuse != _TRUE && pmp_priv->bloadefusemap == _TRUE) {
9779 			RTW_INFO("%s: File eFuse mask file not to be loaded\n", __FUNCTION__);
9780 			sprintf(extra, "Not load eFuse mask file yet, Please use the efuse_mask CMD, now remove the interface !!!!\n");
9781 			rtw_set_surprise_removed(padapter);
9782 			err = 0;
9783 			goto exit;
9784 		}
9785 
9786 		if (pmp_priv->bprocess_mp_mode != _TRUE) {
9787 			RTW_INFO("%s: wlfk2map not to be exec, please first to mp_start\n", __FUNCTION__);
9788 			sprintf(extra, "Error, wlfk2map cant to be exec, please first to mp_start !!!!\n");
9789 			err = 0;
9790 			goto exit;
9791 		}
9792 		if (wifimaplen > EFUSE_MAX_MAP_LEN)
9793 			cnts = EFUSE_MAX_MAP_LEN;
9794 		else
9795 			cnts = wifimaplen;
9796 		if (rtw_efuse_map_write(padapter, 0x00, cnts, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {
9797 			RTW_INFO("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
9798 			err = -EFAULT;
9799 			goto exit;
9800 		}
9801 
9802 		if (rtw_efuse_mask_map_read(padapter, 0x00, wifimaplen, ShadowMapWiFi) == _SUCCESS) {
9803 			addr = 0x00;
9804 			err = _TRUE;
9805 
9806 			for (i = 0; i < cnts; i++) {
9807 				if (padapter->registrypriv.boffefusemask == 0) {
9808 					if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {
9809 						if (rtw_file_efuse_IsMasked(padapter, addr + i, maskfileBuffer) == _TRUE)	/*use file efuse mask. */
9810 							bcmpchk = _FALSE;
9811 					} else {
9812 						if (efuse_IsMasked(padapter, addr + i) == _TRUE)
9813 							bcmpchk = _FALSE;
9814 					}
9815 				}
9816 
9817 				if (bcmpchk == _TRUE) {
9818 					RTW_INFO("compare readMapWiFi[0x%02x] = %x, ModifiedMap = %x\n", addr + i, ShadowMapWiFi[ addr + i], pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9819 					if (_rtw_memcmp((void *) &ShadowMapWiFi[addr + i], (void *)&pEfuseHal->fakeEfuseModifiedMap[addr + i], 1) == _FALSE){
9820 						err = _FALSE;
9821 						break;
9822 					}
9823 				}
9824 				bcmpchk = _TRUE;
9825 			}
9826 		}
9827 
9828 		if (err) {
9829 			RTW_INFO("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
9830 			sprintf(extra, "WiFi write map compare OK\n");
9831 			err = 0;
9832 			goto exit;
9833 		} else {
9834 			sprintf(extra, "WiFi write map compare FAIL\n");
9835 			RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9836 			err = 0;
9837 			goto exit;
9838 		}
9839 	} else if (strcmp(tmp[0], "wlwfake") == 0) {
9840 		if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9841 			err = -EINVAL;
9842 			goto exit;
9843 		}
9844 		if (pmp_priv->bprocess_mp_mode != _TRUE) {
9845 			RTW_INFO("%s: wlwfake not to be exec, please first to mp_start\n", __FUNCTION__);
9846 			sprintf(extra, "Error, wlwfake cant to be exec, please first to mp_start !!!!\n");
9847 			err = 0;
9848 			goto exit;
9849 		}
9850 		addr = simple_strtoul(tmp[1], &ptmp, 16);
9851 		addr &= 0xFFF;
9852 
9853 		cnts = strlen(tmp[2]);
9854 		if (cnts % 2) {
9855 			err = -EINVAL;
9856 			goto exit;
9857 		}
9858 		cnts /= 2;
9859 		if (cnts == 0) {
9860 			err = -EINVAL;
9861 			goto exit;
9862 		}
9863 
9864 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9865 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9866 		RTW_INFO("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
9867 
9868 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9869 			pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9870 		_rtw_memset(extra, '\0', strlen(extra));
9871 		sprintf(extra, "wlwfake OK\n");
9872 
9873 	}
9874 	else if (strcmp(tmp[0], "wfakemac") == 0) {
9875 		if (tmp[1] == NULL) {
9876 			err = -EINVAL;
9877 			goto exit;
9878 		}
9879 		if (pmp_priv->bprocess_mp_mode != _TRUE) {
9880 			RTW_INFO("%s: wfakemac not to be exec, please first to mp_start\n", __FUNCTION__);
9881 			sprintf(extra, "Error, wfakemac cant to be exec, please first to mp_start !!!!\n");
9882 			err = 0;
9883 			goto exit;
9884 		}
9885 		/* wfakemac,00e04c871200 */
9886 		if (hal_efuse_macaddr_offset(padapter) == -1) {
9887 			err = -EFAULT;
9888 			goto exit;
9889 		}
9890 
9891 		addr = hal_efuse_macaddr_offset(padapter);
9892 		cnts = strlen(tmp[1]);
9893 		if (cnts % 2) {
9894 			err = -EINVAL;
9895 			goto exit;
9896 		}
9897 		cnts /= 2;
9898 		if (cnts == 0) {
9899 			err = -EINVAL;
9900 			goto exit;
9901 		}
9902 		if (cnts > 6) {
9903 			RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9904 			err = -EFAULT;
9905 			goto exit;
9906 		}
9907 
9908 		RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9909 		RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9910 		RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9911 
9912 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9913 			if ((addr + jj) < EFUSE_MAX_MAP_LEN)
9914 				pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9915 
9916 		_rtw_memset(extra, '\0', strlen(extra));
9917 		sprintf(extra, "write mac addr to fake map OK\n");
9918 	} else if(strcmp(tmp[0], "update") == 0) {
9919 		RTW_INFO("To Use new eFuse map ver3\n");
9920 
9921 		if (tmp[1] != 0x00) {
9922 			if (strcmp(tmp[1], "fake") == 0) {
9923 				pmp_priv->efuse_update_on = _TRUE;
9924 				RTW_INFO("Set efuse update without file\n");
9925 			} else if (strcmp(tmp[1], "phy") == 0) {
9926 				pmp_priv->efuse_update_file = _FALSE;
9927 				pmp_priv->efuse_update_on = _FALSE;
9928 				RTW_INFO("Set efuse update with phy\n");
9929 			} else {
9930 				pmp_priv->efuse_update_file = _TRUE;
9931 				strcpy(pmp_priv->efuse_file_path , tmp[1]);
9932 				RTW_INFO("Got file path %s\n", pmp_priv->efuse_file_path);
9933 			}
9934 		}
9935 		/*step read efuse/eeprom data and get mac_addr*/
9936 		if (padapter->hal_func.read_adapter_info(padapter)) {
9937 			_rtw_memset(extra, '\0', strlen(extra));
9938 			#ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
9939 			if (pHalData->txpwr_pg_mode == TXPWR_PG_WITH_PWR_IDX)
9940 				hal_load_txpwr_info(padapter);
9941 			#endif
9942 			phy_load_tx_power_ext_info(padapter, 1);
9943 			sprintf(extra, "eFuse Update OK\n");
9944 			RTW_INFO("eFuse Update OK\n");
9945 		} else {
9946 			_rtw_memset(extra, '\0', strlen(extra));
9947 			sprintf(extra, "eFuse Update FAIL\n");
9948 			RTW_INFO("eFuse Update FAIL\n");
9949 		}
9950 
9951 		RTW_INFO("To Use new eFuse map ver3 done\n");
9952 	} else if (strcmp(tmp[0], "analyze") == 0) {
9953 
9954 		rtw_efuse_analyze(padapter, EFUSE_WIFI, 0);
9955 		_rtw_memset(extra, '\0', strlen(extra));
9956 		sprintf(extra, "eFuse Analyze OK,please to check kernel log\n");
9957 	}
9958 exit:
9959 	if (setdata)
9960 		rtw_mfree(setdata, 1024);
9961 	if (ShadowMapBT)
9962 		rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
9963 	if (ShadowMapWiFi)
9964 		rtw_mfree(ShadowMapWiFi, wifimaplen);
9965 	if (setrawdata)
9966 		rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
9967 
9968 	wrqu->length = strlen(extra);
9969 
9970 	if (padapter->registrypriv.mp_mode == 0) {
9971 #ifdef CONFIG_IPS
9972 		rtw_pm_set_ips(padapter, ips_mode);
9973 #endif /* CONFIG_IPS */
9974 
9975 #ifdef CONFIG_LPS
9976 		rtw_pm_set_lps(padapter, lps_mode);
9977 #endif /* CONFIG_LPS */
9978 	}
9979 
9980 	return err;
9981 }
9982 
9983 #ifdef CONFIG_RTW_CUSTOMER_STR
9984 static int rtw_mp_customer_str(
9985 	struct net_device *dev,
9986 	struct iw_request_info *info,
9987 	union iwreq_data *wrqu, char *extra)
9988 {
9989 	_adapter *adapter = rtw_netdev_priv(dev);
9990 	u32 len;
9991 	u8 *pbuf = NULL, *pch;
9992 	char *ptmp;
9993 	u8 param[RTW_CUSTOMER_STR_LEN];
9994 	u8 count = 0;
9995 	u8 tmp;
9996 	u8 i;
9997 	u32 pos;
9998 	u8 ret;
9999 	u8 read = 0;
10000 
10001 	if (adapter->registrypriv.mp_mode != 1
10002 		|| !adapter->registrypriv.mp_customer_str)
10003 		return -EFAULT;
10004 
10005 	len = wrqu->data.length + 1;
10006 
10007 	pbuf = (u8 *)rtw_zmalloc(len);
10008 	if (pbuf == NULL) {
10009 		RTW_WARN("%s: no memory!\n", __func__);
10010 		return -ENOMEM;
10011 	}
10012 
10013 	if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length)) {
10014 		rtw_mfree(pbuf, len);
10015 		RTW_WARN("%s: copy from user fail!\n", __func__);
10016 		return -EFAULT;
10017 	}
10018 	RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
10019 
10020 	ptmp = (char *)pbuf;
10021 	pch = strsep(&ptmp, ",");
10022 	if ((pch == NULL) || (strlen(pch) == 0)) {
10023 		rtw_mfree(pbuf, len);
10024 		RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
10025 		return -EFAULT;
10026 	}
10027 
10028 	_rtw_memset(param, 0xFF, RTW_CUSTOMER_STR_LEN);
10029 
10030 	if (strcmp(pch, "read") == 0) {
10031 		read = 1;
10032 		ret = rtw_hal_customer_str_read(adapter, param);
10033 
10034 	} else if (strcmp(pch, "write") == 0) {
10035 		do {
10036 			pch = strsep(&ptmp, ":");
10037 			if ((pch == NULL) || (strlen(pch) == 0))
10038 				break;
10039 			if (strlen(pch) != 2
10040 				|| IsHexDigit(*pch) == _FALSE
10041 				|| IsHexDigit(*(pch + 1)) == _FALSE
10042 				|| sscanf(pch, "%hhx", &tmp) != 1
10043 			) {
10044 				RTW_WARN("%s: invalid 8-bit hex!\n", __func__);
10045 				rtw_mfree(pbuf, len);
10046 				return -EFAULT;
10047 			}
10048 
10049 			param[count++] = tmp;
10050 
10051 		} while (count < RTW_CUSTOMER_STR_LEN);
10052 
10053 		if (count == 0) {
10054 			rtw_mfree(pbuf, len);
10055 			RTW_WARN("%s: no input!\n", __func__);
10056 			return -EFAULT;
10057 		}
10058 		ret = rtw_hal_customer_str_write(adapter, param);
10059 	} else {
10060 		rtw_mfree(pbuf, len);
10061 		RTW_INFO("%s: parameter error(unknown cmd)!\n", __func__);
10062 		return -EFAULT;
10063 	}
10064 
10065 	pos = sprintf(extra, "%s: ", read ? "read" : "write");
10066 	if (read == 0 || ret == _SUCCESS) {
10067 		for (i = 0; i < RTW_CUSTOMER_STR_LEN; i++)
10068 			pos += sprintf(extra + pos, "%02x:", param[i]);
10069 		extra[pos] = 0;
10070 		pos--;
10071 	}
10072 	pos += sprintf(extra + pos, " %s", ret == _SUCCESS ? "OK" : "FAIL");
10073 
10074 	wrqu->data.length = strlen(extra) + 1;
10075 
10076 	rtw_mfree(pbuf, len);
10077 	return 0;
10078 }
10079 #endif /* CONFIG_RTW_CUSTOMER_STR */
10080 
10081 static int rtw_priv_mp_set(struct net_device *dev,
10082 			   struct iw_request_info *info,
10083 			   union iwreq_data *wdata, char *extra)
10084 {
10085 
10086 	struct iw_point *wrqu = (struct iw_point *)wdata;
10087 	u32 subcmd = wrqu->flags;
10088 	PADAPTER padapter = rtw_netdev_priv(dev);
10089 	int status = 0;
10090 
10091 #ifdef CONFIG_CONCURRENT_MODE
10092 	if (!is_primary_adapter(padapter)) {
10093 		RTW_INFO("MP mode only primary Adapter support\n");
10094 		return -EIO;
10095 	}
10096 #endif
10097 
10098 	RTW_INFO("%s mutx in %d\n", __func__, subcmd);
10099 	_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10100 	switch (subcmd) {
10101 	case CTA_TEST:
10102 		RTW_INFO("set CTA_TEST\n");
10103 		status = rtw_cta_test_start(dev, info, wdata, extra);
10104 		break;
10105 	case MP_DISABLE_BT_COEXIST:
10106 		RTW_INFO("set case MP_DISABLE_BT_COEXIST\n");
10107 		status = rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
10108 		break;
10109 	case MP_IQK:
10110 		RTW_INFO("set MP_IQK\n");
10111 		status = rtw_mp_iqk(dev, info, wrqu, extra);
10112 		break;
10113 	case MP_LCK:
10114 		RTW_INFO("set MP_LCK\n");
10115 		status = rtw_mp_lck(dev, info, wrqu, extra);
10116 	break;
10117 
10118 	default:
10119 		status = -EIO;
10120 	}
10121 	_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10122 	RTW_INFO("%s mutx done %d\n", __func__, subcmd);
10123 
10124 	return status;
10125 }
10126 
10127 static int rtw_priv_mp_get(struct net_device *dev,
10128 			   struct iw_request_info *info,
10129 			   union iwreq_data *wdata, char *extra)
10130 {
10131 
10132 	struct iw_point *wrqu = (struct iw_point *)wdata;
10133 	u32 subcmd = wrqu->flags;
10134 	PADAPTER padapter = rtw_netdev_priv(dev);
10135 	int status = 0;
10136 
10137 #ifdef CONFIG_CONCURRENT_MODE
10138 	if (!is_primary_adapter(padapter)) {
10139 		RTW_INFO("MP mode only primary Adapter support\n");
10140 		return -EIO;
10141 	}
10142 #endif
10143 
10144 	RTW_INFO("%s mutx in %d\n", __func__, subcmd);
10145 	_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10146 
10147 	switch (subcmd) {
10148 	case MP_START:
10149 		RTW_INFO("set case mp_start\n");
10150 		status = rtw_mp_start(dev, info, wrqu, extra);
10151 		break;
10152 	case MP_STOP:
10153 		RTW_INFO("set case mp_stop\n");
10154 		status = rtw_mp_stop(dev, info, wrqu, extra);
10155 		break;
10156 	case MP_BANDWIDTH:
10157 		RTW_INFO("set case mp_bandwidth\n");
10158 		status = rtw_mp_bandwidth(dev, info, wrqu, extra);
10159 		break;
10160 	case MP_RESET_STATS:
10161 		RTW_INFO("set case MP_RESET_STATS\n");
10162 		status = rtw_mp_reset_stats(dev, info, wrqu, extra);
10163 		break;
10164 	case MP_SetRFPathSwh:
10165 		RTW_INFO("set MP_SetRFPathSwitch\n");
10166 		status = rtw_mp_SetRFPath(dev, info, wrqu, extra);
10167 		break;
10168 	case WRITE_REG:
10169 		status = rtw_mp_write_reg(dev, info, wrqu, extra);
10170 		break;
10171 	case WRITE_RF:
10172 		status = rtw_mp_write_rf(dev, info, wrqu, extra);
10173 		break;
10174 	case MP_PHYPARA:
10175 		RTW_INFO("mp_get  MP_PHYPARA\n");
10176 		status = rtw_mp_phypara(dev, info, wrqu, extra);
10177 		break;
10178 	case MP_CHANNEL:
10179 		RTW_INFO("set case mp_channel\n");
10180 		status = rtw_mp_channel(dev , info, wrqu, extra);
10181 		break;
10182 	case  MP_CHL_OFFSET:
10183 		RTW_INFO("set case mp_ch_offset\n");
10184 		status = rtw_mp_ch_offset(dev , info, wrqu, extra);
10185 		break;
10186 	case READ_REG:
10187 		RTW_INFO("mp_get  READ_REG\n");
10188 		status = rtw_mp_read_reg(dev, info, wrqu, extra);
10189 		break;
10190 	case READ_RF:
10191 		RTW_INFO("mp_get  READ_RF\n");
10192 		status = rtw_mp_read_rf(dev, info, wrqu, extra);
10193 		break;
10194 	case MP_RATE:
10195 		RTW_INFO("set case mp_rate\n");
10196 		status = rtw_mp_rate(dev, info, wrqu, extra);
10197 		break;
10198 	case MP_TXPOWER:
10199 		RTW_INFO("set case MP_TXPOWER\n");
10200 		status = rtw_mp_txpower(dev, info, wrqu, extra);
10201 		break;
10202 	case MP_ANT_TX:
10203 		RTW_INFO("set case MP_ANT_TX\n");
10204 		status = rtw_mp_ant_tx(dev, info, wrqu, extra);
10205 		break;
10206 	case MP_ANT_RX:
10207 		RTW_INFO("set case MP_ANT_RX\n");
10208 		status = rtw_mp_ant_rx(dev, info, wrqu, extra);
10209 		break;
10210 	case MP_QUERY:
10211 		status = rtw_mp_trx_query(dev, info, wrqu, extra);
10212 		break;
10213 	case MP_CTX:
10214 		RTW_INFO("set case MP_CTX\n");
10215 		status = rtw_mp_ctx(dev, info, wrqu, extra);
10216 		break;
10217 	case MP_ARX:
10218 		RTW_INFO("set case MP_ARX\n");
10219 		status = rtw_mp_arx(dev, info, wrqu, extra);
10220 		break;
10221 	case MP_DUMP:
10222 		RTW_INFO("set case MP_DUMP\n");
10223 		status = rtw_mp_dump(dev, info, wrqu, extra);
10224 		break;
10225 	case MP_PSD:
10226 		RTW_INFO("set case MP_PSD\n");
10227 		status = rtw_mp_psd(dev, info, wrqu, extra);
10228 		break;
10229 	case MP_THER:
10230 		RTW_INFO("set case MP_THER\n");
10231 		status = rtw_mp_thermal(dev, info, wrqu, extra);
10232 		break;
10233 	case MP_PwrCtlDM:
10234 		RTW_INFO("set MP_PwrCtlDM\n");
10235 		status = rtw_mp_PwrCtlDM(dev, info, wrqu, extra);
10236 		break;
10237 	case MP_QueryDrvStats:
10238 		RTW_INFO("mp_get MP_QueryDrvStats\n");
10239 		status = rtw_mp_QueryDrv(dev, info, wdata, extra);
10240 		break;
10241 	case MP_PWRTRK:
10242 		RTW_INFO("set case MP_PWRTRK\n");
10243 		status = rtw_mp_pwrtrk(dev, info, wrqu, extra);
10244 		break;
10245 	case MP_SET_TSSIDE:
10246 		RTW_INFO("set case MP_TSSI_DE\n");
10247 		status = rtw_mp_set_tsside(dev, info, wrqu, extra);
10248 		break;
10249 #ifdef CONFIG_MP_INCLUDED
10250 	case EFUSE_SET:
10251 		RTW_INFO("set case efuse set\n");
10252 		status = rtw_mp_efuse_set(dev, info, wdata, extra);
10253 		break;
10254 #endif
10255 	case EFUSE_GET:
10256 		RTW_INFO("efuse get EFUSE_GET\n");
10257 		status = rtw_mp_efuse_get(dev, info, wdata, extra);
10258 		break;
10259 	case MP_GET_TXPOWER_INX:
10260 		RTW_INFO("mp_get MP_GET_TXPOWER_INX\n");
10261 		status = rtw_mp_txpower_index(dev, info, wrqu, extra);
10262 		break;
10263 	case MP_GETVER:
10264 		RTW_INFO("mp_get MP_GETVER\n");
10265 		status = rtw_mp_getver(dev, info, wdata, extra);
10266 		break;
10267 	case MP_MON:
10268 		RTW_INFO("mp_get MP_MON\n");
10269 		status = rtw_mp_mon(dev, info, wdata, extra);
10270 		break;
10271 	case EFUSE_BT_MASK:
10272 		RTW_INFO("mp_get EFUSE_BT_MASK\n");
10273 		status = rtw_bt_efuse_mask_file(dev, info, wdata, extra);
10274 		break;
10275 	case EFUSE_MASK:
10276 		RTW_INFO("mp_get EFUSE_MASK\n");
10277 		status = rtw_efuse_mask_file(dev, info, wdata, extra);
10278 		break;
10279 	case EFUSE_FILE:
10280 		RTW_INFO("mp_get EFUSE_FILE\n");
10281 		status = rtw_efuse_file_map(dev, info, wdata, extra);
10282 		break;
10283 	case EFUSE_FILE_STORE:
10284 #if !defined(CONFIG_RTW_ANDROID_GKI)
10285 		RTW_INFO("mp_get EFUSE_FILE_STORE\n");
10286 		status = rtw_efuse_file_map_store(dev, info, wdata, extra);
10287 #else
10288 		RTW_ERR("Android GKI doesn't support: mp_get EFUSE_FILE_STORE\n");
10289 #endif /* !defined(CONFIG_RTW_ANDROID_GKI) */
10290 		break;
10291 	case MP_TX:
10292 		RTW_INFO("mp_get MP_TX\n");
10293 		status = rtw_mp_tx(dev, info, wdata, extra);
10294 		break;
10295 	case MP_RX:
10296 		RTW_INFO("mp_get MP_RX\n");
10297 		status = rtw_mp_rx(dev, info, wdata, extra);
10298 		break;
10299 	case MP_HW_TX_MODE:
10300 		RTW_INFO("mp_get MP_HW_TX_MODE\n");
10301 		status = rtw_mp_hwtx(dev, info, wdata, extra);
10302 		break;
10303 	case MP_GET_TSSIDE:
10304 		RTW_INFO("mp_get TSSI_DE\n");
10305 		status = rtw_mp_get_tsside(dev, info, wrqu, extra);
10306 		break;
10307 #ifdef CONFIG_RTW_CUSTOMER_STR
10308 	case MP_CUSTOMER_STR:
10309 		RTW_INFO("customer str\n");
10310 		status = rtw_mp_customer_str(dev, info, wdata, extra);
10311 		break;
10312 #endif
10313 	case MP_PWRLMT:
10314 		RTW_INFO("mp_get MP_SETPWRLMT\n");
10315 		status = rtw_mp_pwrlmt(dev, info, wdata, extra);
10316 		break;
10317 	case MP_PWRBYRATE:
10318 		RTW_INFO("mp_get MP_SETPWRBYRATE\n");
10319 		status = rtw_mp_pwrbyrate(dev, info, wdata, extra);
10320 		break;
10321 	case  BT_EFUSE_FILE:
10322 		RTW_INFO("mp_get BT EFUSE_FILE\n");
10323 		status = rtw_bt_efuse_file_map(dev, info, wdata, extra);
10324 		break;
10325 	case MP_SWRFPath:
10326 		RTW_INFO("mp_get MP_SWRFPath\n");
10327 		status = rtw_mp_switch_rf_path(dev, info, wrqu, extra);
10328 		break;
10329 	case MP_LINK:
10330 		RTW_INFO("mp_get MP_LINK\n");
10331 		status = rtw_mp_link(dev, info, wrqu, extra);
10332 		break;
10333 	case MP_DPK_TRK:
10334 		RTW_INFO("mp_get MP_DPK_TRK\n");
10335 		status = rtw_mp_dpk_track(dev, info, wdata, extra);
10336 		break;
10337 	case MP_DPK:
10338 		RTW_INFO("set MP_DPK\n");
10339 		status = rtw_mp_dpk(dev, info, wdata, extra);
10340 		break;
10341 	default:
10342 		status = -EIO;
10343 	}
10344 
10345 	_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10346 	RTW_INFO("%s mutx done_%d\n", __func__, subcmd);
10347 
10348 	return status;
10349 }
10350 #endif /*#if defined(CONFIG_MP_INCLUDED)*/
10351 
10352 
10353 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
10354 #define DBG_MP_SDIO_INDIRECT_ACCESS 1
10355 static int rtw_mp_sd_iread(struct net_device *dev
10356 			   , struct iw_request_info *info
10357 			   , struct iw_point *wrqu
10358 			   , char *extra)
10359 {
10360 	char input[16];
10361 	u8 width;
10362 	unsigned long addr;
10363 	u32 ret = 0;
10364 	PADAPTER padapter = rtw_netdev_priv(dev);
10365 
10366 	if (wrqu->length > 16) {
10367 		RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10368 		ret = -EINVAL;
10369 		goto exit;
10370 	}
10371 
10372 	if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10373 		RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10374 		ret = -EFAULT;
10375 		goto exit;
10376 	}
10377 
10378 	_rtw_memset(extra, 0, wrqu->length);
10379 
10380 	if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) {
10381 		RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10382 		ret = -EINVAL;
10383 		goto exit;
10384 	}
10385 
10386 	if (addr > 0x3FFF) {
10387 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10388 		ret = -EINVAL;
10389 		goto exit;
10390 	}
10391 
10392 	if (DBG_MP_SDIO_INDIRECT_ACCESS)
10393 		RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr);
10394 
10395 	switch (width) {
10396 	case 1:
10397 		sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr));
10398 		wrqu->length = strlen(extra);
10399 		break;
10400 	case 2:
10401 		sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr));
10402 		wrqu->length = strlen(extra);
10403 		break;
10404 	case 4:
10405 		sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr));
10406 		wrqu->length = strlen(extra);
10407 		break;
10408 	default:
10409 		wrqu->length = 0;
10410 		ret = -EINVAL;
10411 		break;
10412 	}
10413 
10414 exit:
10415 	return ret;
10416 }
10417 
10418 static int rtw_mp_sd_iwrite(struct net_device *dev
10419 			    , struct iw_request_info *info
10420 			    , struct iw_point *wrqu
10421 			    , char *extra)
10422 {
10423 	char width;
10424 	unsigned long addr, data;
10425 	int ret = 0;
10426 	PADAPTER padapter = rtw_netdev_priv(dev);
10427 	char input[32];
10428 
10429 	if (wrqu->length > 32) {
10430 		RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10431 		ret = -EINVAL;
10432 		goto exit;
10433 	}
10434 
10435 	if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10436 		RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10437 		ret = -EFAULT;
10438 		goto exit;
10439 	}
10440 
10441 	_rtw_memset(extra, 0, wrqu->length);
10442 
10443 	if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) {
10444 		RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10445 		ret = -EINVAL;
10446 		goto exit;
10447 	}
10448 
10449 	if (addr > 0x3FFF) {
10450 		RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10451 		ret = -EINVAL;
10452 		goto exit;
10453 	}
10454 
10455 	if (DBG_MP_SDIO_INDIRECT_ACCESS)
10456 		RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data);
10457 
10458 	switch (width) {
10459 	case 1:
10460 		if (data > 0xFF) {
10461 			ret = -EINVAL;
10462 			break;
10463 		}
10464 		rtw_sd_iwrite8(padapter, addr, data);
10465 		break;
10466 	case 2:
10467 		if (data > 0xFFFF) {
10468 			ret = -EINVAL;
10469 			break;
10470 		}
10471 		rtw_sd_iwrite16(padapter, addr, data);
10472 		break;
10473 	case 4:
10474 		rtw_sd_iwrite32(padapter, addr, data);
10475 		break;
10476 	default:
10477 		wrqu->length = 0;
10478 		ret = -EINVAL;
10479 		break;
10480 	}
10481 
10482 exit:
10483 	return ret;
10484 }
10485 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
10486 
10487 static int rtw_priv_set(struct net_device *dev,
10488 			struct iw_request_info *info,
10489 			union iwreq_data *wdata, char *extra)
10490 {
10491 	struct iw_point *wrqu = (struct iw_point *)wdata;
10492 	u32 subcmd = wrqu->flags;
10493 	PADAPTER padapter = rtw_netdev_priv(dev);
10494 
10495 	if (padapter == NULL)
10496 		return -ENETDOWN;
10497 
10498 	if (padapter->bup == _FALSE) {
10499 		RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10500 		return -ENETDOWN;
10501 	}
10502 
10503 	if (RTW_CANNOT_RUN(padapter)) {
10504 		RTW_INFO("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__);
10505 		return -ENETDOWN;
10506 	}
10507 
10508 	if (extra == NULL) {
10509 		wrqu->length = 0;
10510 		return -EIO;
10511 	}
10512 
10513 	if (subcmd < MP_NULL) {
10514 #ifdef CONFIG_MP_INCLUDED
10515 		rtw_priv_mp_set(dev, info, wdata, extra);
10516 #endif
10517 		return 0;
10518 	}
10519 
10520 	switch (subcmd) {
10521 #ifdef CONFIG_WOWLAN
10522 	case MP_WOW_ENABLE:
10523 		RTW_INFO("set case MP_WOW_ENABLE: %s\n", extra);
10524 
10525 		rtw_wowlan_ctrl(dev, info, wdata, extra);
10526 		break;
10527 	case MP_WOW_SET_PATTERN:
10528 		RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra);
10529 		rtw_wowlan_set_pattern(dev, info, wdata, extra);
10530 		break;
10531 	#ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10532 	case MP_WOW_SET_KEEP_ALIVE_PATTERN:
10533 		RTW_INFO("set case MP_WOW_SET_KEEP_ALIVE_PATTERN: %s\n", extra);
10534 		rtw_wowlan_set_keep_alive_pattern(dev, info, wdata, extra);
10535 		break;
10536 	#endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10537 
10538 #endif
10539 #ifdef CONFIG_AP_WOWLAN
10540 	case MP_AP_WOW_ENABLE:
10541 		RTW_INFO("set case MP_AP_WOW_ENABLE: %s\n", extra);
10542 		rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
10543 		break;
10544 #endif
10545 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10546 	case VENDOR_IE_SET:
10547 		RTW_INFO("set case VENDOR_IE_SET\n");
10548 		rtw_vendor_ie_set(dev , info , wdata , extra);
10549 		break;
10550 #endif
10551 	default:
10552 		return -EIO;
10553 	}
10554 
10555 	return 0;
10556 }
10557 
10558 
10559 static int rtw_priv_get(struct net_device *dev,
10560 			struct iw_request_info *info,
10561 			union iwreq_data *wdata, char *extra)
10562 {
10563 	struct iw_point *wrqu = (struct iw_point *)wdata;
10564 	u32 subcmd = wrqu->flags;
10565 	PADAPTER padapter = rtw_netdev_priv(dev);
10566 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
10567 	struct dm_struct	*p_dm = &pHalData->odmpriv;
10568 	struct dm_rf_calibration_struct	*p_rf_calibrate_info = &(p_dm->rf_calibrate_info);
10569 	struct dm_iqk_info	*p_iqk_info = &p_dm->IQK_info;
10570 	u32 i = 100;
10571 
10572 
10573 	if (padapter->bup == _FALSE) {
10574 		RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10575 		return -ENETDOWN;
10576 	}
10577 
10578 	if (RTW_CANNOT_RUN(padapter)) {
10579 		RTW_INFO("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__);
10580 		return -ENETDOWN;
10581 	}
10582 
10583 	if (extra == NULL) {
10584 		wrqu->length = 0;
10585 		return -EIO;
10586 	}
10587 
10588 	if (subcmd < MP_NULL) {
10589 #ifdef CONFIG_MP_INCLUDED
10590 		while (i > 1) {
10591 			if (p_rf_calibrate_info->is_iqk_in_progress) {
10592 				rtw_msleep_os(10);
10593 			} else {
10594 				p_iqk_info->rfk_forbidden = _TRUE;
10595 				break;
10596 			}
10597 			i--;
10598 		}
10599 		if (subcmd == MP_CHANNEL || subcmd == MP_BANDWIDTH || subcmd == MP_START || subcmd == MP_DPK)
10600 			p_iqk_info->rfk_forbidden = _FALSE;
10601 		rtw_priv_mp_get(dev, info, wdata, extra);
10602 		rtw_msleep_os(10); /* delay 5ms for sending pkt before exit adb shell operation */
10603 		p_iqk_info->rfk_forbidden = _FALSE;
10604 #endif
10605 	} else {
10606 			switch (subcmd) {
10607 #if defined(CONFIG_RTL8723B)
10608 			case MP_SetBT:
10609 				RTW_INFO("set MP_SetBT\n");
10610 				rtw_mp_SetBT(dev, info, wdata, extra);
10611 				break;
10612 #endif
10613 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
10614 			case MP_SD_IREAD:
10615 				rtw_mp_sd_iread(dev, info, wrqu, extra);
10616 				break;
10617 			case MP_SD_IWRITE:
10618 				rtw_mp_sd_iwrite(dev, info, wrqu, extra);
10619 				break;
10620 #endif
10621 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10622 			case VENDOR_IE_GET:
10623 				RTW_INFO("get case VENDOR_IE_GET\n");
10624 				rtw_vendor_ie_get(dev , info , wdata , extra);
10625 				break;
10626 #endif
10627 			case GET_IC_TYPE:
10628 				RTW_INFO("get IC Type\n");
10629 				rtw_get_ic_type(dev , info , wdata , extra);
10630 				break;
10631 			default:
10632 				return -EIO;
10633 			}
10634 		}
10635 
10636 	return 0;
10637 }
10638 
10639 
10640 #ifdef CONFIG_TDLS
10641 static int rtw_wx_tdls_wfd_enable(struct net_device *dev,
10642 				  struct iw_request_info *info,
10643 				  union iwreq_data *wrqu, char *extra)
10644 {
10645 	int ret = 0;
10646 
10647 #ifdef CONFIG_WFD
10648 
10649 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10650 
10651 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10652 
10653 	if (extra[0] == '0')
10654 		rtw_tdls_wfd_enable(padapter, 0);
10655 	else
10656 		rtw_tdls_wfd_enable(padapter, 1);
10657 
10658 #endif /* CONFIG_WFD */
10659 
10660 	return ret;
10661 }
10662 
10663 static int rtw_tdls_weaksec(struct net_device *dev,
10664 			    struct iw_request_info *info,
10665 			    union iwreq_data *wrqu, char *extra)
10666 {
10667 	int ret = 0;
10668 
10669 #ifdef CONFIG_TDLS
10670 
10671 	u8 i, j;
10672 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10673 
10674 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10675 
10676 	if (extra[0] == '0')
10677 		padapter->wdinfo.wfd_tdls_weaksec = 0;
10678 	else
10679 		padapter->wdinfo.wfd_tdls_weaksec = 1;
10680 
10681 #endif /* CONFIG_TDLS */
10682 
10683 	return ret;
10684 }
10685 
10686 
10687 static int rtw_tdls_enable(struct net_device *dev,
10688 			   struct iw_request_info *info,
10689 			   union iwreq_data *wrqu, char *extra)
10690 {
10691 	int ret = 0;
10692 
10693 #ifdef CONFIG_TDLS
10694 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10695 
10696 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10697 
10698 	if (extra[0] == '0')
10699 		rtw_disable_tdls_func(padapter, _TRUE);
10700 	else if (extra[0] == '1')
10701 		rtw_enable_tdls_func(padapter);
10702 #endif /* CONFIG_TDLS */
10703 
10704 	return ret;
10705 }
10706 
10707 static int rtw_tdls_setup(struct net_device *dev,
10708 			  struct iw_request_info *info,
10709 			  union iwreq_data *wrqu, char *extra)
10710 {
10711 	int ret = 0;
10712 #ifdef CONFIG_TDLS
10713 	u8 i, j;
10714 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10715 	struct tdls_txmgmt txmgmt;
10716 #ifdef CONFIG_WFD
10717 	struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
10718 #endif /* CONFIG_WFD */
10719 
10720 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10721 
10722 	if (wrqu->data.length - 1 != 17) {
10723 		RTW_INFO("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length - 1));
10724 		return ret;
10725 	}
10726 
10727 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10728 	for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10729 		txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10730 
10731 #ifdef CONFIG_WFD
10732 	if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
10733 		/* Weak Security situation with AP. */
10734 		if (0 == pwdinfo->wfd_tdls_weaksec)	{
10735 			/* Can't send the tdls setup request out!! */
10736 			RTW_INFO("[%s] Current link is not AES, "
10737 				"SKIP sending the tdls setup request!!\n", __FUNCTION__);
10738 		} else
10739 			issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10740 	} else
10741 #endif /* CONFIG_WFD */
10742 	{
10743 		issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10744 	}
10745 #endif /* CONFIG_TDLS */
10746 
10747 	return ret;
10748 }
10749 
10750 static int rtw_tdls_teardown(struct net_device *dev,
10751 			     struct iw_request_info *info,
10752 			     union iwreq_data *wrqu, char *extra)
10753 {
10754 	int ret = 0;
10755 
10756 #ifdef CONFIG_TDLS
10757 
10758 	u8 i, j;
10759 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10760 	struct sta_info *ptdls_sta = NULL;
10761 	struct tdls_txmgmt txmgmt;
10762 
10763 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10764 
10765 	if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) {
10766 		RTW_INFO("[%s] length:%d != 17 or 19\n",
10767 			 __FUNCTION__, (wrqu->data.length - 1));
10768 		return ret;
10769 	}
10770 
10771 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10772 	for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
10773 		txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10774 
10775 	ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
10776 
10777 	if (ptdls_sta != NULL) {
10778 		txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
10779 		if (wrqu->data.length - 1 == 19)
10780 			issue_tdls_teardown(padapter, &txmgmt, _FALSE);
10781 		else
10782 			issue_tdls_teardown(padapter, &txmgmt, _TRUE);
10783 	} else
10784 		RTW_INFO("TDLS peer not found\n");
10785 #endif /* CONFIG_TDLS */
10786 
10787 	return ret;
10788 }
10789 
10790 static int rtw_tdls_discovery(struct net_device *dev,
10791 			      struct iw_request_info *info,
10792 			      union iwreq_data *wrqu, char *extra)
10793 {
10794 	int ret = 0;
10795 
10796 #ifdef CONFIG_TDLS
10797 
10798 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10799 	struct tdls_txmgmt	txmgmt;
10800 	int i = 0, j = 0;
10801 
10802 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10803 
10804 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10805 	for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10806 		txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10807 
10808 	issue_tdls_dis_req(padapter, &txmgmt);
10809 
10810 #endif /* CONFIG_TDLS */
10811 
10812 	return ret;
10813 }
10814 
10815 static int rtw_tdls_ch_switch(struct net_device *dev,
10816 			      struct iw_request_info *info,
10817 			      union iwreq_data *wrqu, char *extra)
10818 {
10819 	int ret = 0;
10820 
10821 #ifdef CONFIG_TDLS
10822 #ifdef CONFIG_TDLS_CH_SW
10823 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10824 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
10825 	u8 i, j;
10826 	struct sta_info *ptdls_sta = NULL;
10827 	u8 take_care_iqk;
10828 
10829 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10830 
10831 	if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
10832 		RTW_INFO("TDLS channel switch is not allowed\n");
10833 		return ret;
10834 	}
10835 
10836 	for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10837 		pchsw_info->addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10838 
10839 	ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr);
10840 	if (ptdls_sta == NULL)
10841 		return ret;
10842 
10843 	pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE;
10844 
10845 	if (ptdls_sta != NULL) {
10846 		if (pchsw_info->off_ch_num == 0)
10847 			pchsw_info->off_ch_num = 11;
10848 	} else
10849 		RTW_INFO("TDLS peer not found\n");
10850 
10851 	rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
10852 
10853 	rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
10854 	if (take_care_iqk == _TRUE) {
10855 #ifdef CONFIG_TDLS_CH_SW_V2
10856 		rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE);
10857 #else
10858 		u8 central_chnl;
10859 		u8 bw_mode;
10860 
10861 		bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
10862 		central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
10863 		if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) >= 0)
10864 			rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
10865 		else
10866 			rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE);
10867 #endif
10868 	} else
10869 		rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
10870 
10871 	/* issue_tdls_ch_switch_req(padapter, ptdls_sta); */
10872 	/* RTW_INFO("issue tdls ch switch req\n"); */
10873 
10874 #endif /* CONFIG_TDLS_CH_SW */
10875 #endif /* CONFIG_TDLS */
10876 
10877 	return ret;
10878 }
10879 
10880 static int rtw_tdls_ch_switch_off(struct net_device *dev,
10881 				  struct iw_request_info *info,
10882 				  union iwreq_data *wrqu, char *extra)
10883 {
10884 	int ret = 0;
10885 
10886 #ifdef CONFIG_TDLS
10887 #ifdef CONFIG_TDLS_CH_SW
10888 
10889 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10890 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
10891 	u8 i, j, mac_addr[ETH_ALEN];
10892 	struct sta_info *ptdls_sta = NULL;
10893 	struct tdls_txmgmt txmgmt;
10894 
10895 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10896 
10897 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10898 
10899 	if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
10900 		RTW_INFO("TDLS channel switch is not allowed\n");
10901 		return ret;
10902 	}
10903 
10904 	if (wrqu->data.length >= 17) {
10905 		for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10906 			mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10907 		ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
10908 	}
10909 
10910 	if (ptdls_sta == NULL)
10911 		return ret;
10912 
10913 	rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
10914 
10915 	pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
10916 				     TDLS_CH_SWITCH_ON_STATE |
10917 				     TDLS_PEER_AT_OFF_STATE);
10918 	_rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
10919 
10920 	ptdls_sta->ch_switch_time = 0;
10921 	ptdls_sta->ch_switch_timeout = 0;
10922 	_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
10923 	_cancel_timer_ex(&ptdls_sta->delay_timer);
10924 	_cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
10925 	_cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
10926 
10927 	rtw_pm_set_lps(padapter, PS_MODE_MAX);
10928 #endif /* CONFIG_TDLS_CH_SW */
10929 #endif /* CONFIG_TDLS */
10930 
10931 	return ret;
10932 }
10933 
10934 static int rtw_tdls_dump_ch(struct net_device *dev,
10935 			    struct iw_request_info *info,
10936 			    union iwreq_data *wrqu, char *extra)
10937 {
10938 	int ret = 0;
10939 
10940 #ifdef CONFIG_TDLS
10941 #ifdef CONFIG_TDLS_CH_SW
10942 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10943 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10944 
10945 	RTW_INFO("[%s] dump_stack:%s\n", __FUNCTION__, extra);
10946 
10947 	extra[wrqu->data.length] = 0x00;
10948 	ptdlsinfo->chsw_info.dump_stack = rtw_atoi(extra);
10949 
10950 	return ret;
10951 
10952 #endif
10953 #endif /* CONFIG_TDLS */
10954 
10955 	return ret;
10956 }
10957 
10958 static int rtw_tdls_off_ch_num(struct net_device *dev,
10959 			       struct iw_request_info *info,
10960 			       union iwreq_data *wrqu, char *extra)
10961 {
10962 	int ret = 0;
10963 
10964 #ifdef CONFIG_TDLS
10965 #ifdef CONFIG_TDLS_CH_SW
10966 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10967 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10968 
10969 	RTW_INFO("[%s] off_ch_num:%s\n", __FUNCTION__, extra);
10970 
10971 	extra[wrqu->data.length] = 0x00;
10972 	ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra);
10973 
10974 	return ret;
10975 
10976 #endif
10977 #endif /* CONFIG_TDLS */
10978 
10979 	return ret;
10980 }
10981 
10982 static int rtw_tdls_ch_offset(struct net_device *dev,
10983 			      struct iw_request_info *info,
10984 			      union iwreq_data *wrqu, char *extra)
10985 {
10986 	int ret = 0;
10987 
10988 #ifdef CONFIG_TDLS
10989 #ifdef CONFIG_TDLS_CH_SW
10990 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10991 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10992 
10993 	RTW_INFO("[%s] ch_offset:%s\n", __FUNCTION__, extra);
10994 
10995 	extra[wrqu->data.length] = 0x00;
10996 	switch (rtw_atoi(extra)) {
10997 	case SCA:
10998 		ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
10999 		break;
11000 
11001 	case SCB:
11002 		ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11003 		break;
11004 
11005 	default:
11006 		ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11007 		break;
11008 	}
11009 
11010 	return ret;
11011 
11012 #endif
11013 #endif /* CONFIG_TDLS */
11014 
11015 	return ret;
11016 }
11017 
11018 static int rtw_tdls_pson(struct net_device *dev,
11019 			 struct iw_request_info *info,
11020 			 union iwreq_data *wrqu, char *extra)
11021 {
11022 	int ret = 0;
11023 
11024 #ifdef CONFIG_TDLS
11025 
11026 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11027 	u8 i, j, mac_addr[ETH_ALEN];
11028 	struct sta_info *ptdls_sta = NULL;
11029 
11030 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11031 
11032 	for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
11033 		mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11034 
11035 	ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11036 
11037 	issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 1, 3, 500);
11038 
11039 #endif /* CONFIG_TDLS */
11040 
11041 	return ret;
11042 }
11043 
11044 static int rtw_tdls_psoff(struct net_device *dev,
11045 			  struct iw_request_info *info,
11046 			  union iwreq_data *wrqu, char *extra)
11047 {
11048 	int ret = 0;
11049 
11050 #ifdef CONFIG_TDLS
11051 
11052 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11053 	u8 i, j, mac_addr[ETH_ALEN];
11054 	struct sta_info *ptdls_sta = NULL;
11055 
11056 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11057 
11058 	for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
11059 		mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11060 
11061 	ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11062 
11063 	if (ptdls_sta)
11064 		issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 0, 3, 500);
11065 
11066 #endif /* CONFIG_TDLS */
11067 
11068 	return ret;
11069 }
11070 
11071 static int rtw_tdls_setip(struct net_device *dev,
11072 			  struct iw_request_info *info,
11073 			  union iwreq_data *wrqu, char *extra)
11074 {
11075 	int ret = 0;
11076 
11077 #ifdef CONFIG_TDLS
11078 #ifdef CONFIG_WFD
11079 
11080 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11081 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11082 	struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11083 	u8 i = 0, j = 0, k = 0, tag = 0;
11084 
11085 	RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11086 
11087 	while (i < 4) {
11088 		for (j = 0; j < 4; j++) {
11089 			if (*(extra + j + tag) == '.' || *(extra + j + tag) == '\0') {
11090 				if (j == 1)
11091 					pwfd_info->ip_address[i] = convert_ip_addr('0', '0', *(extra + (j - 1) + tag));
11092 				if (j == 2)
11093 					pwfd_info->ip_address[i] = convert_ip_addr('0', *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
11094 				if (j == 3)
11095 					pwfd_info->ip_address[i] = convert_ip_addr(*(extra + (j - 3) + tag), *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
11096 
11097 				tag += j + 1;
11098 				break;
11099 			}
11100 		}
11101 		i++;
11102 	}
11103 
11104 	RTW_INFO("[%s] Set IP = %u.%u.%u.%u\n", __FUNCTION__,
11105 		 ptdlsinfo->wfd_info->ip_address[0],
11106 		 ptdlsinfo->wfd_info->ip_address[1],
11107 		 ptdlsinfo->wfd_info->ip_address[2],
11108 		 ptdlsinfo->wfd_info->ip_address[3]);
11109 
11110 #endif /* CONFIG_WFD */
11111 #endif /* CONFIG_TDLS */
11112 
11113 	return ret;
11114 }
11115 
11116 static int rtw_tdls_getip(struct net_device *dev,
11117 			  struct iw_request_info *info,
11118 			  union iwreq_data *wrqu, char *extra)
11119 {
11120 	int ret = 0;
11121 
11122 #ifdef CONFIG_TDLS
11123 #ifdef CONFIG_WFD
11124 
11125 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11126 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11127 	struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11128 
11129 	RTW_INFO("[%s]\n", __FUNCTION__);
11130 
11131 	sprintf(extra, "\n\n%u.%u.%u.%u\n",
11132 		pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11133 		pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11134 
11135 	RTW_INFO("[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
11136 		 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11137 		 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11138 
11139 	wrqu->data.length = strlen(extra);
11140 
11141 #endif /* CONFIG_WFD */
11142 #endif /* CONFIG_TDLS */
11143 
11144 	return ret;
11145 }
11146 
11147 static int rtw_tdls_getport(struct net_device *dev,
11148 			    struct iw_request_info *info,
11149 			    union iwreq_data *wrqu, char *extra)
11150 {
11151 
11152 	int ret = 0;
11153 
11154 #ifdef CONFIG_TDLS
11155 #ifdef CONFIG_WFD
11156 
11157 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11158 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11159 	struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11160 
11161 	RTW_INFO("[%s]\n", __FUNCTION__);
11162 
11163 	sprintf(extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport);
11164 	RTW_INFO("[%s] remote port = %d\n",
11165 		 __FUNCTION__, pwfd_info->peer_rtsp_ctrlport);
11166 
11167 	wrqu->data.length = strlen(extra);
11168 
11169 #endif /* CONFIG_WFD */
11170 #endif /* CONFIG_TDLS */
11171 
11172 	return ret;
11173 
11174 }
11175 
11176 /* WFDTDLS, for sigma test */
11177 static int rtw_tdls_dis_result(struct net_device *dev,
11178 			       struct iw_request_info *info,
11179 			       union iwreq_data *wrqu, char *extra)
11180 {
11181 
11182 	int ret = 0;
11183 
11184 #ifdef CONFIG_TDLS
11185 #ifdef CONFIG_WFD
11186 
11187 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11188 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11189 
11190 	RTW_INFO("[%s]\n", __FUNCTION__);
11191 
11192 	if (ptdlsinfo->dev_discovered == _TRUE) {
11193 		sprintf(extra, "\n\nDis=1\n");
11194 		ptdlsinfo->dev_discovered = _FALSE;
11195 	}
11196 
11197 	wrqu->data.length = strlen(extra);
11198 
11199 #endif /* CONFIG_WFD */
11200 #endif /* CONFIG_TDLS */
11201 
11202 	return ret;
11203 
11204 }
11205 
11206 /* WFDTDLS, for sigma test */
11207 static int rtw_wfd_tdls_status(struct net_device *dev,
11208 			       struct iw_request_info *info,
11209 			       union iwreq_data *wrqu, char *extra)
11210 {
11211 
11212 	int ret = 0;
11213 
11214 #ifdef CONFIG_TDLS
11215 
11216 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11217 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11218 
11219 	RTW_INFO("[%s]\n", __FUNCTION__);
11220 
11221 	sprintf(extra, "\nlink_established:%d\n"
11222 		"sta_cnt:%d\n"
11223 		"sta_maximum:%d\n"
11224 		"cur_channel:%d\n"
11225 		"tdls_enable:%d"
11226 #ifdef CONFIG_TDLS_CH_SW
11227 		"ch_sw_state:%08x\n"
11228 		"chsw_on:%d\n"
11229 		"off_ch_num:%d\n"
11230 		"cur_time:%d\n"
11231 		"ch_offset:%d\n"
11232 		"delay_swtich_back:%d"
11233 #endif
11234 		,
11235 		ptdlsinfo->link_established, ptdlsinfo->sta_cnt,
11236 		ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel,
11237 		rtw_is_tdls_enabled(padapter)
11238 #ifdef CONFIG_TDLS_CH_SW
11239 		,
11240 		ptdlsinfo->chsw_info.ch_sw_state,
11241 		ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on),
11242 		ptdlsinfo->chsw_info.off_ch_num,
11243 		ptdlsinfo->chsw_info.cur_time,
11244 		ptdlsinfo->chsw_info.ch_offset,
11245 		ptdlsinfo->chsw_info.delay_switch_back
11246 #endif
11247 	       );
11248 
11249 	wrqu->data.length = strlen(extra);
11250 
11251 #endif /* CONFIG_TDLS */
11252 
11253 	return ret;
11254 
11255 }
11256 
11257 static int rtw_tdls_getsta(struct net_device *dev,
11258 			   struct iw_request_info *info,
11259 			   union iwreq_data *wrqu, char *extra)
11260 {
11261 
11262 	int ret = 0;
11263 #ifdef CONFIG_TDLS
11264 	u8 i, j;
11265 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11266 	u8 addr[ETH_ALEN] = {0};
11267 	char charmac[17];
11268 	struct sta_info *ptdls_sta = NULL;
11269 
11270 	RTW_INFO("[%s] %s %d\n", __FUNCTION__,
11271 		 (char *)wrqu->data.pointer, wrqu->data.length - 1);
11272 
11273 	if (copy_from_user(charmac, wrqu->data.pointer + 9, 17)) {
11274 		ret = -EFAULT;
11275 		goto exit;
11276 	}
11277 
11278 	RTW_INFO("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
11279 	for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
11280 		addr[i] = key_2char2num(*(charmac + j), *(charmac + j + 1));
11281 
11282 	RTW_INFO("[%s] %d, charmac:%s, addr:"MAC_FMT"\n",
11283 		 __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
11284 	ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);
11285 	if (ptdls_sta) {
11286 		sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state);
11287 		RTW_INFO("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
11288 	} else {
11289 		sprintf(extra, "\n\nNot found this sta\n");
11290 		RTW_INFO("\n\nNot found this sta\n");
11291 	}
11292 	wrqu->data.length = strlen(extra);
11293 
11294 exit:
11295 #endif /* CONFIG_TDLS */
11296 	return ret;
11297 
11298 }
11299 
11300 static int rtw_tdls_get_best_ch(struct net_device *dev,
11301 				struct iw_request_info *info,
11302 				union iwreq_data *wrqu, char *extra)
11303 {
11304 #ifdef CONFIG_FIND_BEST_CHANNEL
11305 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11306 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
11307 	u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
11308 
11309 	for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {
11310 		if (rfctl->channel_set[i].ChannelNum == 1)
11311 			index_24G = i;
11312 		if (rfctl->channel_set[i].ChannelNum == 36)
11313 			index_5G = i;
11314 	}
11315 
11316 	for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {
11317 		/* 2.4G */
11318 		if (rfctl->channel_set[i].ChannelNum == 6 || rfctl->channel_set[i].ChannelNum == 11) {
11319 			if (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_24G].rx_count) {
11320 				index_24G = i;
11321 				best_channel_24G = rfctl->channel_set[i].ChannelNum;
11322 			}
11323 		}
11324 
11325 		/* 5G */
11326 		if (rfctl->channel_set[i].ChannelNum >= 36
11327 		    && rfctl->channel_set[i].ChannelNum < 140) {
11328 			/* Find primary channel */
11329 			if (((rfctl->channel_set[i].ChannelNum - 36) % 8 == 0)
11330 			    && (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {
11331 				index_5G = i;
11332 				best_channel_5G = rfctl->channel_set[i].ChannelNum;
11333 			}
11334 		}
11335 
11336 		if (rfctl->channel_set[i].ChannelNum >= 149
11337 		    && rfctl->channel_set[i].ChannelNum < 165) {
11338 			/* Find primary channel */
11339 			if (((rfctl->channel_set[i].ChannelNum - 149) % 8 == 0)
11340 			    && (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {
11341 				index_5G = i;
11342 				best_channel_5G = rfctl->channel_set[i].ChannelNum;
11343 			}
11344 		}
11345 #if 1 /* debug */
11346 		RTW_INFO("The rx cnt of channel %3d = %d\n",
11347 			 rfctl->channel_set[i].ChannelNum,
11348 			 rfctl->channel_set[i].rx_count);
11349 #endif
11350 	}
11351 
11352 	sprintf(extra, "\nbest_channel_24G = %d\n", best_channel_24G);
11353 	RTW_INFO("best_channel_24G = %d\n", best_channel_24G);
11354 
11355 	if (index_5G != 0) {
11356 		sprintf(extra, "best_channel_5G = %d\n", best_channel_5G);
11357 		RTW_INFO("best_channel_5G = %d\n", best_channel_5G);
11358 	}
11359 
11360 	wrqu->data.length = strlen(extra);
11361 
11362 #endif
11363 
11364 	return 0;
11365 
11366 }
11367 #endif /*#ifdef CONFIG_TDLS*/
11368 static int rtw_tdls(struct net_device *dev,
11369 		    struct iw_request_info *info,
11370 		    union iwreq_data *wrqu, char *extra)
11371 {
11372 	int ret = 0;
11373 
11374 #ifdef CONFIG_TDLS
11375 
11376 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11377 
11378 	RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
11379 
11380 	if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
11381 		RTW_INFO("Discard tdls oper since hal doesn't support tdls\n");
11382 		return 0;
11383 	}
11384 
11385 	if (rtw_is_tdls_enabled(padapter) == _FALSE) {
11386 		RTW_INFO("TDLS is not enabled\n");
11387 		return 0;
11388 	}
11389 
11390 	/* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */
11391 
11392 	if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11393 		if (_rtw_memcmp(extra, "wfdenable=", 10)) {
11394 			wrqu->data.length -= 10;
11395 			rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]);
11396 			return ret;
11397 		}
11398 	}
11399 
11400 	if (_rtw_memcmp(extra, "weaksec=", 8)) {
11401 		wrqu->data.length -= 8;
11402 		rtw_tdls_weaksec(dev, info, wrqu, &extra[8]);
11403 		return ret;
11404 	} else if (_rtw_memcmp(extra, "tdlsenable=", 11)) {
11405 		wrqu->data.length -= 11;
11406 		rtw_tdls_enable(dev, info, wrqu, &extra[11]);
11407 		return ret;
11408 	}
11409 
11410 	if (_rtw_memcmp(extra, "setup=", 6)) {
11411 		wrqu->data.length -= 6;
11412 		rtw_tdls_setup(dev, info, wrqu, &extra[6]);
11413 	} else if (_rtw_memcmp(extra, "tear=", 5)) {
11414 		wrqu->data.length -= 5;
11415 		rtw_tdls_teardown(dev, info, wrqu, &extra[5]);
11416 	} else if (_rtw_memcmp(extra, "dis=", 4)) {
11417 		wrqu->data.length -= 4;
11418 		rtw_tdls_discovery(dev, info, wrqu, &extra[4]);
11419 	} else if (_rtw_memcmp(extra, "swoff=", 6)) {
11420 		wrqu->data.length -= 6;
11421 		rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]);
11422 	} else if (_rtw_memcmp(extra, "sw=", 3)) {
11423 		wrqu->data.length -= 3;
11424 		rtw_tdls_ch_switch(dev, info, wrqu, &extra[3]);
11425 	} else if (_rtw_memcmp(extra, "dumpstack=", 10)) {
11426 		wrqu->data.length -= 10;
11427 		rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]);
11428 	} else if (_rtw_memcmp(extra, "offchnum=", 9)) {
11429 		wrqu->data.length -= 9;
11430 		rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]);
11431 	} else if (_rtw_memcmp(extra, "choffset=", 9)) {
11432 		wrqu->data.length -= 9;
11433 		rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]);
11434 	} else if (_rtw_memcmp(extra, "pson=", 5)) {
11435 		wrqu->data.length -= 5;
11436 		rtw_tdls_pson(dev, info, wrqu, &extra[5]);
11437 	} else if (_rtw_memcmp(extra, "psoff=", 6)) {
11438 		wrqu->data.length -= 6;
11439 		rtw_tdls_psoff(dev, info, wrqu, &extra[6]);
11440 	}
11441 
11442 #ifdef CONFIG_WFD
11443 	if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11444 		if (_rtw_memcmp(extra, "setip=", 6)) {
11445 			wrqu->data.length -= 6;
11446 			rtw_tdls_setip(dev, info, wrqu, &extra[6]);
11447 		} else if (_rtw_memcmp(extra, "tprobe=", 6))
11448 			issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
11449 	}
11450 #endif /* CONFIG_WFD */
11451 
11452 #endif /* CONFIG_TDLS */
11453 
11454 	return ret;
11455 }
11456 
11457 
11458 static int rtw_tdls_get(struct net_device *dev,
11459 			struct iw_request_info *info,
11460 			union iwreq_data *wrqu, char *extra)
11461 {
11462 	int ret = 0;
11463 
11464 #ifdef CONFIG_TDLS
11465 
11466 	RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
11467 
11468 	if (_rtw_memcmp(wrqu->data.pointer, "ip", 2))
11469 		rtw_tdls_getip(dev, info, wrqu, extra);
11470 	else if (_rtw_memcmp(wrqu->data.pointer, "port", 4))
11471 		rtw_tdls_getport(dev, info, wrqu, extra);
11472 	/* WFDTDLS, for sigma test */
11473 	else if (_rtw_memcmp(wrqu->data.pointer, "dis", 3))
11474 		rtw_tdls_dis_result(dev, info, wrqu, extra);
11475 	else if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
11476 		rtw_wfd_tdls_status(dev, info, wrqu, extra);
11477 	else if (_rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9))
11478 		rtw_tdls_getsta(dev, info, wrqu, extra);
11479 	else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7))
11480 		rtw_tdls_get_best_ch(dev, info, wrqu, extra);
11481 #endif /* CONFIG_TDLS */
11482 
11483 	return ret;
11484 }
11485 
11486 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
11487 
11488 #if defined(CONFIG_RTL8188E)
11489 #include <rtl8188e_hal.h>
11490 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11491 #define cal_txdesc_chksum(padapter, desc) rtl8188e_cal_txdesc_chksum(desc)
11492 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11493 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11494 #define fill_default_txdesc rtl8188es_fill_default_txdesc
11495 #endif /* CONFIG_SDIO_HCI */
11496 #endif /* CONFIG_RTL8188E */
11497 #if defined(CONFIG_RTL8723B)
11498 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11499 #define cal_txdesc_chksum(padapter, desc) rtl8723b_cal_txdesc_chksum(desc)
11500 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11501 #define fill_default_txdesc rtl8723b_fill_default_txdesc
11502 #endif /* CONFIG_RTL8723B */
11503 
11504 #if defined(CONFIG_RTL8703B)
11505 /* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11506 #define cal_txdesc_chksum(padapter, desc) rtl8703b_cal_txdesc_chksum(desc)
11507 /* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11508 #define fill_default_txdesc rtl8703b_fill_default_txdesc
11509 #endif /* CONFIG_RTL8703B */
11510 
11511 #if defined(CONFIG_RTL8723D)
11512 /* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11513 #define cal_txdesc_chksum(padapter, desc) rtl8723d_cal_txdesc_chksum(desc)
11514 /* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11515 #define fill_default_txdesc rtl8723d_fill_default_txdesc
11516 #endif /* CONFIG_RTL8723D */
11517 
11518 #if defined(CONFIG_RTL8710B)
11519 #define cal_txdesc_chksum(padapter, desc) rtl8710b_cal_txdesc_chksum(desc)
11520 #define fill_default_txdesc rtl8710b_fill_default_txdesc
11521 #endif /* CONFIG_RTL8710B */
11522 
11523 #if defined(CONFIG_RTL8192E)
11524 extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11525 #define cal_txdesc_chksum(padapter, desc) rtl8192e_cal_txdesc_chksum(desc)
11526 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11527 extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11528 #define fill_default_txdesc rtl8192es_fill_default_txdesc
11529 #endif /* CONFIG_SDIO_HCI */
11530 #endif /* CONFIG_RTL8192E */
11531 
11532 #if defined(CONFIG_RTL8192F)
11533 /* extern void rtl8192f_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11534 #define cal_txdesc_chksum(padapter, desc) rtl8192f_cal_txdesc_chksum(desc)
11535 /* extern void rtl8192f_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11536 #define fill_default_txdesc rtl8192f_fill_default_txdesc
11537 #endif /* CONFIG_RTL8192F */
11538 
11539 #ifdef CONFIG_RTL8723F
11540 #include <../../hal/rtl8723f/rtl8723f.h>
11541 
11542 #define REG_LOOPBACK_ENABLE 0x0103
11543 #define LOOKBACK_ENABLE_VALUE 0x0b
11544 #define cal_txdesc_chksum(padapter, desc) rtl8723f_cal_txdesc_chksum(padapter, desc)
11545 #define dump_txdesc_data(padapter, desc) rtl8723f_dbg_dump_tx_desc(padapter, DATA_FRAMETAG, desc);
11546 #define get_rx_desc(rx_desc, rxbuf) rtl8723f_rxdesc2attribute(rx_desc, rxbuf)
11547 #define hal_init rtl8723f_hal_init
11548 #endif /* CONFIG_RTL8723F */
11549 
11550 void dbg_dump_pkt(char *s, u8 *buf, u8 len)
11551 {
11552 	u8 i, j = 1;
11553 
11554 	RTW_INFO("%s size = %u\n", s, len);
11555 
11556 	for (i = 0; (i + 4) < len; i += 4) {
11557 		if (j % 4 == 1)
11558 			RTW_PRINT("idx:%u:", i);
11559 		_RTW_PRINT(" 0x%02x 0x%02x 0x%02x 0x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
11560 		if ((j++) % 4 == 0)
11561 			_RTW_PRINT("\n");
11562 	}
11563 
11564 	for (; i < len ; i++) {
11565 		_RTW_PRINT(" 0x%02x", buf[i]);
11566 	}
11567 	_RTW_PRINT("\n ================================\n");
11568 }
11569 
11570 static s32 initLoopback(PADAPTER padapter)
11571 {
11572 	PLOOPBACKDATA ploopback;
11573 
11574 	if (padapter->ploopback == NULL) {
11575 		ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
11576 		if (ploopback == NULL)
11577 			return -ENOMEM;
11578 
11579 		_rtw_init_sema(&ploopback->sema, 0);
11580 		ploopback->bstop = _TRUE;
11581 		ploopback->cnt = 0;
11582 		ploopback->size = 300;
11583 		_rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
11584 
11585 		padapter->ploopback = ploopback;
11586 	}
11587 
11588 	return 0;
11589 }
11590 
11591 static void freeLoopback(PADAPTER padapter)
11592 {
11593 	PLOOPBACKDATA ploopback;
11594 
11595 	ploopback = padapter->ploopback;
11596 	if (ploopback) {
11597 		rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA));
11598 		padapter->ploopback = NULL;
11599 	}
11600 }
11601 
11602 static s32 initpseudoadhoc(PADAPTER padapter)
11603 {
11604 	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
11605 	s32 err;
11606 
11607 	networkType = Ndis802_11IBSS;
11608 	err = rtw_set_802_11_infrastructure_mode(padapter, networkType, 0);
11609 	if (err == _FALSE)
11610 		return _FAIL;
11611 
11612 	err = rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
11613 	if (err == _FAIL)
11614 		return _FAIL;
11615 
11616 	return _SUCCESS;
11617 }
11618 
11619 static s32 createpseudoadhoc(PADAPTER padapter)
11620 {
11621 	NDIS_802_11_AUTHENTICATION_MODE authmode;
11622 	struct mlme_priv *pmlmepriv;
11623 	NDIS_802_11_SSID *passoc_ssid;
11624 	WLAN_BSSID_EX *pdev_network;
11625 	u8 *pibss;
11626 	u8 ssid[] = "pseduo_ad-hoc";
11627 	s32 err;
11628 	_irqL irqL;
11629 
11630 	pmlmepriv = &padapter->mlmepriv;
11631 
11632 	authmode = Ndis802_11AuthModeOpen;
11633 	err = rtw_set_802_11_authentication_mode(padapter, authmode);
11634 	if (err == _FALSE)
11635 		return _FAIL;
11636 
11637 	passoc_ssid = &pmlmepriv->assoc_ssid;
11638 	_rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
11639 	passoc_ssid->SsidLength = sizeof(ssid) - 1;
11640 	_rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
11641 
11642 	pdev_network = &padapter->registrypriv.dev_network;
11643 	pibss = padapter->registrypriv.dev_network.MacAddress;
11644 	_rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
11645 
11646 	rtw_update_registrypriv_dev_network(padapter);
11647 	rtw_generate_random_ibss(pibss);
11648 
11649 	_enter_critical_bh(&pmlmepriv->lock, &irqL);
11650 	/*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
11651 	init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
11652 
11653 	_exit_critical_bh(&pmlmepriv->lock, &irqL);
11654 
11655 #if 0
11656 	err = rtw_create_ibss_cmd(padapter, 0);
11657 	if (err == _FAIL)
11658 		return _FAIL;
11659 #else
11660 	{
11661 		struct wlan_network *pcur_network;
11662 		struct sta_info *psta;
11663 
11664 		/* 3  create a new psta */
11665 		pcur_network = &pmlmepriv->cur_network;
11666 
11667 		/* clear psta in the cur_network, if any */
11668 		psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
11669 		if (psta)
11670 			rtw_free_stainfo(padapter, psta);
11671 
11672 		psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
11673 		if (psta == NULL)
11674 			return _FAIL;
11675 
11676 		/* 3  join psudo AdHoc */
11677 		pcur_network->join_res = 1;
11678 		pcur_network->aid = psta->cmn.aid = 1;
11679 		_rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
11680 
11681 		/* set msr to WIFI_FW_ADHOC_STATE */
11682 		padapter->hw_port = HW_PORT0;
11683 		Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11684 
11685 	}
11686 #endif
11687 
11688 	return _SUCCESS;
11689 }
11690 
11691 static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size)
11692 {
11693 	struct xmit_priv *pxmitpriv;
11694 	struct xmit_frame *pframe;
11695 	struct xmit_buf *pxmitbuf;
11696 	struct pkt_attrib *pattrib;
11697 	struct tx_desc *desc;
11698 	u8 *pkt_start, *pkt_end, *ptr;
11699 	struct rtw_ieee80211_hdr *hdr;
11700 	s32 bmcast;
11701 	_irqL irqL;
11702 
11703 
11704 	if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ)
11705 		return NULL;
11706 
11707 	pxmitpriv = &padapter->xmitpriv;
11708 	pframe = NULL;
11709 
11710 	/* 2 1. allocate xmit frame */
11711 	pframe = rtw_alloc_xmitframe(pxmitpriv, 0);
11712 	if (pframe == NULL)
11713 		return NULL;
11714 	pframe->padapter = padapter;
11715 
11716 	/* 2 2. allocate xmit buffer */
11717 	_enter_critical_bh(&pxmitpriv->lock, &irqL);
11718 	pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
11719 	_exit_critical_bh(&pxmitpriv->lock, &irqL);
11720 	if (pxmitbuf == NULL) {
11721 		rtw_free_xmitframe(pxmitpriv, pframe);
11722 		return NULL;
11723 	}
11724 
11725 	pframe->pxmitbuf = pxmitbuf;
11726 	pframe->buf_addr = pxmitbuf->pbuf;
11727 	pxmitbuf->priv_data = pframe;
11728 
11729 	/* 2 3. update_attrib() */
11730 	pattrib = &pframe->attrib;
11731 
11732 	/* init xmitframe attribute */
11733 	_rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
11734 
11735 	pattrib->ether_type = 0x8723;
11736 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
11737 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
11738 	_rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11739 	_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
11740 
11741 	/*	pattrib->dhcp_pkt = 0;
11742 	 *	pattrib->pktlen = 0; */
11743 	pattrib->ack_policy = 0;
11744 	/*	pattrib->pkt_hdrlen = ETH_HLEN; */
11745 	pattrib->hdrlen = WLAN_HDR_A3_LEN;
11746 	pattrib->subtype = WIFI_DATA;
11747 	pattrib->priority = 0;
11748 	pattrib->qsel = pattrib->priority;
11749 	/*	do_queue_select(padapter, pattrib); */
11750 	pattrib->nr_frags = 1;
11751 	pattrib->encrypt = 0;
11752 	pattrib->bswenc = _FALSE;
11753 	pattrib->qos_en = _FALSE;
11754 
11755 	bmcast = IS_MCAST(pattrib->ra);
11756 	if (bmcast)
11757 		pattrib->psta = rtw_get_bcmc_stainfo(padapter);
11758 	else
11759 		pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
11760 
11761 	pattrib->mac_id = pattrib->psta->cmn.mac_id;
11762 	pattrib->pktlen = size;
11763 	pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
11764 
11765 	/* 2 4. fill TX descriptor */
11766 	desc = (struct tx_desc *)pframe->buf_addr;
11767 	_rtw_memset(desc, 0, TXDESC_SIZE);
11768 
11769 	fill_default_txdesc(pframe, (u8 *)desc);
11770 
11771 #if 0
11772 	/* Hw set sequence number */
11773 	((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable
11774  * ((PTXDESC)desc)->hwseq_sel = 0;  */ /* HWSEQ_SEL */
11775 
11776 	((PTXDESC)desc)->disdatafb = 1;
11777 
11778 	/* convert to little endian */
11779 	desc->txdw0 = cpu_to_le32(desc->txdw0);
11780 	desc->txdw1 = cpu_to_le32(desc->txdw1);
11781 	desc->txdw2 = cpu_to_le32(desc->txdw2);
11782 	desc->txdw3 = cpu_to_le32(desc->txdw3);
11783 	desc->txdw4 = cpu_to_le32(desc->txdw4);
11784 	desc->txdw5 = cpu_to_le32(desc->txdw5);
11785 	desc->txdw6 = cpu_to_le32(desc->txdw6);
11786 	desc->txdw7 = cpu_to_le32(desc->txdw7);
11787 #ifdef CONFIG_PCI_HCI
11788 	desc->txdw8 = cpu_to_le32(desc->txdw8);
11789 	desc->txdw9 = cpu_to_le32(desc->txdw9);
11790 	desc->txdw10 = cpu_to_le32(desc->txdw10);
11791 	desc->txdw11 = cpu_to_le32(desc->txdw11);
11792 	desc->txdw12 = cpu_to_le32(desc->txdw12);
11793 	desc->txdw13 = cpu_to_le32(desc->txdw13);
11794 	desc->txdw14 = cpu_to_le32(desc->txdw14);
11795 	desc->txdw15 = cpu_to_le32(desc->txdw15);
11796 #endif
11797 #endif
11798 
11799 	cal_txdesc_chksum(padapter, (u8*)desc);
11800 	/* dump_txdesc_data(padapter, (u8*)desc); */
11801 
11802 	/* 2 5. coalesce */
11803 	pkt_start = pframe->buf_addr + TXDESC_SIZE;
11804 	pkt_end = pkt_start + pattrib->last_txcmdsz;
11805 
11806 	/* 3 5.1. make wlan header, make_wlanhdr() */
11807 	hdr = (struct rtw_ieee80211_hdr *)pkt_start;
11808 	set_frame_sub_type(&hdr->frame_ctl, pattrib->subtype);
11809 	_rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */
11810 	_rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */
11811 	_rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */
11812 
11813 	/* 3 5.2. make payload */
11814 	ptr = pkt_start + pattrib->hdrlen;
11815 	get_random_bytes(ptr, pkt_end - ptr);
11816 
11817 	pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
11818 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
11819 	pxmitbuf->ptail += pxmitbuf->len;
11820 #endif
11821 
11822 	dbg_dump_pkt("TX packet", pxmitbuf->pbuf, pxmitbuf->len);
11823 
11824 	return pframe;
11825 }
11826 
11827 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
11828 {
11829 	struct xmit_priv *pxmitpriv;
11830 	struct xmit_buf *pxmitbuf;
11831 
11832 	pxmitpriv = &padapter->xmitpriv;
11833 	pxmitbuf = pframe->pxmitbuf;
11834 
11835 	rtw_free_xmitframe(pxmitpriv, pframe);
11836 	rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
11837 }
11838 
11839 static void printdata(u8 *pbuf, u32 len)
11840 {
11841 	u32 i, val;
11842 
11843 	for (i = 0; (i + 4) <= len; i += 4) {
11844 		printk("%08X", *(u32 *)(pbuf + i));
11845 		if ((i + 4) & 0x1F)
11846 			printk(" ");
11847 		else
11848 			printk("\n");
11849 	}
11850 
11851 	if (i < len) {
11852 #ifdef CONFIG_BIG_ENDIAN
11853 		for (; i < len, i++)
11854 			printk("%02X", pbuf + i);
11855 #else /* CONFIG_LITTLE_ENDIAN */
11856 #if 0
11857 		val = 0;
11858 		_rtw_memcpy(&val, pbuf + i, len - i);
11859 		printk("%8X", val);
11860 #else
11861 		u8 str[9];
11862 		u8 n;
11863 		val = 0;
11864 		n = len - i;
11865 		_rtw_memcpy(&val, pbuf + i, n);
11866 		sprintf(str, "%08X", val);
11867 		n = (4 - n) * 2;
11868 		printk("%8s", str + n);
11869 #endif
11870 #endif /* CONFIG_LITTLE_ENDIAN */
11871 	}
11872 	printk("\n");
11873 }
11874 
11875 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
11876 {
11877 	struct rx_pkt_attrib rx_desc;
11878 #if 0
11879 	struct recv_stat *prxstat;
11880 	struct recv_stat report;
11881 	PRXREPORT prxreport;
11882 #endif
11883 	u32 rxpktsize;
11884 	u8 drvinfosize;
11885 	u8 shiftsize;
11886 	u8 ret = _FALSE;
11887 	u8 skip_len = 4; /* Don't compare the frame control and duration field */
11888 	get_rx_desc(&rx_desc, rxbuf);
11889 	rxpktsize = rx_desc.pkt_len;
11890 	drvinfosize = rx_desc.drvinfo_sz;
11891 	shiftsize = rx_desc.shift_sz;
11892 
11893 #if 0
11894 	prxstat = (struct recv_stat *)rxbuf;
11895 	report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
11896 	report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
11897 	report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
11898 	report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
11899 	report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
11900 	report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
11901 
11902 	prxreport = (PRXREPORT)&report;
11903 	drvinfosize = prxreport->drvinfosize << 3;
11904 	rxpktsize = prxreport->pktlen;
11905 #endif
11906 
11907 	if (rtw_hal_rcr_check(padapter, RCR_APPFCS))
11908 		rxpktsize -= IEEE80211_FCS_LEN;
11909 
11910 	if ((txsz - TXDESC_SIZE) != rxpktsize) {
11911 		RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n",
11912 			 __func__, txsz - TXDESC_SIZE, rxpktsize);
11913 		ret = _FALSE;
11914 	} else {
11915 		ret = _rtw_memcmp(txbuf + TXDESC_SIZE + skip_len, \
11916 				  rxbuf + RXDESC_SIZE + skip_len + drvinfosize, \
11917 				  txsz - TXDESC_SIZE - skip_len);
11918 		if (ret == _FALSE)
11919 			RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__);
11920 	}
11921 
11922 	if (ret == _FALSE) {
11923 		RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
11924 			 __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
11925 		dbg_dump_pkt("TX DESC", txbuf, TXDESC_SIZE);
11926 		dbg_dump_pkt("TX content", txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
11927 
11928 		RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
11929 			__func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
11930 		if (rxpktsize != 0) {
11931 			dbg_dump_pkt("RX DESC", rxbuf, RXDESC_SIZE);
11932 			dbg_dump_pkt("RX drvinfo", rxbuf + RXDESC_SIZE, drvinfosize);
11933 			dbg_dump_pkt("RX packet content", rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
11934 		} else {
11935 			RTW_INFO("%s: RX data size=%d\n", __func__, rxsz);
11936 		}
11937 	}
11938 
11939 	return ret;
11940 }
11941 
11942 thread_return lbk_thread(thread_context context)
11943 {
11944 	s32 err;
11945 	PADAPTER padapter;
11946 	PLOOPBACKDATA ploopback;
11947 	struct xmit_frame *pxmitframe;
11948 	u32 cnt, ok, fail, headerlen;
11949 	u32 pktsize;
11950 	u32 ff_hwaddr;
11951 
11952 	padapter = (PADAPTER)context;
11953 	ploopback = padapter->ploopback;
11954 	if (ploopback == NULL)
11955 		return -1;
11956 	cnt = 0;
11957 	ok = 0;
11958 	fail = 0;
11959 
11960 	thread_enter("RTW_LBK_THREAD");
11961 	/* daemonize("%s", "RTW_LBK_THREAD"); */
11962 	allow_signal(SIGTERM);
11963 
11964 	do {
11965 		if (ploopback->size == 0) {
11966 			get_random_bytes(&pktsize, 4);
11967 			pktsize = (pktsize % 1535) + 1; /* 1~1535 */
11968 		} else
11969 			pktsize = ploopback->size;
11970 
11971 		pxmitframe = createloopbackpkt(padapter, pktsize);
11972 		if (pxmitframe == NULL) {
11973 			sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
11974 			break;
11975 		}
11976 
11977 		ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
11978 		_rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
11979 		ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
11980 		cnt++;
11981 		RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
11982 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
11983 		pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
11984 #endif
11985 		rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
11986 
11987 		/* wait for rx pkt */
11988 		RTW_INFO("%s: wait for rx packet\n", __func__);
11989 		_rtw_down_sema(&ploopback->sema);
11990 
11991 		err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
11992 		if (err == _TRUE)
11993 			ok++;
11994 		else
11995 			fail++;
11996 
11997 		ploopback->txsize = 0;
11998 		_rtw_memset(ploopback->txbuf, 0, 0x8000);
11999 		ploopback->rxsize = 0;
12000 		_rtw_memset(ploopback->rxbuf, 0, 0x8000);
12001 
12002 		freeloopbackpkt(padapter, pxmitframe);
12003 		pxmitframe = NULL;
12004 
12005 		flush_signals_thread();
12006 
12007 		if ((ploopback->bstop == _TRUE) ||
12008 		    ((ploopback->cnt != 0) && (ploopback->cnt == cnt))) {
12009 			u32 ok_rate, fail_rate, all;
12010 			all = cnt;
12011 			ok_rate = (ok * 100) / all;
12012 			fail_rate = (fail * 100) / all;
12013 			sprintf(ploopback->msg, \
12014 				"loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)", \
12015 				ok_rate, ok, all, fail_rate, fail, all);
12016 			break;
12017 		}
12018 	} while (1);
12019 
12020 	ploopback->bstop = _TRUE;
12021 
12022 	thread_exit(NULL);
12023 	return 0;
12024 }
12025 
12026 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg)
12027 {
12028 	PLOOPBACKDATA ploopback;
12029 	u32 len;
12030 	s32 err;
12031 
12032 	ploopback = padapter->ploopback;
12033 
12034 	if (ploopback) {
12035 		if (ploopback->bstop == _FALSE) {
12036 			ploopback->bstop = _TRUE;
12037 			_rtw_up_sema(&ploopback->sema);
12038 		}
12039 		len = 0;
12040 		do {
12041 			len = strlen(ploopback->msg);
12042 			if (len)
12043 				break;
12044 			rtw_msleep_os(1);
12045 		} while (1);
12046 		RTW_INFO("Free loopback, end the test.\n");
12047 		_rtw_memcpy(pmsg, ploopback->msg, len + 1);
12048 		freeLoopback(padapter);
12049 
12050 		return;
12051 	}
12052 
12053 	/* disable dynamic algorithm	 */
12054 #ifndef CONFIG_NO_PHYDM
12055 	rtw_phydm_ability_backup(padapter);
12056 	rtw_phydm_func_disable_all(padapter);
12057 #endif
12058 
12059 	/* create pseudo ad-hoc connection */
12060 	err = initpseudoadhoc(padapter);
12061 	if (err == _FAIL) {
12062 		sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
12063 		return;
12064 	}
12065 
12066 	err = createpseudoadhoc(padapter);
12067 	if (err == _FAIL) {
12068 		sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
12069 		return;
12070 	}
12071 
12072 	err = initLoopback(padapter);
12073 	if (err) {
12074 		sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
12075 		return;
12076 	}
12077 
12078 	ploopback = padapter->ploopback;
12079 
12080 	ploopback->bstop = _FALSE;
12081 	ploopback->cnt = cnt;
12082 	ploopback->size = size;
12083 	ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
12084 	if (IS_ERR(ploopback->lbkthread)) {
12085 		freeLoopback(padapter);
12086 		ploopback->lbkthread = NULL;
12087 		sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
12088 		return;
12089 	}
12090 
12091 	sprintf(pmsg, "loopback start! cnt=%d", cnt);
12092 }
12093 #endif /* CONFIG_MAC_LOOPBACK_DRIVER */
12094 
12095 static int rtw_test(
12096 	struct net_device *dev,
12097 	struct iw_request_info *info,
12098 	union iwreq_data *wrqu, char *extra)
12099 {
12100 	u32 len;
12101 	u8 *pbuf, *pch;
12102 	char *ptmp;
12103 	u8 *delim = ",";
12104 	PADAPTER padapter = rtw_netdev_priv(dev);
12105 
12106 
12107 	RTW_INFO("+%s\n", __func__);
12108 	len = wrqu->data.length;
12109 
12110 	pbuf = (u8 *)rtw_zmalloc(len + 1);
12111 	if (pbuf == NULL) {
12112 		RTW_INFO("%s: no memory!\n", __func__);
12113 		return -ENOMEM;
12114 	}
12115 
12116 	if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
12117 		rtw_mfree(pbuf, len + 1);
12118 		RTW_INFO("%s: copy from user fail!\n", __func__);
12119 		return -EFAULT;
12120 	}
12121 
12122 	pbuf[len] = '\0';
12123 
12124 	RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
12125 
12126 	ptmp = (char *)pbuf;
12127 	pch = strsep(&ptmp, delim);
12128 	if ((pch == NULL) || (strlen(pch) == 0)) {
12129 		rtw_mfree(pbuf, len);
12130 		RTW_INFO("%s: parameter error(level 1)!\n", __func__);
12131 		return -EFAULT;
12132 	}
12133 
12134 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
12135 	if (strcmp(pch, "init") == 0) {
12136 		u8 status;
12137 
12138 		rtw_clr_drv_stopped(padapter); /* should clear drv_stopped, otherwise driver can't trx */
12139 
12140 		status = hal_init(padapter);
12141 		RTW_INFO("HAL_INIT %s\n", status ? "SUCCESS" : "FAIL");
12142 
12143 		rtw_write8(padapter, REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE);
12144 		RTW_INFO("Write 0x%03x to 0x%02x, enable loopback\n",
12145 			REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE);
12146 
12147 	} else if (strcmp(pch, "loopback") == 0) {
12148 		s32 cnt = 0;
12149 		u32 size = 64;
12150 
12151 		pch = strsep(&ptmp, delim);
12152 		if ((pch == NULL) || (strlen(pch) == 0)) {
12153 			rtw_mfree(pbuf, len);
12154 			RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12155 			return -EFAULT;
12156 		}
12157 
12158 		sscanf(pch, "%d", &cnt);
12159 		RTW_INFO("%s: loopback cnt=%d\n", __func__, cnt);
12160 
12161 		pch = strsep(&ptmp, delim);
12162 		if ((pch == NULL) || (strlen(pch) == 0)) {
12163 			rtw_mfree(pbuf, len);
12164 			RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12165 			return -EFAULT;
12166 		}
12167 
12168 		sscanf(pch, "%d", &size);
12169 		RTW_INFO("%s: loopback size=%d\n", __func__, size);
12170 
12171 		loopbackTest(padapter, cnt, size, extra);
12172 		wrqu->data.length = strlen(extra) + 1;
12173 
12174 		goto free_buf;
12175 	}
12176 #endif
12177 
12178 
12179 #ifdef CONFIG_BT_COEXIST
12180 	if (strcmp(pch, "bton") == 0) {
12181 		rtw_btcoex_SetManualControl(padapter, _FALSE);
12182 		goto free_buf;
12183 	} else if (strcmp(pch, "btoff") == 0) {
12184 		rtw_btcoex_SetManualControl(padapter, _TRUE);
12185 		goto free_buf;
12186 	} else if (strcmp(pch, "coex_auto") == 0) {
12187 		rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_AUTO);
12188 		goto free_buf;
12189 	} else if (strcmp(pch, "coex_force_freerun") == 0) {
12190 		rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_FREERUN);
12191 		goto free_buf;
12192 	} else if (strcmp(pch, "coex_force_tdma") == 0) {
12193 		rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_TDMA);
12194 		goto free_buf;
12195 	}
12196 #endif
12197 
12198 	if (strcmp(pch, "h2c") == 0) {
12199 		u8 param[8];
12200 		u8 count = 0;
12201 		u32 tmp;
12202 		u8 i;
12203 		u32 pos;
12204 		u8 ret;
12205 
12206 		do {
12207 			pch = strsep(&ptmp, delim);
12208 			if ((pch == NULL) || (strlen(pch) == 0))
12209 				break;
12210 
12211 			sscanf(pch, "%x", &tmp);
12212 			param[count++] = (u8)tmp;
12213 		} while (count < 8);
12214 
12215 		if (count == 0) {
12216 			rtw_mfree(pbuf, len);
12217 			RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12218 			return -EFAULT;
12219 		}
12220 
12221 		ret = rtw_test_h2c_cmd(padapter, param, count);
12222 
12223 		pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
12224 		for (i = 1; i < count; i++)
12225 			pos += sprintf(extra + pos, "%02x,", param[i]);
12226 		extra[pos] = 0;
12227 		pos--;
12228 		pos += sprintf(extra + pos, " %s", ret == _FAIL ? "FAIL" : "OK");
12229 
12230 		wrqu->data.length = strlen(extra) + 1;
12231 
12232 		goto free_buf;
12233 	}
12234 
12235 	if (strcmp(pch, "dump_mac_reg") == 0) {
12236 		mac_reg_dump(RTW_DBGDUMP, padapter);
12237 		goto free_buf;
12238 	}
12239 
12240 free_buf:
12241 	rtw_mfree(pbuf, len);
12242 	return 0;
12243 }
12244 
12245 static iw_handler rtw_handlers[] = {
12246 #ifdef CONFIG_IOCTL_WEXT
12247 	NULL,					/* SIOCSIWCOMMIT */
12248 	rtw_wx_get_name,		/* SIOCGIWNAME */
12249 	dummy,					/* SIOCSIWNWID */
12250 	dummy,					/* SIOCGIWNWID */
12251 	rtw_wx_set_freq,		/* SIOCSIWFREQ */
12252 	rtw_wx_get_freq,		/* SIOCGIWFREQ */
12253 	rtw_wx_set_mode,		/* SIOCSIWMODE */
12254 	rtw_wx_get_mode,		/* SIOCGIWMODE */
12255 	dummy,					/* SIOCSIWSENS */
12256 	rtw_wx_get_sens,		/* SIOCGIWSENS */
12257 	NULL,					/* SIOCSIWRANGE */
12258 	rtw_wx_get_range,		/* SIOCGIWRANGE */
12259 	rtw_wx_set_priv,		/* SIOCSIWPRIV */
12260 	NULL,					/* SIOCGIWPRIV */
12261 	NULL,					/* SIOCSIWSTATS */
12262 	NULL,					/* SIOCGIWSTATS */
12263 	dummy,					/* SIOCSIWSPY */
12264 	dummy,					/* SIOCGIWSPY */
12265 	NULL,					/* SIOCGIWTHRSPY */
12266 	NULL,					/* SIOCWIWTHRSPY */
12267 	rtw_wx_set_wap,		/* SIOCSIWAP */
12268 	rtw_wx_get_wap,		/* SIOCGIWAP */
12269 	rtw_wx_set_mlme,		/* request MLME operation; uses struct iw_mlme */
12270 	dummy,					/* SIOCGIWAPLIST -- depricated */
12271 	rtw_wx_set_scan,		/* SIOCSIWSCAN */
12272 	rtw_wx_get_scan,		/* SIOCGIWSCAN */
12273 	rtw_wx_set_essid,		/* SIOCSIWESSID */
12274 	rtw_wx_get_essid,		/* SIOCGIWESSID */
12275 	dummy,					/* SIOCSIWNICKN */
12276 	rtw_wx_get_nick,		/* SIOCGIWNICKN */
12277 	NULL,					/* -- hole -- */
12278 	NULL,					/* -- hole -- */
12279 	rtw_wx_set_rate,		/* SIOCSIWRATE */
12280 	rtw_wx_get_rate,		/* SIOCGIWRATE */
12281 	rtw_wx_set_rts,			/* SIOCSIWRTS */
12282 	rtw_wx_get_rts,			/* SIOCGIWRTS */
12283 	rtw_wx_set_frag,		/* SIOCSIWFRAG */
12284 	rtw_wx_get_frag,		/* SIOCGIWFRAG */
12285 	dummy,					/* SIOCSIWTXPOW */
12286 	dummy,					/* SIOCGIWTXPOW */
12287 	dummy,					/* SIOCSIWRETRY */
12288 	rtw_wx_get_retry,		/* SIOCGIWRETRY */
12289 	rtw_wx_set_enc,			/* SIOCSIWENCODE */
12290 	rtw_wx_get_enc,			/* SIOCGIWENCODE */
12291 	dummy,					/* SIOCSIWPOWER */
12292 	rtw_wx_get_power,		/* SIOCGIWPOWER */
12293 	NULL,					/*---hole---*/
12294 	NULL,					/*---hole---*/
12295 	rtw_wx_set_gen_ie,		/* SIOCSIWGENIE */
12296 	NULL,					/* SIOCGWGENIE */
12297 	rtw_wx_set_auth,		/* SIOCSIWAUTH */
12298 	NULL,					/* SIOCGIWAUTH */
12299 	rtw_wx_set_enc_ext,		/* SIOCSIWENCODEEXT */
12300 	NULL,					/* SIOCGIWENCODEEXT */
12301 	rtw_wx_set_pmkid,		/* SIOCSIWPMKSA */
12302 	NULL,					/*---hole---*/
12303 #endif
12304 };
12305 
12306 
12307 static const struct iw_priv_args rtw_private_args[] = {
12308 	{
12309 		SIOCIWFIRSTPRIV + 0x0,
12310 		IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
12311 	},
12312 	{
12313 		SIOCIWFIRSTPRIV + 0x1,
12314 		IW_PRIV_TYPE_CHAR | 0x7FF,
12315 		IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
12316 	},
12317 	{
12318 		SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
12319 	},
12320 	{
12321 		SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
12322 	},
12323 	{
12324 		SIOCIWFIRSTPRIV + 0x4,
12325 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
12326 	},
12327 	{
12328 		SIOCIWFIRSTPRIV + 0x5,
12329 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
12330 	},
12331 	{
12332 		SIOCIWFIRSTPRIV + 0x6,
12333 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
12334 	},
12335 	/* for PLATFORM_MT53XX	 */
12336 	{
12337 		SIOCIWFIRSTPRIV + 0x7,
12338 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
12339 	},
12340 	{
12341 		SIOCIWFIRSTPRIV + 0x8,
12342 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
12343 	},
12344 	{
12345 		SIOCIWFIRSTPRIV + 0x9,
12346 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
12347 	},
12348 
12349 	/* for RTK_DMP_PLATFORM	 */
12350 	{
12351 		SIOCIWFIRSTPRIV + 0xA,
12352 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
12353 	},
12354 
12355 	{
12356 		SIOCIWFIRSTPRIV + 0xB,
12357 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
12358 	},
12359 	{
12360 		SIOCIWFIRSTPRIV + 0xC,
12361 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
12362 	},
12363 	{
12364 		SIOCIWFIRSTPRIV + 0xD,
12365 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
12366 	},
12367 #if 0
12368 	{
12369 		SIOCIWFIRSTPRIV + 0xE, 0, 0, "wowlan_ctrl"
12370 	},
12371 #endif
12372 	{
12373 		SIOCIWFIRSTPRIV + 0x10,
12374 		IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
12375 	},
12376 	{
12377 		SIOCIWFIRSTPRIV + 0x11,
12378 		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
12379 	},
12380 	{
12381 		SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
12382 	},
12383 	{
12384 		SIOCIWFIRSTPRIV + 0x13,
12385 		IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
12386 	},
12387 	{
12388 		SIOCIWFIRSTPRIV + 0x14,
12389 		IW_PRIV_TYPE_CHAR  | 64, 0, "tdls"
12390 	},
12391 	{
12392 		SIOCIWFIRSTPRIV + 0x15,
12393 		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
12394 	},
12395 	{
12396 		SIOCIWFIRSTPRIV + 0x16,
12397 		IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
12398 	},
12399 #ifdef CONFIG_RTW_80211K
12400 	{
12401 		SIOCIWFIRSTPRIV + 0x17,
12402 		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "rrm"
12403 	},
12404 #else
12405 	{SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 1024 , 0 , "NULL"},
12406 #endif
12407 
12408 #ifdef CONFIG_PLATFORM_CMAP_INTFS
12409 	{SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | 1024 , 0 , "cmap_intfs"},
12410 #else
12411 	{SIOCIWFIRSTPRIV + 0x18, 0, 0, "NULL"},
12412 #endif
12413 
12414 #ifdef CONFIG_MP_INCLUDED
12415 	{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0,  "NULL"},
12416 	{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
12417 #else
12418 	{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0,  "NULL"},
12419 	{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
12420 #endif
12421 	{
12422 		SIOCIWFIRSTPRIV + 0x1D,
12423 		IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
12424 	},
12425 
12426 	{ SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""},  /* set  */
12427 	{ SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},/* get
12428  * --- sub-ioctls definitions --- */
12429 
12430 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
12431 	{ VENDOR_IE_SET, IW_PRIV_TYPE_CHAR | 1024 , 0 , "vendor_ie_set" },
12432 	{ VENDOR_IE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "vendor_ie_get" },
12433 #endif
12434 #if defined(CONFIG_RTL8723B)
12435 	{ MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
12436 	{ MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
12437 #endif
12438 #ifdef CONFIG_WOWLAN
12439 	{ MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
12440 	{ MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },
12441 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
12442 	{ MP_WOW_SET_KEEP_ALIVE_PATTERN ,IW_PRIV_TYPE_CHAR | 1024 , 0 , "wow_keep_alive"},
12443 #endif /* defined (CONFIG_KEEP_ALIVE_PATTERN)*/
12444 #endif
12445 
12446 #ifdef CONFIG_AP_WOWLAN
12447 	{ MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set  */
12448 #endif
12449 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
12450 	{ MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },
12451 	{ MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },
12452 #endif
12453 	{ GET_IC_TYPE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "ic_type" },
12454 };
12455 
12456 
12457 static const struct iw_priv_args rtw_mp_private_args[] = {
12458 	/* --- sub-ioctls definitions --- */
12459 #ifdef CONFIG_MP_INCLUDED
12460 	{ MP_START , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_start" },
12461 	{ MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },
12462 	{ MP_STOP , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_stop" },
12463 	{ MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },
12464 	{ MP_CHL_OFFSET , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ch_offset" },
12465 	{ MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_bandwidth"},
12466 	{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12467 	{ MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_reset_stats"},
12468 	{ MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"},
12469 	{ READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
12470 	{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12471 	{ READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
12472 	{ MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
12473 	{ MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
12474 	{ MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
12475 	{ MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024,  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
12476 	{ MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
12477 	{ WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
12478 	{ WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
12479 	{ MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
12480 	{ MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
12481 	{ MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
12482 	{ EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
12483 	{ EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
12484 	{ MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrtrk"},
12485 	{ MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
12486 	{ MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},
12487 	{ MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setrfpath" },
12488 	{ MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
12489 	{ MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
12490 	{ MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },
12491 	{ MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },
12492 	{ EFUSE_BT_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_bt_mask" },
12493 	{ EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },
12494 	{ EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },
12495 	{ EFUSE_FILE_STORE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_store" },
12496 	{ MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },
12497 	{ MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },
12498 	{ MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },
12499 	{ MP_PWRLMT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrlmt" },
12500 	{ MP_PWRBYRATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrbyrate" },
12501 	{ CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
12502 	{ MP_IQK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_iqk"},
12503 	{ MP_LCK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_lck"},
12504 	{ BT_EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bt_efuse_file" },
12505 	{ MP_SWRFPath, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_swrfpath" },
12506 	{ MP_LINK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_link" },
12507 	{ MP_DPK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk"},
12508 	{ MP_DPK_TRK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk_trk" },
12509 	{ MP_GET_TSSIDE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_tsside" },
12510 	{ MP_SET_TSSIDE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_set_tsside" },
12511 #ifdef CONFIG_RTW_CUSTOMER_STR
12512 	{ MP_CUSTOMER_STR, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "customer_str" },
12513 #endif
12514 
12515 #endif /* CONFIG_MP_INCLUDED */
12516 };
12517 
12518 static iw_handler rtw_private_handler[] = {
12519 	rtw_wx_write32,					/* 0x00 */
12520 	rtw_wx_read32,					/* 0x01 */
12521 	NULL,					/* 0x02 */
12522 #ifdef MP_IOCTL_HDL
12523 	rtw_mp_ioctl_hdl,				/* 0x03 */
12524 #else
12525 	rtw_wx_priv_null,
12526 #endif
12527 	/* for MM DTV platform */
12528 	rtw_get_ap_info,					/* 0x04 */
12529 
12530 	rtw_set_pid,						/* 0x05 */
12531 	rtw_wps_start,					/* 0x06 */
12532 
12533 	/* for PLATFORM_MT53XX */
12534 	rtw_wx_get_sensitivity,			/* 0x07 */
12535 	rtw_wx_set_mtk_wps_probe_ie,	/* 0x08 */
12536 	rtw_wx_set_mtk_wps_ie,			/* 0x09 */
12537 
12538 	/* for RTK_DMP_PLATFORM
12539 	 * Set Channel depend on the country code */
12540 	rtw_wx_set_channel_plan,		/* 0x0A */
12541 
12542 	rtw_dbg_port,					/* 0x0B */
12543 	rtw_wx_write_rf,					/* 0x0C */
12544 	rtw_wx_read_rf,					/* 0x0D */
12545 
12546 	rtw_priv_set,					/*0x0E*/
12547 	rtw_priv_get,					/*0x0F*/
12548 
12549 	rtw_p2p_set,					/* 0x10 */
12550 	rtw_p2p_get,					/* 0x11 */
12551 	NULL,							/* 0x12 */
12552 	rtw_p2p_get2,					/* 0x13 */
12553 
12554 	rtw_tdls,						/* 0x14 */
12555 	rtw_tdls_get,					/* 0x15 */
12556 
12557 	rtw_pm_set,						/* 0x16 */
12558 #ifdef CONFIG_RTW_80211K
12559 	rtw_wx_priv_rrm,				/* 0x17 */
12560 #else
12561 	rtw_wx_priv_null,				/* 0x17 */
12562 #endif
12563 #ifdef CONFIG_PLATFORM_CMAP_INTFS
12564 	cmap_intfs_ioctl,				/* 0x18 */
12565 #else
12566 	NULL,							/* 0x18 */
12567 #endif
12568 	rtw_wx_priv_null,				/* 0x19 */
12569 #ifdef CONFIG_MP_INCLUDED
12570 	rtw_wx_priv_null,				/* 0x1A */
12571 	rtw_wx_priv_null,				/* 0x1B */
12572 #else
12573 	rtw_wx_priv_null,				/* 0x1A */
12574 	rtw_mp_efuse_get,				/* 0x1B */
12575 #endif
12576 	NULL,							/* 0x1C is reserved for hostapd */
12577 	rtw_test,						/* 0x1D */
12578 };
12579 
12580 #ifdef CONFIG_WIRELESS_EXT
12581 #if WIRELESS_EXT >= 17
12582 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
12583 {
12584 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12585 	struct iw_statistics *piwstats = &padapter->iwstats;
12586 	int tmp_level = 0;
12587 	int tmp_qual = 0;
12588 	int tmp_noise = 0;
12589 
12590 	if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) != _TRUE) {
12591 		piwstats->qual.qual = 0;
12592 		piwstats->qual.level = 0;
12593 		piwstats->qual.noise = 0;
12594 		/* RTW_INFO("No link  level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */
12595 	} else {
12596 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
12597 		tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
12598 #else
12599 		tmp_level = padapter->recvpriv.signal_strength;
12600 #endif
12601 
12602 		tmp_qual = padapter->recvpriv.signal_qual;
12603 		#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
12604 		if (IS_NM_ENABLE(padapter)) {
12605 			tmp_noise = rtw_noise_measure_curchan(padapter);
12606 			#ifndef CONFIG_SIGNAL_DISPLAY_DBM
12607 			tmp_noise = translate_dbm_to_percentage(tmp_noise);/*percentage*/
12608 			#endif
12609 		}
12610 		#endif
12611 		/* RTW_INFO("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); */
12612 
12613 		piwstats->qual.level = tmp_level;
12614 		piwstats->qual.qual = tmp_qual;
12615 		piwstats->qual.noise = tmp_noise;
12616 	}
12617 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14))
12618 	piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* |IW_QUAL_DBM; */
12619 #else
12620 #ifdef RTK_DMP_PLATFORM
12621 	/* IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. */
12622 	/* remove this flag for show percentage 0~100 */
12623 	piwstats->qual.updated = 0x07;
12624 #else
12625 	piwstats->qual.updated = 0x0f;
12626 #endif
12627 #endif
12628 
12629 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
12630 	piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
12631 #endif
12632 
12633 	return &padapter->iwstats;
12634 }
12635 #endif
12636 
12637 struct iw_handler_def rtw_handlers_def = {
12638 	.standard = rtw_handlers,
12639 	.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
12640 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) || defined(CONFIG_WEXT_PRIV)
12641 	.private = rtw_private_handler,
12642 	.private_args = (struct iw_priv_args *)rtw_private_args,
12643 	.num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
12644 	.num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
12645 #endif
12646 #if WIRELESS_EXT >= 17
12647 	.get_wireless_stats = rtw_get_wireless_stats,
12648 #endif
12649 };
12650 #endif
12651 
12652 /* copy from net/wireless/wext.c start
12653  * ----------------------------------------------------------------
12654  *
12655  * Calculate size of private arguments
12656  */
12657 static const char iw_priv_type_size[] = {
12658 	0,                              /* IW_PRIV_TYPE_NONE */
12659 	1,                              /* IW_PRIV_TYPE_BYTE */
12660 	1,                              /* IW_PRIV_TYPE_CHAR */
12661 	0,                              /* Not defined */
12662 	sizeof(__u32),                  /* IW_PRIV_TYPE_INT */
12663 	sizeof(struct iw_freq),         /* IW_PRIV_TYPE_FLOAT */
12664 	sizeof(struct sockaddr),        /* IW_PRIV_TYPE_ADDR */
12665 	0,                              /* Not defined */
12666 };
12667 
12668 static int get_priv_size(__u16 args)
12669 {
12670 	int num = args & IW_PRIV_SIZE_MASK;
12671 	int type = (args & IW_PRIV_TYPE_MASK) >> 12;
12672 
12673 	return num * iw_priv_type_size[type];
12674 }
12675 /* copy from net/wireless/wext.c end */
12676 
12677 
12678 static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
12679 {
12680 	int err = 0;
12681 	u8 *input = NULL;
12682 	u32 input_len = 0;
12683 	const char delim[] = " ";
12684 	u8 *output = NULL;
12685 	u32 output_len = 0;
12686 	u32 count = 0;
12687 	u8 *buffer = NULL;
12688 	u32 buffer_len = 0;
12689 	char *ptr = NULL;
12690 	u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */
12691 	u32 cmdlen;
12692 	s32 len;
12693 	u8 *extra = NULL;
12694 	u32 extra_size = 0;
12695 
12696 	s32 k;
12697 	const iw_handler *priv;		/* Private ioctl */
12698 	const struct iw_priv_args *priv_args;	/* Private ioctl description */
12699 	const struct iw_priv_args *mp_priv_args;	/*MP Private ioctl description */
12700 	const struct iw_priv_args *sel_priv_args;	/*Selected Private ioctl description */
12701 	u32 num_priv;				/* Number of ioctl */
12702 	u32 num_priv_args;			/* Number of descriptions */
12703 	u32 num_mp_priv_args;			/*Number of MP descriptions */
12704 	u32 num_sel_priv_args;			/*Number of Selected descriptions */
12705 	iw_handler handler;
12706 	int temp;
12707 	int subcmd = 0;				/* sub-ioctl index */
12708 	int offset = 0;				/* Space for sub-ioctl index */
12709 
12710 	union iwreq_data wdata;
12711 
12712 	_rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
12713 
12714 	input_len = wdata.data.length;
12715 	if (!input_len)
12716 		return -EINVAL;
12717 	input = rtw_zmalloc(input_len);
12718 
12719 	if (input == NULL) {
12720 		err = -EOPNOTSUPP;
12721 		goto exit;
12722 	}
12723 
12724 	if (copy_from_user(input, wdata.data.pointer, input_len)) {
12725 		err = -EFAULT;
12726 		goto exit;
12727 	}
12728 	input[input_len - 1] = '\0';
12729 	ptr = input;
12730 	len = input_len;
12731 
12732 	sscanf(ptr, "%16s", cmdname);
12733 	cmdlen = strlen(cmdname);
12734 	RTW_DBG("%s: cmd=%s\n", __func__, cmdname);
12735 
12736 	/* skip command string */
12737 	if (cmdlen > 0)
12738 		cmdlen += 1; /* skip one space */
12739 	ptr += cmdlen;
12740 	len -= cmdlen;
12741 	RTW_DBG("%s: parameters=%s\n", __func__, ptr);
12742 
12743 	priv = rtw_private_handler;
12744 	priv_args = rtw_private_args;
12745 	mp_priv_args = rtw_mp_private_args;
12746 	num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
12747 	num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
12748 	num_mp_priv_args = sizeof(rtw_mp_private_args) / sizeof(struct iw_priv_args);
12749 
12750 	if (num_priv_args == 0) {
12751 		err = -EOPNOTSUPP;
12752 		goto exit;
12753 	}
12754 
12755 	/* Search the correct ioctl */
12756 	k = -1;
12757 	sel_priv_args = priv_args;
12758 	num_sel_priv_args = num_priv_args;
12759 	while
12760 	((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12761 		;
12762 
12763 	/* If not found... */
12764 	if (k == num_sel_priv_args) {
12765 		k = -1;
12766 		sel_priv_args = mp_priv_args;
12767 		num_sel_priv_args = num_mp_priv_args;
12768 		while
12769 		((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12770 			;
12771 
12772 		if (k == num_sel_priv_args) {
12773 			err = -EOPNOTSUPP;
12774 			goto exit;
12775 		}
12776 	}
12777 
12778 	/* Watch out for sub-ioctls ! */
12779 	if (sel_priv_args[k].cmd < SIOCDEVPRIVATE) {
12780 		int j = -1;
12781 
12782 		/* Find the matching *real* ioctl */
12783 		while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
12784 			 (priv_args[j].set_args != sel_priv_args[k].set_args) ||
12785 			 (priv_args[j].get_args != sel_priv_args[k].get_args)))
12786 			;
12787 
12788 		/* If not found... */
12789 		if (j == num_priv_args) {
12790 			err = -EINVAL;
12791 			goto exit;
12792 		}
12793 
12794 		/* Save sub-ioctl number */
12795 		subcmd = sel_priv_args[k].cmd;
12796 		/* Reserve one int (simplify alignment issues) */
12797 		offset = sizeof(__u32);
12798 		/* Use real ioctl definition from now on */
12799 		k = j;
12800 	}
12801 
12802 	buffer = rtw_zmalloc(4096);
12803 	if (NULL == buffer) {
12804 		err = -ENOMEM;
12805 		goto exit;
12806 	}
12807 
12808 	if (k >= num_priv_args) {
12809 		err = -EINVAL;
12810 		goto exit;
12811 	}
12812 
12813 	/* If we have to set some data */
12814 	if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
12815 	    (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
12816 		u8 *str;
12817 
12818 		switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
12819 		case IW_PRIV_TYPE_BYTE:
12820 			/* Fetch args */
12821 			count = 0;
12822 			do {
12823 				str = strsep(&ptr, delim);
12824 				if (NULL == str || count >= 4096)
12825 					break;
12826 				sscanf(str, "%i", &temp);
12827 				buffer[count++] = (u8)temp;
12828 			} while (1);
12829 			buffer_len = count;
12830 
12831 			/* Number of args to fetch */
12832 			wdata.data.length = count;
12833 			if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12834 				wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12835 
12836 			break;
12837 
12838 		case IW_PRIV_TYPE_INT:
12839 			/* Fetch args */
12840 			count = 0;
12841 			do {
12842 				str = strsep(&ptr, delim);
12843 				if (NULL == str || count >= 1024)
12844 					break;
12845 				sscanf(str, "%i", &temp);
12846 				((s32 *)buffer)[count++] = (s32)temp;
12847 			} while (1);
12848 			buffer_len = count * sizeof(s32);
12849 
12850 			/* Number of args to fetch */
12851 			wdata.data.length = count;
12852 			if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12853 				wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12854 
12855 			break;
12856 
12857 		case IW_PRIV_TYPE_CHAR:
12858 			if (len > 0) {
12859 				/* Size of the string to fetch */
12860 				wdata.data.length = len;
12861 				if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12862 					wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12863 
12864 				/* Fetch string */
12865 				_rtw_memcpy(buffer, ptr, wdata.data.length);
12866 			} else {
12867 				wdata.data.length = 1;
12868 				buffer[0] = '\0';
12869 			}
12870 			buffer_len = wdata.data.length;
12871 			break;
12872 
12873 		default:
12874 			RTW_INFO("%s: Not yet implemented...\n", __func__);
12875 			err = -1;
12876 			goto exit;
12877 		}
12878 
12879 		if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12880 		    (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
12881 			RTW_INFO("%s: The command %s needs exactly %d argument(s)...\n",
12882 				__func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
12883 			err = -EINVAL;
12884 			goto exit;
12885 		}
12886 	}   /* if args to set */
12887 	else
12888 		wdata.data.length = 0L;
12889 
12890 	/* Those two tests are important. They define how the driver
12891 	* will have to handle the data */
12892 	if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12893 	    ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
12894 		/* First case : all SET args fit within wrq */
12895 		if (offset)
12896 			wdata.mode = subcmd;
12897 		_rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
12898 	} else {
12899 		if ((priv_args[k].set_args == 0) &&
12900 		    (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12901 		    (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
12902 			/* Second case : no SET args, GET args fit within wrq */
12903 			if (offset)
12904 				wdata.mode = subcmd;
12905 		} else {
12906 			/* Third case : args won't fit in wrq, or variable number of args */
12907 			if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
12908 				err = -EFAULT;
12909 				goto exit;
12910 			}
12911 			wdata.data.flags = subcmd;
12912 		}
12913 	}
12914 
12915 	rtw_mfree(input, input_len);
12916 	input = NULL;
12917 
12918 	extra_size = 0;
12919 	if (IW_IS_SET(priv_args[k].cmd)) {
12920 		/* Size of set arguments */
12921 		extra_size = get_priv_size(priv_args[k].set_args);
12922 
12923 		/* Does it fits in iwr ? */
12924 		if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12925 		    ((extra_size + offset) <= IFNAMSIZ))
12926 			extra_size = 0;
12927 	} else {
12928 		/* Size of get arguments */
12929 		extra_size = get_priv_size(priv_args[k].get_args);
12930 
12931 		/* Does it fits in iwr ? */
12932 		if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12933 		    (extra_size <= IFNAMSIZ))
12934 			extra_size = 0;
12935 	}
12936 
12937 	if (extra_size == 0) {
12938 		extra = (u8 *)&wdata;
12939 		rtw_mfree(buffer, 4096);
12940 		buffer = NULL;
12941 	} else
12942 		extra = buffer;
12943 
12944 	handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
12945 	err = handler(dev, NULL, &wdata, extra);
12946 
12947 	/* If we have to get some data */
12948 	if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
12949 	    (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
12950 		int j;
12951 		int n = 0;	/* number of args */
12952 		u8 str[20] = {0};
12953 
12954 		/* Check where is the returned data */
12955 		if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12956 		    (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
12957 			n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
12958 		else
12959 			n = wdata.data.length;
12960 
12961 		output = rtw_zmalloc(4096);
12962 		if (NULL == output) {
12963 			err =  -ENOMEM;
12964 			goto exit;
12965 		}
12966 
12967 		switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
12968 		case IW_PRIV_TYPE_BYTE:
12969 			/* Display args */
12970 			for (j = 0; j < n; j++) {
12971 				sprintf(str, "%d  ", extra[j]);
12972 				len = strlen(str);
12973 				output_len = strlen(output);
12974 				if ((output_len + len + 1) > 4096) {
12975 					err = -E2BIG;
12976 					goto exit;
12977 				}
12978 				_rtw_memcpy(output + output_len, str, len);
12979 			}
12980 			break;
12981 
12982 		case IW_PRIV_TYPE_INT:
12983 			/* Display args */
12984 			for (j = 0; j < n; j++) {
12985 				sprintf(str, "%d  ", ((__s32 *)extra)[j]);
12986 				len = strlen(str);
12987 				output_len = strlen(output);
12988 				if ((output_len + len + 1) > 4096) {
12989 					err = -E2BIG;
12990 					goto exit;
12991 				}
12992 				_rtw_memcpy(output + output_len, str, len);
12993 			}
12994 			break;
12995 
12996 		case IW_PRIV_TYPE_CHAR:
12997 			/* Display args */
12998 			_rtw_memcpy(output, extra, n);
12999 			break;
13000 
13001 		default:
13002 			RTW_INFO("%s: Not yet implemented...\n", __func__);
13003 			err = -1;
13004 			goto exit;
13005 		}
13006 
13007 		output_len = strlen(output) + 1;
13008 		wrq_data->data.length = output_len;
13009 		if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
13010 			err = -EFAULT;
13011 			goto exit;
13012 		}
13013 	}   /* if args to set */
13014 	else
13015 		wrq_data->data.length = 0;
13016 
13017 exit:
13018 	if (input)
13019 		rtw_mfree(input, input_len);
13020 	if (buffer)
13021 		rtw_mfree(buffer, 4096);
13022 	if (output)
13023 		rtw_mfree(output, 4096);
13024 
13025 	return err;
13026 }
13027 
13028 #ifdef CONFIG_COMPAT
13029 static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)
13030 {
13031 	struct compat_iw_point iwp_compat;
13032 	union iwreq_data wrq_data;
13033 	int err = 0;
13034 	RTW_DBG("%s:...\n", __func__);
13035 	if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))
13036 		return -EFAULT;
13037 
13038 	wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);
13039 	wrq_data.data.length = iwp_compat.length;
13040 	wrq_data.data.flags = iwp_compat.flags;
13041 
13042 	err = _rtw_ioctl_wext_private(dev, &wrq_data);
13043 
13044 	iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);
13045 	iwp_compat.length = wrq_data.data.length;
13046 	iwp_compat.flags = wrq_data.data.flags;
13047 	if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))
13048 		return -EFAULT;
13049 
13050 	return err;
13051 }
13052 #endif /* CONFIG_COMPAT */
13053 
13054 static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)
13055 {
13056 	struct iw_point *iwp;
13057 	union iwreq_data wrq_data;
13058 	int err = 0;
13059 	iwp = &wrq_data.data;
13060 	RTW_DBG("%s:...\n", __func__);
13061 	if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))
13062 		return -EFAULT;
13063 
13064 	err = _rtw_ioctl_wext_private(dev, &wrq_data);
13065 
13066 	if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))
13067 		return -EFAULT;
13068 
13069 	return err;
13070 }
13071 
13072 static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq)
13073 {
13074 #ifdef CONFIG_COMPAT
13075 #if (KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE)
13076 	if (is_compat_task())
13077 #else
13078 	if (in_compat_syscall())
13079 #endif
13080 		return rtw_ioctl_compat_wext_private(dev, rq);
13081 	else
13082 #endif /* CONFIG_COMPAT */
13083 		return rtw_ioctl_standard_wext_private(dev, rq);
13084 }
13085 
13086 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
13087 {
13088 	struct iwreq *wrq = (struct iwreq *)rq;
13089 	int ret = 0;
13090 
13091 	switch (cmd) {
13092 #ifdef CONFIG_IOCTL_WEXT
13093 	case RTL_IOCTL_WPA_SUPPLICANT:
13094 		ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
13095 		break;
13096 #ifdef CONFIG_AP_MODE
13097 	case RTL_IOCTL_HOSTAPD:
13098 		ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
13099 		break;
13100 #ifdef CONFIG_WIRELESS_EXT
13101 	case SIOCSIWMODE:
13102 		ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
13103 		break;
13104 #endif
13105 #endif /* CONFIG_AP_MODE */
13106 #endif /* CONFIG_IOCTL_WEXT */
13107 	case SIOCDEVPRIVATE:
13108 		ret = rtw_ioctl_wext_private(dev, rq);
13109 		break;
13110 	case (SIOCDEVPRIVATE+1):
13111 		ret = rtw_android_priv_cmd(dev, rq, cmd);
13112 		break;
13113 	default:
13114 		ret = -EOPNOTSUPP;
13115 		break;
13116 	}
13117 
13118 	return ret;
13119 }
13120