1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _IOCTL_LINUX_C_
8 
9 #include <linux/etherdevice.h>
10 #include <drv_types.h>
11 #include <rtw_debug.h>
12 #include <rtw_mp.h>
13 #include <linux/jiffies.h>
14 #include <linux/kernel.h>
15 
16 #define RTL_IOCTL_WPA_SUPPLICANT	(SIOCIWFIRSTPRIV+30)
17 
18 #define SCAN_ITEM_SIZE 768
19 #define MAX_CUSTOM_LEN 64
20 #define RATE_COUNT 4
21 
22 /*  combo scan */
23 #define WEXT_CSCAN_AMOUNT 9
24 #define WEXT_CSCAN_BUF_LEN		360
25 #define WEXT_CSCAN_HEADER		"CSCAN S\x01\x00\x00S\x00"
26 #define WEXT_CSCAN_HEADER_SIZE		12
27 #define WEXT_CSCAN_SSID_SECTION		'S'
28 #define WEXT_CSCAN_CHANNEL_SECTION	'C'
29 #define WEXT_CSCAN_NPROBE_SECTION	'N'
30 #define WEXT_CSCAN_ACTV_DWELL_SECTION	'A'
31 #define WEXT_CSCAN_PASV_DWELL_SECTION	'P'
32 #define WEXT_CSCAN_HOME_DWELL_SECTION	'H'
33 #define WEXT_CSCAN_TYPE_SECTION		'T'
34 
35 
36 extern u8 key_2char2num(u8 hch, u8 lch);
37 
38 static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
39 	6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
40 
41 static const char * const iw_operation_mode[] = {
42 	"Auto", "Ad-Hoc", "Managed",  "Master", "Repeater", "Secondary", "Monitor"
43 };
44 
45 static int hex2num_i(char c)
46 {
47 	if (c >= '0' && c <= '9')
48 		return c - '0';
49 	if (c >= 'a' && c <= 'f')
50 		return c - 'a' + 10;
51 	if (c >= 'A' && c <= 'F')
52 		return c - 'A' + 10;
53 	return -1;
54 }
55 
56 /**
57  * hwaddr_aton - Convert ASCII string to MAC address
58  * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
59  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
60  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
61  */
62 static int hwaddr_aton_i(const char *txt, u8 *addr)
63 {
64 	int i;
65 
66 	for (i = 0; i < 6; i++) {
67 		int a, b;
68 
69 		a = hex2num_i(*txt++);
70 		if (a < 0)
71 			return -1;
72 		b = hex2num_i(*txt++);
73 		if (b < 0)
74 			return -1;
75 		*addr++ = (a << 4) | b;
76 		if (i < 5 && *txt++ != ':')
77 			return -1;
78 	}
79 
80 	return 0;
81 }
82 
83 void indicate_wx_scan_complete_event(struct adapter *padapter)
84 {
85 	union iwreq_data wrqu;
86 
87 	memset(&wrqu, 0, sizeof(union iwreq_data));
88 
89 	/* DBG_871X("+rtw_indicate_wx_scan_complete_event\n"); */
90 }
91 
92 
93 void rtw_indicate_wx_assoc_event(struct adapter *padapter)
94 {
95 	union iwreq_data wrqu;
96 	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
97 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
98 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
99 	struct wlan_bssid_ex		*pnetwork = (struct wlan_bssid_ex*)(&(pmlmeinfo->network));
100 
101 	memset(&wrqu, 0, sizeof(union iwreq_data));
102 
103 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
104 
105 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ==true)
106 		memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
107 	else
108 		memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
109 
110 	DBG_871X_LEVEL(_drv_always_, "assoc success\n");
111 }
112 
113 void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
114 {
115 	union iwreq_data wrqu;
116 
117 	memset(&wrqu, 0, sizeof(union iwreq_data));
118 
119 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
120 	eth_zero_addr(wrqu.ap_addr.sa_data);
121 }
122 
123 /*
124 uint	rtw_is_cckrates_included(u8 *rate)
125 {
126 		u32 i = 0;
127 
128 		while (rate[i]!= 0)
129 		{
130 			if  ((((rate[i]) & 0x7f) == 2)	|| (((rate[i]) & 0x7f) == 4) ||
131 			(((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22))
132 			return true;
133 			i++;
134 		}
135 
136 		return false;
137 }
138 
139 uint	rtw_is_cckratesonly_included(u8 *rate)
140 {
141 	u32 i = 0;
142 
143 	while (rate[i]!= 0)
144 	{
145 			if  ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
146 				(((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22))
147 			return false;
148 			i++;
149 	}
150 
151 	return true;
152 }
153 */
154 
155 static char *translate_scan(struct adapter *padapter,
156 				struct iw_request_info* info, struct wlan_network *pnetwork,
157 				char *start, char *stop)
158 {
159 	struct iw_event iwe;
160 	u16 cap;
161 	u32 ht_ielen = 0;
162 	char *custom = NULL;
163 	char *p;
164 	u16 max_rate = 0, rate, ht_cap =false, vht_cap = false;
165 	u32 i = 0;
166 	u8 bw_40MHz = 0, short_GI = 0;
167 	u16 mcs_rate = 0, vht_data_rate = 0;
168 	u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
169 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
170 	u8 ss, sq;
171 
172 	/*  AP MAC address  */
173 	iwe.cmd = SIOCGIWAP;
174 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
175 
176 	memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
177 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
178 
179 	/* Add the ESSID */
180 	iwe.cmd = SIOCGIWESSID;
181 	iwe.u.data.flags = 1;
182 	iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
183 	start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
184 
185 	/* parsing HT_CAP_IE */
186 	if (pnetwork->network.Reserved[0] == 2) { /*  Probe Request */
187 		p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength);
188 	} else {
189 		p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
190 	}
191 	if (p && ht_ielen>0) {
192 		struct rtw_ieee80211_ht_cap *pht_capie;
193 		ht_cap = true;
194 		pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
195 		memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
196 		bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
197 		short_GI = (le16_to_cpu(pht_capie->cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
198 	}
199 
200 	/* Add the protocol name */
201 	iwe.cmd = SIOCGIWNAME;
202 	if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == true) {
203 		if (ht_cap == true)
204 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
205 		else
206 		snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
207 	} else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == true) {
208 		if (ht_cap == true)
209 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
210 		else
211 			snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
212 	} else {
213 		if (pnetwork->network.Configuration.DSConfig > 14) {
214 			if (vht_cap == true)
215 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
216 			else if (ht_cap == true)
217 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
218 			else
219 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
220 		} else {
221 			if (ht_cap == true)
222 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
223 			else
224 				snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
225 		}
226 	}
227 
228 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
229 
230 	  /* Add mode */
231 	if (pnetwork->network.Reserved[0] == 2) { /*  Probe Request */
232 		cap = 0;
233 	} else {
234 		__le16 le_tmp;
235 
236 	        iwe.cmd = SIOCGIWMODE;
237 		memcpy((u8 *)&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
238 		cap = le16_to_cpu(le_tmp);
239 	}
240 
241 	if (cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)) {
242 		if (cap & WLAN_CAPABILITY_BSS)
243 			iwe.u.mode = IW_MODE_MASTER;
244 		else
245 			iwe.u.mode = IW_MODE_ADHOC;
246 
247 		start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
248 	}
249 
250 	if (pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
251 		pnetwork->network.Configuration.DSConfig = 1;
252 
253 	 /* Add frequency/channel */
254 	iwe.cmd = SIOCGIWFREQ;
255 	iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
256 	iwe.u.freq.e = 1;
257 	iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
258 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
259 
260 	/* Add encryption capability */
261 	iwe.cmd = SIOCGIWENCODE;
262 	if (cap & WLAN_CAPABILITY_PRIVACY)
263 		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
264 	else
265 		iwe.u.data.flags = IW_ENCODE_DISABLED;
266 	iwe.u.data.length = 0;
267 	start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
268 
269 	/*Add basic and extended rates */
270 	max_rate = 0;
271 	custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC);
272 	if (!custom)
273 		return start;
274 	p = custom;
275 	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
276 	while (pnetwork->network.SupportedRates[i]!= 0) {
277 		rate = pnetwork->network.SupportedRates[i]&0x7F;
278 		if (rate > max_rate)
279 			max_rate = rate;
280 		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
281 			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
282 		i++;
283 	}
284 
285 	if (vht_cap == true) {
286 		max_rate = vht_data_rate;
287 	} else if (ht_cap == true) {
288 		if (mcs_rate&0x8000) { /* MCS15 */
289 			max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
290 		} else if (mcs_rate&0x0080) { /* MCS7 */
291 			max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
292 		} else { /* default MCS7 */
293 			/* DBG_871X("wx_get_scan, mcs_rate_bitmap = 0x%x\n", mcs_rate); */
294 			max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
295 		}
296 
297 		max_rate = max_rate*2;/* Mbps/2; */
298 	}
299 
300 	iwe.cmd = SIOCGIWRATE;
301 	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
302 	iwe.u.bitrate.value = max_rate * 500000;
303 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
304 
305 	/* parsing WPA/WPA2 IE */
306 	if (pnetwork->network.Reserved[0] != 2) { /*  Probe Request */
307 		u8 *buf;
308 		u8 wpa_ie[255], rsn_ie[255];
309 		u16 wpa_len = 0, rsn_len = 0;
310 		u8 *p;
311 		sint out_len = 0;
312 		out_len =rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie,&rsn_len, wpa_ie,&wpa_len);
313 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid =%s\n", pnetwork->network.Ssid.Ssid));
314 		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len =%d rsn_len =%d\n", wpa_len, rsn_len));
315 
316 		buf = kzalloc(MAX_WPA_IE_LEN*2, GFP_KERNEL);
317 		if (!buf)
318 			return start;
319 		if (wpa_len > 0) {
320 			p =buf;
321 			p += sprintf(p, "wpa_ie =");
322 			for (i = 0; i < wpa_len; i++)
323 				p += sprintf(p, "%02x", wpa_ie[i]);
324 
325 			if (wpa_len > 100) {
326 				printk("-----------------Len %d----------------\n", wpa_len);
327 				for (i = 0; i < wpa_len; i++)
328 					printk("%02x ", wpa_ie[i]);
329 				printk("\n");
330 				printk("-----------------Len %d----------------\n", wpa_len);
331 			}
332 
333 			memset(&iwe, 0, sizeof(iwe));
334 			iwe.cmd = IWEVCUSTOM;
335 			iwe.u.data.length = strlen(buf);
336 			start = iwe_stream_add_point(info, start, stop, &iwe, buf);
337 
338 			memset(&iwe, 0, sizeof(iwe));
339 			iwe.cmd =IWEVGENIE;
340 			iwe.u.data.length = wpa_len;
341 			start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
342 		}
343 		if (rsn_len > 0) {
344 			p = buf;
345 			memset(buf, 0, MAX_WPA_IE_LEN*2);
346 			p += sprintf(p, "rsn_ie =");
347 			for (i = 0; i < rsn_len; i++)
348 				p += sprintf(p, "%02x", rsn_ie[i]);
349 			memset(&iwe, 0, sizeof(iwe));
350 			iwe.cmd = IWEVCUSTOM;
351 			iwe.u.data.length = strlen(buf);
352 			start = iwe_stream_add_point(info, start, stop, &iwe, buf);
353 
354 			memset(&iwe, 0, sizeof(iwe));
355 			iwe.cmd =IWEVGENIE;
356 			iwe.u.data.length = rsn_len;
357 			start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
358 		}
359 		kfree(buf);
360 	}
361 
362 	{ /* parsing WPS IE */
363 		uint cnt = 0, total_ielen;
364 		u8 *wpsie_ptr = NULL;
365 		uint wps_ielen = 0;
366 
367 		u8 *ie_ptr;
368 		total_ielen = pnetwork->network.IELength - ie_offset;
369 
370 		if (pnetwork->network.Reserved[0] == 2) { /*  Probe Request */
371 			ie_ptr = pnetwork->network.IEs;
372 			total_ielen = pnetwork->network.IELength;
373 		} else {    /*  Beacon or Probe Respones */
374 			ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
375 			total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
376 		}
377 
378 		while (cnt < total_ielen) {
379 			if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2)) {
380 				wpsie_ptr = &ie_ptr[cnt];
381 				iwe.cmd =IWEVGENIE;
382 				iwe.u.data.length = (u16)wps_ielen;
383 				start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
384 			}
385 			cnt+=ie_ptr[cnt+1]+2; /* goto next */
386 		}
387 	}
388 
389 	/* Add quality statistics */
390 	iwe.cmd = IWEVQUAL;
391 	iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
392 	#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
393 		| IW_QUAL_NOISE_UPDATED
394 	#else
395 		| IW_QUAL_NOISE_INVALID
396 	#endif
397 	#ifdef CONFIG_SIGNAL_DISPLAY_DBM
398 		| IW_QUAL_DBM
399 	#endif
400 	;
401 
402 	if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
403 		is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
404 		ss = padapter->recvpriv.signal_strength;
405 		sq = padapter->recvpriv.signal_qual;
406 	} else {
407 		ss = pnetwork->network.PhyInfo.SignalStrength;
408 		sq = pnetwork->network.PhyInfo.SignalQuality;
409 	}
410 
411 
412 	#ifdef CONFIG_SIGNAL_DISPLAY_DBM
413 	iwe.u.qual.level = (u8) translate_percentage_to_dbm(ss);/* dbm */
414 	#else
415 	#ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
416 	{
417 		/* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
418 
419 		struct hal_com_data *pHal = GET_HAL_DATA(padapter);
420 
421 		iwe.u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
422 	}
423 	#else
424 	iwe.u.qual.level = (u8)ss;/*  */
425 	#endif
426 	#endif
427 
428 	iwe.u.qual.qual = (u8)sq;   /*  signal quality */
429 
430 	#if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
431 	{
432 		s16 tmp_noise = 0;
433 		rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
434 		iwe.u.qual.noise = tmp_noise ;
435 	}
436 	#else
437 	iwe.u.qual.noise = 0; /*  noise level */
438 	#endif
439 
440 	/* DBG_871X("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); */
441 
442 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
443 
444 	{
445 		u8 *buf;
446 		u8 *p, *pos;
447 
448 		buf = kzalloc(MAX_WPA_IE_LEN, GFP_KERNEL);
449 		if (!buf)
450 			goto exit;
451 		p = buf;
452 		pos = pnetwork->network.Reserved;
453 		p += sprintf(p, "fm =%02X%02X", pos[1], pos[0]);
454 		memset(&iwe, 0, sizeof(iwe));
455 		iwe.cmd = IWEVCUSTOM;
456 		iwe.u.data.length = strlen(buf);
457 		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
458 		kfree(buf);
459 	}
460 exit:
461 	kfree(custom);
462 
463 	return start;
464 }
465 
466 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
467 {
468 	struct adapter *padapter = (struct adapter *) rtw_netdev_priv(dev);
469 	int ret = 0;
470 
471 	if ((value & WLAN_AUTH_SHARED_KEY) && (value & WLAN_AUTH_OPEN)) {
472 		DBG_871X("wpa_set_auth_algs, WLAN_AUTH_SHARED_KEY and WLAN_AUTH_OPEN [value:0x%x]\n", value);
473 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
474 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
475 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
476 	} else if (value & WLAN_AUTH_SHARED_KEY)	{
477 		DBG_871X("wpa_set_auth_algs, WLAN_AUTH_SHARED_KEY  [value:0x%x]\n", value);
478 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
479 
480 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
481 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
482 	} else if (value & WLAN_AUTH_OPEN) {
483 		DBG_871X("wpa_set_auth_algs, WLAN_AUTH_OPEN\n");
484 		/* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
485 		if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
486 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
487 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
488 		}
489 	} else if (value & WLAN_AUTH_LEAP) {
490 		DBG_871X("wpa_set_auth_algs, WLAN_AUTH_LEAP\n");
491 	} else {
492 		DBG_871X("wpa_set_auth_algs, error!\n");
493 		ret = -EINVAL;
494 	}
495 
496 	return ret;
497 
498 }
499 
500 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
501 {
502 	int ret = 0;
503 	u32 wep_key_idx, wep_key_len, wep_total_len;
504 	struct ndis_802_11_wep	 *pwep = NULL;
505 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
506 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
507 	struct security_priv *psecuritypriv = &padapter->securitypriv;
508 
509 	param->u.crypt.err = 0;
510 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
511 
512 	if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
513 		ret =  -EINVAL;
514 		goto exit;
515 	}
516 
517 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
518 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
519 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
520 		if (param->u.crypt.idx >= WEP_KEYS ||
521 		    param->u.crypt.idx >= BIP_MAX_KEYID) {
522 			ret = -EINVAL;
523 			goto exit;
524 		}
525 	} else {
526 		{
527 			ret = -EINVAL;
528 			goto exit;
529 		}
530 	}
531 
532 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
533 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
534 		DBG_871X("wpa_set_encryption, crypt.alg = WEP\n");
535 
536 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
537 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
538 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
539 
540 		wep_key_idx = param->u.crypt.idx;
541 		wep_key_len = param->u.crypt.key_len;
542 
543 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(1)wep_key_idx =%d\n", wep_key_idx));
544 		DBG_871X("(1)wep_key_idx =%d\n", wep_key_idx);
545 
546 		if (wep_key_idx > WEP_KEYS)
547 			return -EINVAL;
548 
549 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("(2)wep_key_idx =%d\n", wep_key_idx));
550 
551 		if (wep_key_len > 0) {
552 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
553 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
554 			pwep = rtw_malloc(wep_total_len);
555 			if (pwep == NULL) {
556 				RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, (" wpa_set_encryption: pwep allocate fail !!!\n"));
557 				goto exit;
558 			}
559 
560 			memset(pwep, 0, wep_total_len);
561 
562 			pwep->KeyLength = wep_key_len;
563 			pwep->Length = wep_total_len;
564 
565 			if (wep_key_len == 13) {
566 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
567 				padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
568 			}
569 		} else {
570 			ret = -EINVAL;
571 			goto exit;
572 		}
573 
574 		pwep->KeyIndex = wep_key_idx;
575 		pwep->KeyIndex |= 0x80000000;
576 
577 		memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
578 
579 		if (param->u.crypt.set_tx) {
580 			DBG_871X("wep, set_tx = 1\n");
581 
582 			if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
583 				ret = -EOPNOTSUPP ;
584 		} else {
585 			DBG_871X("wep, set_tx = 0\n");
586 
587 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
588 			/* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to fw/cam */
589 
590 			if (wep_key_idx >= WEP_KEYS) {
591 				ret = -EOPNOTSUPP ;
592 				goto exit;
593 			}
594 
595 			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
596 			psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
597 			rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true);
598 		}
599 
600 		goto exit;
601 	}
602 
603 	if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
604 		struct sta_info * psta,*pbcmc_sta;
605 		struct sta_priv * pstapriv = &padapter->stapriv;
606 
607 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
608 			psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
609 			if (psta == NULL) {
610 				/* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
611 			} else {
612 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
613 				if (strcmp(param->u.crypt.alg, "none") != 0)
614 					psta->ieee8021x_blocked = false;
615 
616 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
617 						(padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled)) {
618 					psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
619 				}
620 
621 				if (param->u.crypt.set_tx == 1) { /* pairwise key */
622 					memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
623 
624 					if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
625 						/* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
626 						memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
627 						memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
628 
629 						padapter->securitypriv.busetkipkey =false;
630 						/* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
631 					}
632 
633 					/* DEBUG_ERR((" param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
634 					DBG_871X(" ~~~~set sta key:unicastkey\n");
635 
636 					rtw_setstakey_cmd(padapter, psta, true, true);
637 				} else { /* group key */
638 					if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
639 						memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
640 						/* only TKIP group key need to install this */
641 						if (param->u.crypt.key_len > 16) {
642 							memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]), 8);
643 							memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]), 8);
644 						}
645 						padapter->securitypriv.binstallGrpkey = true;
646 						/* DEBUG_ERR((" param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
647 						DBG_871X(" ~~~~set sta key:groupkey\n");
648 
649 						padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
650 
651 						rtw_set_key(padapter,&padapter->securitypriv, param->u.crypt.idx, 1, true);
652 					} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
653 						/* printk("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
654 						/* save the IGTK key, length 16 bytes */
655 						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));
656 						/*printk("IGTK key below:\n");
657 						for (no = 0;no<16;no++)
658 							printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
659 						printk("\n");*/
660 						padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
661 						padapter->securitypriv.binstallBIPkey = true;
662 						DBG_871X(" ~~~~set sta key:IGKT\n");
663 					}
664 				}
665 			}
666 
667 			pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
668 			if (pbcmc_sta == NULL) {
669 				/* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
670 			} else {
671 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
672 				if (strcmp(param->u.crypt.alg, "none") != 0)
673 					pbcmc_sta->ieee8021x_blocked = false;
674 
675 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
676 						(padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled)) {
677 					pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
678 				}
679 			}
680 		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
681 			/* adhoc mode */
682 		}
683 	}
684 
685 exit:
686 
687 	kfree(pwep);
688 	return ret;
689 }
690 
691 static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
692 {
693 	u8 *buf = NULL, *pos = NULL;
694 	int group_cipher = 0, pairwise_cipher = 0;
695 	int ret = 0;
696 	u8 null_addr[]= {0, 0, 0, 0, 0, 0};
697 
698 	if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
699 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
700 		if (pie == NULL)
701 			return ret;
702 		else
703 			return -EINVAL;
704 	}
705 
706 	if (ielen) {
707 		buf = rtw_zmalloc(ielen);
708 		if (buf == NULL) {
709 			ret =  -ENOMEM;
710 			goto exit;
711 		}
712 
713 		memcpy(buf, pie , ielen);
714 
715 		/* dump */
716 		{
717 			int i;
718 			DBG_871X("\n wpa_ie(length:%d):\n", ielen);
719 			for (i = 0;i<ielen;i =i+8)
720 				DBG_871X("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]);
721 		}
722 
723 		pos = buf;
724 		if (ielen < RSN_HEADER_LEN) {
725 			RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
726 			ret  = -1;
727 			goto exit;
728 		}
729 
730 		if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
731 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
732 			padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPAPSK;
733 			memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
734 		}
735 
736 		if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
737 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
738 			padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPA2PSK;
739 			memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
740 		}
741 
742 		if (group_cipher == 0)
743 			group_cipher = WPA_CIPHER_NONE;
744 		if (pairwise_cipher == 0)
745 			pairwise_cipher = WPA_CIPHER_NONE;
746 
747 		switch (group_cipher) {
748 			case WPA_CIPHER_NONE:
749 				padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
750 				padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
751 				break;
752 			case WPA_CIPHER_WEP40:
753 				padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
754 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
755 				break;
756 			case WPA_CIPHER_TKIP:
757 				padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
758 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
759 				break;
760 			case WPA_CIPHER_CCMP:
761 				padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
762 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
763 				break;
764 			case WPA_CIPHER_WEP104:
765 				padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
766 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
767 				break;
768 		}
769 
770 		switch (pairwise_cipher) {
771 			case WPA_CIPHER_NONE:
772 				padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
773 				padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
774 				break;
775 			case WPA_CIPHER_WEP40:
776 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
777 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
778 				break;
779 			case WPA_CIPHER_TKIP:
780 				padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
781 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
782 				break;
783 			case WPA_CIPHER_CCMP:
784 				padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
785 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
786 				break;
787 			case WPA_CIPHER_WEP104:
788 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
789 				padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
790 				break;
791 		}
792 
793 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
794 		{/* set wps_ie */
795 			u16 cnt = 0;
796 			u8 eid, wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
797 
798 			while (cnt < ielen) {
799 				eid = buf[cnt];
800 
801 				if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt+2], wps_oui, 4))) {
802 					DBG_871X("SET WPS_IE\n");
803 
804 					padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
805 
806 					memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
807 
808 					set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
809 
810 					cnt += buf[cnt+1]+2;
811 
812 					break;
813 				} else {
814 					cnt += buf[cnt+1]+2; /* goto next */
815 				}
816 			}
817 		}
818 	}
819 
820 	/* TKIP and AES disallow multicast packets until installing group key */
821         if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
822                 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
823                 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
824                 /* WPS open need to enable multicast */
825                 /*  check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true) */
826                 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
827 
828 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
829 		 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
830 		  pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
831 
832 exit:
833 
834 	kfree(buf);
835 
836 	return ret;
837 }
838 
839 static int rtw_wx_get_name(struct net_device *dev,
840 			     struct iw_request_info *info,
841 			     union iwreq_data *wrqu, char *extra)
842 {
843 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
844 	u32 ht_ielen = 0;
845 	char *p;
846 	u8 ht_cap =false, vht_cap =false;
847 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
848 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
849 	NDIS_802_11_RATES_EX* prates = NULL;
850 
851 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("cmd_code =%x\n", info->cmd));
852 
853 	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
854 		/* parsing HT_CAP_IE */
855 		p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
856 		if (p && ht_ielen>0)
857 			ht_cap = true;
858 
859 		prates = &pcur_bss->SupportedRates;
860 
861 		if (rtw_is_cckratesonly_included((u8 *)prates) == true) {
862 			if (ht_cap == true)
863 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
864 			else
865 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
866 		} else if ((rtw_is_cckrates_included((u8 *)prates)) == true) {
867 			if (ht_cap == true)
868 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
869 			else
870 				snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
871 		} else {
872 			if (pcur_bss->Configuration.DSConfig > 14) {
873 				if (vht_cap == true)
874 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
875 				else if (ht_cap == true)
876 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
877 				else
878 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
879 			} else {
880 				if (ht_cap == true)
881 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
882 				else
883 					snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
884 			}
885 		}
886 	} else {
887 		/* prates = &padapter->registrypriv.dev_network.SupportedRates; */
888 		/* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */
889 		snprintf(wrqu->name, IFNAMSIZ, "unassociated");
890 	}
891 	return 0;
892 }
893 
894 static int rtw_wx_set_freq(struct net_device *dev,
895 			     struct iw_request_info *info,
896 			     union iwreq_data *wrqu, char *extra)
897 {
898 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
899 
900 	return 0;
901 }
902 
903 static int rtw_wx_get_freq(struct net_device *dev,
904 			     struct iw_request_info *info,
905 			     union iwreq_data *wrqu, char *extra)
906 {
907 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
908 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
909 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
910 
911 	if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
912 		/* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
913 		wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
914 		wrqu->freq.e = 1;
915 		wrqu->freq.i = pcur_bss->Configuration.DSConfig;
916 
917 	} else {
918 		wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
919 		wrqu->freq.e = 1;
920 		wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
921 	}
922 
923 	return 0;
924 }
925 
926 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
927 			     union iwreq_data *wrqu, char *b)
928 {
929 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
930 	enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
931 	int ret = 0;
932 
933 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
934 		ret = -EPERM;
935 		goto exit;
936 	}
937 
938 	if (padapter->hw_init_completed ==false) {
939 		ret = -EPERM;
940 		goto exit;
941 	}
942 
943 	switch (wrqu->mode) {
944 		case IW_MODE_AUTO:
945 			networkType = Ndis802_11AutoUnknown;
946 			DBG_871X("set_mode = IW_MODE_AUTO\n");
947 			break;
948 		case IW_MODE_ADHOC:
949 			networkType = Ndis802_11IBSS;
950 			DBG_871X("set_mode = IW_MODE_ADHOC\n");
951 			break;
952 		case IW_MODE_MASTER:
953 			networkType = Ndis802_11APMode;
954 			DBG_871X("set_mode = IW_MODE_MASTER\n");
955                         /* rtw_setopmode_cmd(padapter, networkType, true); */
956 			break;
957 		case IW_MODE_INFRA:
958 			networkType = Ndis802_11Infrastructure;
959 			DBG_871X("set_mode = IW_MODE_INFRA\n");
960 			break;
961 
962 		default :
963 			ret = -EINVAL;
964 			RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode]));
965 			goto exit;
966 	}
967 
968 /*
969 	if (Ndis802_11APMode == networkType)
970 	{
971 		rtw_setopmode_cmd(padapter, networkType, true);
972 	}
973 	else
974 	{
975 		rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown, true);
976 	}
977 */
978 
979 	if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==false) {
980 
981 		ret = -EPERM;
982 		goto exit;
983 
984 	}
985 
986 	rtw_setopmode_cmd(padapter, networkType, true);
987 
988 exit:
989 	return ret;
990 }
991 
992 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
993 			     union iwreq_data *wrqu, char *b)
994 {
995 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
996 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
997 
998 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
999 
1000 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
1001 		wrqu->mode = IW_MODE_INFRA;
1002 	} else if  ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
1003 		       (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
1004 		wrqu->mode = IW_MODE_ADHOC;
1005 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1006 		wrqu->mode = IW_MODE_MASTER;
1007 	} else {
1008 		wrqu->mode = IW_MODE_AUTO;
1009 	}
1010 	return 0;
1011 }
1012 
1013 
1014 static int rtw_wx_set_pmkid(struct net_device *dev,
1015 	                     struct iw_request_info *a,
1016 			     union iwreq_data *wrqu, char *extra)
1017 {
1018 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1019 	u8          j, blInserted = false;
1020 	int         intReturn = false;
1021 	struct security_priv *psecuritypriv = &padapter->securitypriv;
1022         struct iw_pmksa*  pPMK = (struct iw_pmksa*) extra;
1023         u8     strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
1024         u8     strIssueBssid[ ETH_ALEN ] = { 0x00 };
1025 
1026 	/*
1027         There are the BSSID information in the bssid.sa_data array.
1028         If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1029         If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver.
1030         If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver.
1031         */
1032 
1033 	memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1034         if (pPMK->cmd == IW_PMKSA_ADD) {
1035                 DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
1036                 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
1037                     return(intReturn);
1038                 else
1039                     intReturn = true;
1040 
1041 		blInserted = false;
1042 
1043 		/* overwrite PMKID */
1044 		for (j = 0 ; j<NUM_PMKID_CACHE; j++) {
1045 			if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
1046 				/*  BSSID is matched, the same AP => rewrite with new PMKID. */
1047                                 DBG_871X("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
1048 
1049 				memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1050                                 psecuritypriv->PMKIDList[ j ].bUsed = true;
1051 				psecuritypriv->PMKIDIndex = j+1;
1052 				blInserted = true;
1053 				break;
1054 			}
1055 	        }
1056 
1057 	        if (!blInserted) {
1058 		    /*  Find a new entry */
1059                     DBG_871X("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1060                             psecuritypriv->PMKIDIndex);
1061 
1062 	            memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1063 		    memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1064 
1065                     psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = true;
1066 		    psecuritypriv->PMKIDIndex++ ;
1067 		    if (psecuritypriv->PMKIDIndex == 16)
1068 		        psecuritypriv->PMKIDIndex = 0;
1069 		}
1070         } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
1071                 DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
1072                 intReturn = true;
1073 		for (j = 0 ; j<NUM_PMKID_CACHE; j++) {
1074 			if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
1075 				/*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
1076                                 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
1077                                 psecuritypriv->PMKIDList[ j ].bUsed = false;
1078 				break;
1079 			}
1080 	        }
1081         } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
1082             DBG_871X("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
1083             memset(&psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
1084             psecuritypriv->PMKIDIndex = 0;
1085             intReturn = true;
1086         }
1087 	return intReturn;
1088 }
1089 
1090 static int rtw_wx_get_sens(struct net_device *dev,
1091 			     struct iw_request_info *info,
1092 			     union iwreq_data *wrqu, char *extra)
1093 {
1094 	{
1095 		wrqu->sens.value = 0;
1096 		wrqu->sens.fixed = 0;	/* no auto select */
1097 		wrqu->sens.disabled = 1;
1098 	}
1099 	return 0;
1100 }
1101 
1102 static int rtw_wx_get_range(struct net_device *dev,
1103 				struct iw_request_info *info,
1104 				union iwreq_data *wrqu, char *extra)
1105 {
1106 	struct iw_range *range = (struct iw_range *)extra;
1107 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1108 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1109 
1110 	u16 val;
1111 	int i;
1112 
1113 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code =%x\n", info->cmd));
1114 
1115 	wrqu->data.length = sizeof(*range);
1116 	memset(range, 0, sizeof(*range));
1117 
1118 	/* Let's try to keep this struct in the same order as in
1119 	 * linux/include/wireless.h
1120 	 */
1121 
1122 	/* TODO: See what values we can set, and remove the ones we can't
1123 	 * set, or fill them with some default data.
1124 	 */
1125 
1126 	/* ~5 Mb/s real (802.11b) */
1127 	range->throughput = 5 * 1000 * 1000;
1128 
1129 	/* signal level threshold range */
1130 
1131 	/* percent values between 0 and 100. */
1132 	range->max_qual.qual = 100;
1133 	range->max_qual.level = 100;
1134 	range->max_qual.noise = 100;
1135 	range->max_qual.updated = 7; /* Updated all three */
1136 
1137 
1138 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1139 	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1140 	range->avg_qual.level = 256 - 78;
1141 	range->avg_qual.noise = 0;
1142 	range->avg_qual.updated = 7; /* Updated all three */
1143 
1144 	range->num_bitrates = RATE_COUNT;
1145 
1146 	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
1147 		range->bitrate[i] = rtw_rates[i];
1148 
1149 	range->min_frag = MIN_FRAG_THRESHOLD;
1150 	range->max_frag = MAX_FRAG_THRESHOLD;
1151 
1152 	range->pm_capa = 0;
1153 
1154 	range->we_version_compiled = WIRELESS_EXT;
1155 	range->we_version_source = 16;
1156 
1157 	for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
1158 
1159 		/*  Include only legal frequencies for some countries */
1160 		if (pmlmeext->channel_set[i].ChannelNum != 0) {
1161 			range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
1162 			range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
1163 			range->freq[val].e = 1;
1164 			val++;
1165 		}
1166 
1167 		if (val == IW_MAX_FREQUENCIES)
1168 			break;
1169 	}
1170 
1171 	range->num_channels = val;
1172 	range->num_frequency = val;
1173 
1174 /*  Commented by Albert 2009/10/13 */
1175 /*  The following code will proivde the security capability to network manager. */
1176 /*  If the driver doesn't provide this capability to network manager, */
1177 /*  the WPA/WPA2 routers can't be choosen in the network manager. */
1178 
1179 /*
1180 #define IW_SCAN_CAPA_NONE		0x00
1181 #define IW_SCAN_CAPA_ESSID		0x01
1182 #define IW_SCAN_CAPA_BSSID		0x02
1183 #define IW_SCAN_CAPA_CHANNEL	0x04
1184 #define IW_SCAN_CAPA_MODE		0x08
1185 #define IW_SCAN_CAPA_RATE		0x10
1186 #define IW_SCAN_CAPA_TYPE		0x20
1187 #define IW_SCAN_CAPA_TIME		0x40
1188 */
1189 
1190 	range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
1191 			  IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
1192 
1193 	range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
1194 					IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
1195 
1196 	return 0;
1197 }
1198 
1199 /* set bssid flow */
1200 /* s1. rtw_set_802_11_infrastructure_mode() */
1201 /* s2. rtw_set_802_11_authentication_mode() */
1202 /* s3. set_802_11_encryption_mode() */
1203 /* s4. rtw_set_802_11_bssid() */
1204 static int rtw_wx_set_wap(struct net_device *dev,
1205 			 struct iw_request_info *info,
1206 			 union iwreq_data *awrq,
1207 			 char *extra)
1208 {
1209 	uint ret = 0;
1210 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1211 	struct sockaddr *temp = (struct sockaddr *)awrq;
1212 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1213 	struct list_head	*phead;
1214 	u8 *dst_bssid, *src_bssid;
1215 	struct __queue	*queue	= &(pmlmepriv->scanned_queue);
1216 	struct	wlan_network	*pnetwork = NULL;
1217 	enum NDIS_802_11_AUTHENTICATION_MODE	authmode;
1218 
1219 	rtw_ps_deny(padapter, PS_DENY_JOIN);
1220 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1221 		ret = -1;
1222 		goto exit;
1223 	}
1224 
1225 	if (!padapter->bup) {
1226 		ret = -1;
1227 		goto exit;
1228 	}
1229 
1230 
1231 	if (temp->sa_family != ARPHRD_ETHER) {
1232 		ret = -EINVAL;
1233 		goto exit;
1234 	}
1235 
1236 	authmode = padapter->securitypriv.ndisauthtype;
1237 	spin_lock_bh(&queue->lock);
1238 	phead = get_list_head(queue);
1239 	pmlmepriv->pscanned = get_next(phead);
1240 
1241 	while (1) {
1242 		if (phead == pmlmepriv->pscanned)
1243 			break;
1244 
1245 		pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1246 
1247 		pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1248 
1249 		dst_bssid = pnetwork->network.MacAddress;
1250 
1251 		src_bssid = temp->sa_data;
1252 
1253 		if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
1254 			if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1255 				ret = -1;
1256 				spin_unlock_bh(&queue->lock);
1257 				goto exit;
1258 			}
1259 				break;
1260 		}
1261 
1262 	}
1263 	spin_unlock_bh(&queue->lock);
1264 
1265 	rtw_set_802_11_authentication_mode(padapter, authmode);
1266 	/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1267 	if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) {
1268 		ret = -1;
1269 		goto exit;
1270 	}
1271 
1272 exit:
1273 
1274 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1275 
1276 	return ret;
1277 }
1278 
1279 static int rtw_wx_get_wap(struct net_device *dev,
1280 			    struct iw_request_info *info,
1281 			    union iwreq_data *wrqu, char *extra)
1282 {
1283 
1284 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1285 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1286 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
1287 
1288 	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1289 
1290 	eth_zero_addr(wrqu->ap_addr.sa_data);
1291 
1292 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n"));
1293 
1294 	if  (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) ||
1295 			((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) ||
1296 			((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) {
1297 		memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1298 	} else {
1299 		eth_zero_addr(wrqu->ap_addr.sa_data);
1300 	}
1301 
1302 	return 0;
1303 }
1304 
1305 static int rtw_wx_set_mlme(struct net_device *dev,
1306 			     struct iw_request_info *info,
1307 			     union iwreq_data *wrqu, char *extra)
1308 {
1309 	int ret = 0;
1310 	u16 reason;
1311 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1312 	struct iw_mlme *mlme = (struct iw_mlme *) extra;
1313 
1314 
1315 	if (mlme == NULL)
1316 		return -1;
1317 
1318 	DBG_871X("%s\n", __func__);
1319 
1320 	reason = mlme->reason_code;
1321 
1322 	DBG_871X("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
1323 
1324 	switch (mlme->cmd) {
1325 	case IW_MLME_DEAUTH:
1326 		if (!rtw_set_802_11_disassociate(padapter))
1327 			ret = -1;
1328 		break;
1329 	case IW_MLME_DISASSOC:
1330 		if (!rtw_set_802_11_disassociate(padapter))
1331 			ret = -1;
1332 		break;
1333 	default:
1334 		return -EOPNOTSUPP;
1335 	}
1336 
1337 	return ret;
1338 }
1339 
1340 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1341 			     union iwreq_data *wrqu, char *extra)
1342 {
1343 	u8 _status = false;
1344 	int ret = 0;
1345 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1346 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1347 	struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1348 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
1349 
1350 	#ifdef DBG_IOCTL
1351 	DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
1352 	#endif
1353 
1354 	rtw_ps_deny(padapter, PS_DENY_SCAN);
1355 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1356 		ret = -1;
1357 		goto exit;
1358 	}
1359 
1360 	if (padapter->bDriverStopped) {
1361 		DBG_871X("bDriverStopped =%d\n", padapter->bDriverStopped);
1362 		ret = -1;
1363 		goto exit;
1364 	}
1365 
1366 	if (!padapter->bup) {
1367 		ret = -1;
1368 		goto exit;
1369 	}
1370 
1371 	if (padapter->hw_init_completed ==false) {
1372 		ret = -1;
1373 		goto exit;
1374 	}
1375 
1376 	/*  When Busy Traffic, driver do not site survey. So driver return success. */
1377 	/*  wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1378 	/*  modify by thomas 2011-02-22. */
1379 	if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
1380 		indicate_wx_scan_complete_event(padapter);
1381 		goto exit;
1382 	}
1383 
1384 	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) {
1385 		indicate_wx_scan_complete_event(padapter);
1386 		goto exit;
1387 	}
1388 
1389 	memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
1390 
1391 	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1392 		struct iw_scan_req *req = (struct iw_scan_req *)extra;
1393 
1394 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1395 			int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1396 
1397 			memcpy(ssid[0].Ssid, req->essid, len);
1398 			ssid[0].SsidLength = len;
1399 
1400 			DBG_871X("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len);
1401 
1402 			spin_lock_bh(&pmlmepriv->lock);
1403 
1404 			_status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1405 
1406 			spin_unlock_bh(&pmlmepriv->lock);
1407 
1408 		} else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
1409 			DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1410 		}
1411 
1412 	} else if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
1413 		&& !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1414 		int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
1415 		char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
1416 		char section;
1417 		char sec_len;
1418 		int ssid_index = 0;
1419 
1420 		/* DBG_871X("%s COMBO_SCAN header is recognized\n", __func__); */
1421 
1422 		while (len >= 1) {
1423 			section = *(pos++); len-= 1;
1424 
1425 			switch (section) {
1426 				case WEXT_CSCAN_SSID_SECTION:
1427 					/* DBG_871X("WEXT_CSCAN_SSID_SECTION\n"); */
1428 					if (len < 1) {
1429 						len = 0;
1430 						break;
1431 					}
1432 
1433 					sec_len = *(pos++); len-= 1;
1434 
1435 					if (sec_len>0 && sec_len<=len) {
1436 						ssid[ssid_index].SsidLength = sec_len;
1437 						memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1438 						/* DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __func__ */
1439 						/* 	, ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength); */
1440 						ssid_index++;
1441 					}
1442 
1443 					pos+=sec_len; len-=sec_len;
1444 					break;
1445 
1446 
1447 				case WEXT_CSCAN_CHANNEL_SECTION:
1448 					/* DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n"); */
1449 					pos+= 1; len-= 1;
1450 					break;
1451 				case WEXT_CSCAN_ACTV_DWELL_SECTION:
1452 					/* DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); */
1453 					pos+=2; len-=2;
1454 					break;
1455 				case WEXT_CSCAN_PASV_DWELL_SECTION:
1456 					/* DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n"); */
1457 					pos+=2; len-=2;
1458 					break;
1459 				case WEXT_CSCAN_HOME_DWELL_SECTION:
1460 					/* DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n"); */
1461 					pos+=2; len-=2;
1462 					break;
1463 				case WEXT_CSCAN_TYPE_SECTION:
1464 					/* DBG_871X("WEXT_CSCAN_TYPE_SECTION\n"); */
1465 					pos+= 1; len-= 1;
1466 					break;
1467 				default:
1468 					/* DBG_871X("Unknown CSCAN section %c\n", section); */
1469 					len = 0; /*  stop parsing */
1470 			}
1471 			/* DBG_871X("len:%d\n", len); */
1472 
1473 		}
1474 
1475 		/* jeff: it has still some scan paramater to parse, we only do this now... */
1476 		_status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1477 
1478 	} else {
1479 		_status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1480 	}
1481 
1482 	if (_status == false)
1483 		ret = -1;
1484 
1485 exit:
1486 
1487 	rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
1488 
1489 	#ifdef DBG_IOCTL
1490 	DBG_871X("DBG_IOCTL %s:%d return %d\n", __func__, __LINE__, ret);
1491 	#endif
1492 
1493 	return ret;
1494 }
1495 
1496 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1497 			     union iwreq_data *wrqu, char *extra)
1498 {
1499 	struct list_head					*plist, *phead;
1500 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1501 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1502 	struct __queue				*queue	= &(pmlmepriv->scanned_queue);
1503 	struct	wlan_network	*pnetwork = NULL;
1504 	char *ev = extra;
1505 	char *stop = ev + wrqu->data.length;
1506 	u32 ret = 0;
1507 	sint wait_status;
1508 
1509 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
1510 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
1511 
1512 	#ifdef DBG_IOCTL
1513 	DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
1514 	#endif
1515 
1516 	if (adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped) {
1517 		ret = -EINVAL;
1518 		goto exit;
1519 	}
1520 
1521 	wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1522 
1523 	if (check_fwstate(pmlmepriv, wait_status))
1524 		return -EAGAIN;
1525 
1526 	spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1527 
1528 	phead = get_list_head(queue);
1529 	plist = get_next(phead);
1530 
1531 	while (1) {
1532 		if (phead == plist)
1533 			break;
1534 
1535 		if ((stop - ev) < SCAN_ITEM_SIZE) {
1536 			ret = -E2BIG;
1537 			break;
1538 		}
1539 
1540 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1541 
1542 		/* report network only if the current channel set contains the channel to which this network belongs */
1543 		if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1544 			&& rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
1545 			&& true == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
1546 
1547 			ev =translate_scan(padapter, a, pnetwork, ev, stop);
1548 		}
1549 
1550 		plist = get_next(plist);
1551 
1552 	}
1553 
1554 	spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1555 
1556 	wrqu->data.length = ev-extra;
1557 	wrqu->data.flags = 0;
1558 
1559 exit:
1560 
1561 	#ifdef DBG_IOCTL
1562 	DBG_871X("DBG_IOCTL %s:%d return %d\n", __func__, __LINE__, ret);
1563 	#endif
1564 
1565 	return ret ;
1566 
1567 }
1568 
1569 /* set ssid flow */
1570 /* s1. rtw_set_802_11_infrastructure_mode() */
1571 /* s2. set_802_11_authenticaion_mode() */
1572 /* s3. set_802_11_encryption_mode() */
1573 /* s4. rtw_set_802_11_ssid() */
1574 static int rtw_wx_set_essid(struct net_device *dev,
1575 			      struct iw_request_info *a,
1576 			      union iwreq_data *wrqu, char *extra)
1577 {
1578 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1579 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1580 	struct __queue *queue = &pmlmepriv->scanned_queue;
1581 	struct list_head *phead;
1582 	struct wlan_network *pnetwork = NULL;
1583 	enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1584 	struct ndis_802_11_ssid ndis_ssid;
1585 	u8 *dst_ssid, *src_ssid;
1586 
1587 	uint ret = 0, len;
1588 
1589 	#ifdef DBG_IOCTL
1590 	DBG_871X("DBG_IOCTL %s:%d\n", __func__, __LINE__);
1591 	#endif
1592 
1593 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1594 		 ("+rtw_wx_set_essid: fw_state = 0x%08x\n", get_fwstate(pmlmepriv)));
1595 
1596 	rtw_ps_deny(padapter, PS_DENY_JOIN);
1597 	if (_FAIL == rtw_pwr_wakeup(padapter)) {
1598 		ret = -1;
1599 		goto exit;
1600 	}
1601 
1602 	if (!padapter->bup) {
1603 		ret = -1;
1604 		goto exit;
1605 	}
1606 
1607 	if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1608 		ret = -E2BIG;
1609 		goto exit;
1610 	}
1611 
1612 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1613 		ret = -1;
1614 		goto exit;
1615 	}
1616 
1617 	authmode = padapter->securitypriv.ndisauthtype;
1618 	DBG_871X("=>%s\n", __func__);
1619 	if (wrqu->essid.flags && wrqu->essid.length) {
1620 		len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
1621 
1622 		if (wrqu->essid.length != 33)
1623 			DBG_871X("ssid =%s, len =%d\n", extra, wrqu->essid.length);
1624 
1625 		memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1626 		ndis_ssid.SsidLength = len;
1627 		memcpy(ndis_ssid.Ssid, extra, len);
1628 		src_ssid = ndis_ssid.Ssid;
1629 
1630 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid =[%s]\n", src_ssid));
1631 		spin_lock_bh(&queue->lock);
1632 		phead = get_list_head(queue);
1633 		pmlmepriv->pscanned = get_next(phead);
1634 
1635 		while (1) {
1636 			if (phead == pmlmepriv->pscanned) {
1637 			        RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
1638 					 ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
1639 
1640 				break;
1641 			}
1642 
1643 			pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1644 
1645 			pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1646 
1647 			dst_ssid = pnetwork->network.Ssid.Ssid;
1648 
1649 			RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1650 				 ("rtw_wx_set_essid: dst_ssid =%s\n",
1651 				  pnetwork->network.Ssid.Ssid));
1652 
1653 			if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
1654 				(pnetwork->network.Ssid.SsidLength ==ndis_ssid.SsidLength)) {
1655 				RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1656 					 ("rtw_wx_set_essid: find match, set infra mode\n"));
1657 
1658 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
1659 					if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1660 						continue;
1661 				}
1662 
1663 				if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == false) {
1664 					ret = -1;
1665 					spin_unlock_bh(&queue->lock);
1666 					goto exit;
1667 				}
1668 
1669 				break;
1670 			}
1671 		}
1672 		spin_unlock_bh(&queue->lock);
1673 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1674 			 ("set ssid: set_802_11_auth. mode =%d\n", authmode));
1675 		rtw_set_802_11_authentication_mode(padapter, authmode);
1676 		/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1677 		if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) {
1678 			ret = -1;
1679 			goto exit;
1680 		}
1681 	}
1682 
1683 exit:
1684 
1685 	rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1686 
1687 	DBG_871X("<=%s, ret %d\n", __func__, ret);
1688 
1689 	#ifdef DBG_IOCTL
1690 	DBG_871X("DBG_IOCTL %s:%d return %d\n", __func__, __LINE__, ret);
1691 	#endif
1692 
1693 	return ret;
1694 }
1695 
1696 static int rtw_wx_get_essid(struct net_device *dev,
1697 			      struct iw_request_info *a,
1698 			      union iwreq_data *wrqu, char *extra)
1699 {
1700 	u32 len, ret = 0;
1701 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1702 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1703 	struct wlan_bssid_ex  *pcur_bss = &pmlmepriv->cur_network.network;
1704 
1705 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
1706 
1707 	if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
1708 	      (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
1709 		len = pcur_bss->Ssid.SsidLength;
1710 
1711 		wrqu->essid.length = len;
1712 
1713 		memcpy(extra, pcur_bss->Ssid.Ssid, len);
1714 
1715 		wrqu->essid.flags = 1;
1716 	} else {
1717 		ret = -1;
1718 		goto exit;
1719 	}
1720 
1721 exit:
1722 	return ret;
1723 }
1724 
1725 static int rtw_wx_set_rate(struct net_device *dev,
1726 			      struct iw_request_info *a,
1727 			      union iwreq_data *wrqu, char *extra)
1728 {
1729 	int	i, ret = 0;
1730 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1731 	u8 datarates[NumRates];
1732 	u32 target_rate = wrqu->bitrate.value;
1733 	u32 fixed = wrqu->bitrate.fixed;
1734 	u32 ratevalue = 0;
1735 	u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1736 
1737 	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n"));
1738 	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed));
1739 
1740 	if (target_rate == -1) {
1741 		ratevalue = 11;
1742 		goto set_rate;
1743 	}
1744 	target_rate = target_rate/100000;
1745 
1746 	switch (target_rate) {
1747 		case 10:
1748 			ratevalue = 0;
1749 			break;
1750 		case 20:
1751 			ratevalue = 1;
1752 			break;
1753 		case 55:
1754 			ratevalue = 2;
1755 			break;
1756 		case 60:
1757 			ratevalue = 3;
1758 			break;
1759 		case 90:
1760 			ratevalue = 4;
1761 			break;
1762 		case 110:
1763 			ratevalue = 5;
1764 			break;
1765 		case 120:
1766 			ratevalue = 6;
1767 			break;
1768 		case 180:
1769 			ratevalue = 7;
1770 			break;
1771 		case 240:
1772 			ratevalue = 8;
1773 			break;
1774 		case 360:
1775 			ratevalue = 9;
1776 			break;
1777 		case 480:
1778 			ratevalue = 10;
1779 			break;
1780 		case 540:
1781 			ratevalue = 11;
1782 			break;
1783 		default:
1784 			ratevalue = 11;
1785 			break;
1786 	}
1787 
1788 set_rate:
1789 
1790 	for (i = 0; i<NumRates; i++) {
1791 		if (ratevalue ==mpdatarate[i]) {
1792 			datarates[i] = mpdatarate[i];
1793 			if (fixed == 0)
1794 				break;
1795 		} else {
1796 			datarates[i] = 0xff;
1797 		}
1798 
1799 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx =%d\n", datarates[i]));
1800 	}
1801 
1802 	if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
1803 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("rtw_wx_set_rate Fail!!!\n"));
1804 		ret = -1;
1805 	}
1806 	return ret;
1807 }
1808 
1809 static int rtw_wx_get_rate(struct net_device *dev,
1810 			     struct iw_request_info *info,
1811 			     union iwreq_data *wrqu, char *extra)
1812 {
1813 	u16 max_rate = 0;
1814 
1815 	max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
1816 
1817 	if (max_rate == 0)
1818 		return -EPERM;
1819 
1820 	wrqu->bitrate.fixed = 0;	/* no auto select */
1821 	wrqu->bitrate.value = max_rate * 100000;
1822 
1823 	return 0;
1824 }
1825 
1826 static int rtw_wx_set_rts(struct net_device *dev,
1827 			     struct iw_request_info *info,
1828 			     union iwreq_data *wrqu, char *extra)
1829 {
1830 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1831 
1832 	if (wrqu->rts.disabled)
1833 		padapter->registrypriv.rts_thresh = 2347;
1834 	else {
1835 		if (wrqu->rts.value < 0 ||
1836 		    wrqu->rts.value > 2347)
1837 			return -EINVAL;
1838 
1839 		padapter->registrypriv.rts_thresh = wrqu->rts.value;
1840 	}
1841 
1842 	DBG_871X("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1843 
1844 	return 0;
1845 }
1846 
1847 static int rtw_wx_get_rts(struct net_device *dev,
1848 			     struct iw_request_info *info,
1849 			     union iwreq_data *wrqu, char *extra)
1850 {
1851 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1852 
1853 	DBG_871X("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1854 
1855 	wrqu->rts.value = padapter->registrypriv.rts_thresh;
1856 	wrqu->rts.fixed = 0;	/* no auto select */
1857 	/* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
1858 
1859 	return 0;
1860 }
1861 
1862 static int rtw_wx_set_frag(struct net_device *dev,
1863 			     struct iw_request_info *info,
1864 			     union iwreq_data *wrqu, char *extra)
1865 {
1866 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1867 
1868 	if (wrqu->frag.disabled)
1869 		padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1870 	else {
1871 		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1872 		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
1873 			return -EINVAL;
1874 
1875 		padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1876 	}
1877 
1878 	DBG_871X("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1879 
1880 	return 0;
1881 
1882 }
1883 
1884 static int rtw_wx_get_frag(struct net_device *dev,
1885 			     struct iw_request_info *info,
1886 			     union iwreq_data *wrqu, char *extra)
1887 {
1888 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1889 
1890 	DBG_871X("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1891 
1892 	wrqu->frag.value = padapter->xmitpriv.frag_len;
1893 	wrqu->frag.fixed = 0;	/* no auto select */
1894 	/* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */
1895 
1896 	return 0;
1897 }
1898 
1899 static int rtw_wx_get_retry(struct net_device *dev,
1900 			     struct iw_request_info *info,
1901 			     union iwreq_data *wrqu, char *extra)
1902 {
1903 	/* struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); */
1904 
1905 
1906 	wrqu->retry.value = 7;
1907 	wrqu->retry.fixed = 0;	/* no auto select */
1908 	wrqu->retry.disabled = 1;
1909 
1910 	return 0;
1911 
1912 }
1913 
1914 static int rtw_wx_set_enc(struct net_device *dev,
1915 			    struct iw_request_info *info,
1916 			    union iwreq_data *wrqu, char *keybuf)
1917 {
1918 	u32 key, ret = 0;
1919 	u32 keyindex_provided;
1920 	struct ndis_802_11_wep	 wep;
1921 	enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1922 
1923 	struct iw_point *erq = &(wrqu->encoding);
1924 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1925 	struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1926 	DBG_871X("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
1927 
1928 	memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1929 
1930 	key = erq->flags & IW_ENCODE_INDEX;
1931 
1932 	if (erq->flags & IW_ENCODE_DISABLED) {
1933 		DBG_871X("EncryptionDisabled\n");
1934 		padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1935 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1936 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1937 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
1938 		authmode = Ndis802_11AuthModeOpen;
1939 		padapter->securitypriv.ndisauthtype =authmode;
1940 
1941 		goto exit;
1942 	}
1943 
1944 	if (key) {
1945 		if (key > WEP_KEYS)
1946 			return -EINVAL;
1947 		key--;
1948 		keyindex_provided = 1;
1949 	} else {
1950 		keyindex_provided = 0;
1951 		key = padapter->securitypriv.dot11PrivacyKeyIndex;
1952 		DBG_871X("rtw_wx_set_enc, key =%d\n", key);
1953 	}
1954 
1955 	/* set authentication mode */
1956 	if (erq->flags & IW_ENCODE_OPEN) {
1957 		DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1958 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
1959 
1960 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1961 
1962 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1963 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1964 		authmode = Ndis802_11AuthModeOpen;
1965 		padapter->securitypriv.ndisauthtype =authmode;
1966 	} else if (erq->flags & IW_ENCODE_RESTRICTED) {
1967 		DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1968 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1969 
1970 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1971 
1972 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1973 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1974 		authmode = Ndis802_11AuthModeShared;
1975 		padapter->securitypriv.ndisauthtype =authmode;
1976 	} else {
1977 		DBG_871X("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
1978 
1979 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
1980 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
1981 		padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1982 		padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1983 		authmode = Ndis802_11AuthModeOpen;
1984 		padapter->securitypriv.ndisauthtype =authmode;
1985 	}
1986 
1987 	wep.KeyIndex = key;
1988 	if (erq->length > 0) {
1989 		wep.KeyLength = erq->length <= 5 ? 5 : 13;
1990 
1991 		wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
1992 	} else {
1993 		wep.KeyLength = 0 ;
1994 
1995 		if (keyindex_provided == 1) { /*  set key_id only, no given KeyMaterial(erq->length == 0). */
1996 			padapter->securitypriv.dot11PrivacyKeyIndex = key;
1997 
1998 			DBG_871X("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
1999 
2000 			switch (padapter->securitypriv.dot11DefKeylen[key]) {
2001 				case 5:
2002 					padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2003 					break;
2004 				case 13:
2005 					padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2006 					break;
2007 				default:
2008 					padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2009 					break;
2010 			}
2011 
2012 			goto exit;
2013 
2014 		}
2015 
2016 	}
2017 
2018 	wep.KeyIndex |= 0x80000000;
2019 
2020 	memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
2021 
2022 	if (rtw_set_802_11_add_wep(padapter, &wep) == false) {
2023 		if (rf_on == pwrpriv->rf_pwrstate)
2024 			ret = -EOPNOTSUPP;
2025 		goto exit;
2026 	}
2027 
2028 exit:
2029 	return ret;
2030 }
2031 
2032 static int rtw_wx_get_enc(struct net_device *dev,
2033 			    struct iw_request_info *info,
2034 			    union iwreq_data *wrqu, char *keybuf)
2035 {
2036 	uint key, ret = 0;
2037 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2038 	struct iw_point *erq = &(wrqu->encoding);
2039 	struct	mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2040 
2041 	if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
2042 		 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true) {
2043 			 erq->length = 0;
2044 			 erq->flags |= IW_ENCODE_DISABLED;
2045 			 return 0;
2046 		 }
2047 	}
2048 
2049 
2050 	key = erq->flags & IW_ENCODE_INDEX;
2051 
2052 	if (key) {
2053 		if (key > WEP_KEYS)
2054 			return -EINVAL;
2055 		key--;
2056 	} else {
2057 		key = padapter->securitypriv.dot11PrivacyKeyIndex;
2058 	}
2059 
2060 	erq->flags = key + 1;
2061 
2062 	/* if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */
2063 	/*  */
2064 	/*       erq->flags |= IW_ENCODE_OPEN; */
2065 	/*  */
2066 
2067 	switch (padapter->securitypriv.ndisencryptstatus) {
2068 	case Ndis802_11EncryptionNotSupported:
2069 	case Ndis802_11EncryptionDisabled:
2070 		erq->length = 0;
2071 		erq->flags |= IW_ENCODE_DISABLED;
2072 		break;
2073 	case Ndis802_11Encryption1Enabled:
2074 		erq->length = padapter->securitypriv.dot11DefKeylen[key];
2075 
2076 		if (erq->length) {
2077 			memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
2078 
2079 			erq->flags |= IW_ENCODE_ENABLED;
2080 
2081 			if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2082 				erq->flags |= IW_ENCODE_OPEN;
2083 			else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
2084 				erq->flags |= IW_ENCODE_RESTRICTED;
2085 		} else {
2086 			erq->length = 0;
2087 			erq->flags |= IW_ENCODE_DISABLED;
2088 		}
2089 		break;
2090 	case Ndis802_11Encryption2Enabled:
2091 	case Ndis802_11Encryption3Enabled:
2092 		erq->length = 16;
2093 		erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
2094 		break;
2095 	default:
2096 		erq->length = 0;
2097 		erq->flags |= IW_ENCODE_DISABLED;
2098 		break;
2099 	}
2100 	return ret;
2101 }
2102 
2103 static int rtw_wx_get_power(struct net_device *dev,
2104 			     struct iw_request_info *info,
2105 			     union iwreq_data *wrqu, char *extra)
2106 {
2107 	/* struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); */
2108 
2109 	wrqu->power.value = 0;
2110 	wrqu->power.fixed = 0;	/* no auto select */
2111 	wrqu->power.disabled = 1;
2112 
2113 	return 0;
2114 }
2115 
2116 static int rtw_wx_set_gen_ie(struct net_device *dev,
2117 			     struct iw_request_info *info,
2118 			     union iwreq_data *wrqu, char *extra)
2119 {
2120 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2121 
2122 	return rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
2123 }
2124 
2125 static int rtw_wx_set_auth(struct net_device *dev,
2126 			   struct iw_request_info *info,
2127 			   union iwreq_data *wrqu, char *extra)
2128 {
2129 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2130 	struct iw_param *param = (struct iw_param*)&(wrqu->param);
2131 	int ret = 0;
2132 
2133 	switch (param->flags & IW_AUTH_INDEX) {
2134 	case IW_AUTH_WPA_VERSION:
2135 		break;
2136 	case IW_AUTH_CIPHER_PAIRWISE:
2137 		break;
2138 	case IW_AUTH_CIPHER_GROUP:
2139 		break;
2140 	case IW_AUTH_KEY_MGMT:
2141 		/*
2142 		 *  ??? does not use these parameters
2143 		 */
2144 		break;
2145 	case IW_AUTH_TKIP_COUNTERMEASURES:
2146 		/* wpa_supplicant is setting the tkip countermeasure. */
2147 		if (param->value) /* enabling */
2148 			padapter->securitypriv.btkip_countermeasure = true;
2149 		else /* disabling */
2150 			padapter->securitypriv.btkip_countermeasure = false;
2151 		break;
2152 	case IW_AUTH_DROP_UNENCRYPTED:
2153 		/* HACK:
2154 		 *
2155 		 * wpa_supplicant calls set_wpa_enabled when the driver
2156 		 * is loaded and unloaded, regardless of if WPA is being
2157 		 * used.  No other calls are made which can be used to
2158 		 * determine if encryption will be used or not prior to
2159 		 * association being expected.  If encryption is not being
2160 		 * used, drop_unencrypted is set to false, else true -- we
2161 		 * can use this to determine if the CAP_PRIVACY_ON bit should
2162 		 * be set.
2163 		 */
2164 
2165 		/*
2166 		 * This means init value, or using wep, ndisencryptstatus =
2167 		 * Ndis802_11Encryption1Enabled, then it needn't reset it;
2168 		 */
2169 		if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
2170 			break;
2171 
2172 		if (param->value) {
2173 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2174 			padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2175 			padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2176 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2177 			padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeOpen;
2178 		}
2179 
2180 		break;
2181 	case IW_AUTH_80211_AUTH_ALG:
2182 		/*
2183 		 *  It's the starting point of a link layer connection using wpa_supplicant
2184 		 */
2185 		if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2186 			LeaveAllPowerSaveMode(padapter);
2187 			rtw_disassoc_cmd(padapter, 500, false);
2188 			DBG_871X("%s...call rtw_indicate_disconnect\n ", __func__);
2189 			rtw_indicate_disconnect(padapter);
2190 			rtw_free_assoc_resources(padapter, 1);
2191 		}
2192 
2193 		ret = wpa_set_auth_algs(dev, (u32)param->value);
2194 		break;
2195 	case IW_AUTH_WPA_ENABLED:
2196 		break;
2197 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2198 		break;
2199 	case IW_AUTH_PRIVACY_INVOKED:
2200 		break;
2201 	default:
2202 		return -EOPNOTSUPP;
2203 	}
2204 
2205 	return ret;
2206 }
2207 
2208 static int rtw_wx_set_enc_ext(struct net_device *dev,
2209 			     struct iw_request_info *info,
2210 			     union iwreq_data *wrqu, char *extra)
2211 {
2212 	char *alg_name;
2213 	u32 param_len;
2214 	struct ieee_param *param = NULL;
2215 	struct iw_point *pencoding = &wrqu->encoding;
2216 	struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
2217 	int ret = 0;
2218 
2219 	param_len = sizeof(struct ieee_param) + pext->key_len;
2220 	param = rtw_malloc(param_len);
2221 	if (param == NULL)
2222 		return -1;
2223 
2224 	memset(param, 0, param_len);
2225 
2226 	param->cmd = IEEE_CMD_SET_ENCRYPTION;
2227 	memset(param->sta_addr, 0xff, ETH_ALEN);
2228 
2229 
2230 	switch (pext->alg) {
2231 	case IW_ENCODE_ALG_NONE:
2232 		/* todo: remove key */
2233 		/* remove = 1; */
2234 		alg_name = "none";
2235 		break;
2236 	case IW_ENCODE_ALG_WEP:
2237 		alg_name = "WEP";
2238 		break;
2239 	case IW_ENCODE_ALG_TKIP:
2240 		alg_name = "TKIP";
2241 		break;
2242 	case IW_ENCODE_ALG_CCMP:
2243 		alg_name = "CCMP";
2244 		break;
2245 	case IW_ENCODE_ALG_AES_CMAC:
2246 		alg_name = "BIP";
2247 		break;
2248 	default:
2249 		ret = -1;
2250 		goto exit;
2251 	}
2252 
2253 	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
2254 
2255 	if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2256 		param->u.crypt.set_tx = 1;
2257 
2258 	/* cliW: WEP does not have group key
2259 	 * just not checking GROUP key setting
2260 	 */
2261 	if ((pext->alg != IW_ENCODE_ALG_WEP) &&
2262 		((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2263 		|| (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)))	{
2264 		param->u.crypt.set_tx = 0;
2265 	}
2266 
2267 	param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
2268 
2269 	if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
2270 		memcpy(param->u.crypt.seq, pext->rx_seq, 8);
2271 
2272 	if (pext->key_len) {
2273 		param->u.crypt.key_len = pext->key_len;
2274 		/* memcpy(param + 1, pext + 1, pext->key_len); */
2275 		memcpy(param->u.crypt.key, pext + 1, pext->key_len);
2276 	}
2277 
2278 	if (pencoding->flags & IW_ENCODE_DISABLED) {
2279 		/* todo: remove key */
2280 		/* remove = 1; */
2281 	}
2282 
2283 	ret =  wpa_set_encryption(dev, param, param_len);
2284 
2285 exit:
2286 	kfree(param);
2287 
2288 	return ret;
2289 }
2290 
2291 
2292 static int rtw_wx_get_nick(struct net_device *dev,
2293 			     struct iw_request_info *info,
2294 			     union iwreq_data *wrqu, char *extra)
2295 {
2296 	/* struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); */
2297 	 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
2298 	 /* struct security_priv *psecuritypriv = &padapter->securitypriv; */
2299 
2300 	if (extra) {
2301 		wrqu->data.length = 14;
2302 		wrqu->data.flags = 1;
2303 		memcpy(extra, "<WIFI@REALTEK>", 14);
2304 	}
2305 	return 0;
2306 }
2307 
2308 static int rtw_wx_read32(struct net_device *dev,
2309                             struct iw_request_info *info,
2310                             union iwreq_data *wrqu, char *extra)
2311 {
2312 	struct adapter *padapter;
2313 	struct iw_point *p;
2314 	u16 len;
2315 	u32 addr;
2316 	u32 data32;
2317 	u32 bytes;
2318 	u8 *ptmp;
2319 	int ret;
2320 
2321 
2322 	ret = 0;
2323 	padapter = (struct adapter *)rtw_netdev_priv(dev);
2324 	p = &wrqu->data;
2325 	len = p->length;
2326 	if (0 == len)
2327 		return -EINVAL;
2328 
2329 	ptmp = rtw_malloc(len);
2330 	if (NULL == ptmp)
2331 		return -ENOMEM;
2332 
2333 	if (copy_from_user(ptmp, p->pointer, len)) {
2334 		ret = -EFAULT;
2335 		goto exit;
2336 	}
2337 
2338 	bytes = 0;
2339 	addr = 0;
2340 	sscanf(ptmp, "%d,%x", &bytes, &addr);
2341 
2342 	switch (bytes) {
2343 		case 1:
2344 			data32 = rtw_read8(padapter, addr);
2345 			sprintf(extra, "0x%02X", data32);
2346 			break;
2347 		case 2:
2348 			data32 = rtw_read16(padapter, addr);
2349 			sprintf(extra, "0x%04X", data32);
2350 			break;
2351 		case 4:
2352 			data32 = rtw_read32(padapter, addr);
2353 			sprintf(extra, "0x%08X", data32);
2354 			break;
2355 		default:
2356 			DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
2357 			ret = -EINVAL;
2358 			goto exit;
2359 	}
2360 	DBG_871X(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
2361 
2362 exit:
2363 	kfree(ptmp);
2364 
2365 	return 0;
2366 }
2367 
2368 static int rtw_wx_write32(struct net_device *dev,
2369                             struct iw_request_info *info,
2370                             union iwreq_data *wrqu, char *extra)
2371 {
2372 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2373 
2374 	u32 addr;
2375 	u32 data32;
2376 	u32 bytes;
2377 
2378 
2379 	bytes = 0;
2380 	addr = 0;
2381 	data32 = 0;
2382 	sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
2383 
2384 	switch (bytes) {
2385 		case 1:
2386 			rtw_write8(padapter, addr, (u8)data32);
2387 			DBG_871X(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32);
2388 			break;
2389 		case 2:
2390 			rtw_write16(padapter, addr, (u16)data32);
2391 			DBG_871X(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32);
2392 			break;
2393 		case 4:
2394 			rtw_write32(padapter, addr, data32);
2395 			DBG_871X(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32);
2396 			break;
2397 		default:
2398 			DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
2399 			return -EINVAL;
2400 	}
2401 
2402 	return 0;
2403 }
2404 
2405 static int rtw_wx_read_rf(struct net_device *dev,
2406                             struct iw_request_info *info,
2407                             union iwreq_data *wrqu, char *extra)
2408 {
2409 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2410 	u32 path, addr, data32;
2411 
2412 
2413 	path = *(u32*)extra;
2414 	addr = *((u32*)extra + 1);
2415 	data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
2416 	/*
2417 	 * IMPORTANT!!
2418 	 * Only when wireless private ioctl is at odd order,
2419 	 * "extra" would be copied to user space.
2420 	 */
2421 	sprintf(extra, "0x%05x", data32);
2422 
2423 	return 0;
2424 }
2425 
2426 static int rtw_wx_write_rf(struct net_device *dev,
2427                             struct iw_request_info *info,
2428                             union iwreq_data *wrqu, char *extra)
2429 {
2430 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2431 	u32 path, addr, data32;
2432 
2433 
2434 	path = *(u32*)extra;
2435 	addr = *((u32*)extra + 1);
2436 	data32 = *((u32*)extra + 2);
2437 /* 	DBG_871X("%s: path =%d addr = 0x%02x data = 0x%05x\n", __func__, path, addr, data32); */
2438 	rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
2439 
2440 	return 0;
2441 }
2442 
2443 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
2444 		 union iwreq_data *wrqu, char *b)
2445 {
2446 	return -1;
2447 }
2448 
2449 static int dummy(struct net_device *dev, struct iw_request_info *a,
2450 		 union iwreq_data *wrqu, char *b)
2451 {
2452 	/* struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); */
2453 	/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
2454 
2455 	/* DBG_871X("cmd_code =%x, fwstate = 0x%x\n", a->cmd, get_fwstate(pmlmepriv)); */
2456 
2457 	return -1;
2458 
2459 }
2460 
2461 static int rtw_wx_set_channel_plan(struct net_device *dev,
2462                                struct iw_request_info *info,
2463                                union iwreq_data *wrqu, char *extra)
2464 {
2465 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2466 	u8 channel_plan_req = (u8) (*((int *)wrqu));
2467 
2468 	if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1))
2469 		DBG_871X("%s set channel_plan = 0x%02X\n", __func__, channel_plan_req);
2470 	 else
2471 		return -EPERM;
2472 
2473 	return 0;
2474 }
2475 
2476 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
2477 		struct iw_request_info *a,
2478 		union iwreq_data *wrqu, char *b)
2479 {
2480 	return 0;
2481 }
2482 
2483 static int rtw_wx_get_sensitivity(struct net_device *dev,
2484 				struct iw_request_info *info,
2485 				union iwreq_data *wrqu, char *buf)
2486 {
2487 	return 0;
2488 }
2489 
2490 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
2491 				struct iw_request_info *info,
2492 				union iwreq_data *wrqu, char *extra)
2493 {
2494 	return 0;
2495 }
2496 
2497 /*
2498 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
2499 			  union iwreq_data *wrqu, char *extra);
2500 */
2501 /*
2502  *For all data larger than 16 octets, we need to use a
2503  *pointer to memory allocated in user space.
2504  */
2505 static  int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
2506 						union iwreq_data *wrqu, char *extra)
2507 {
2508 	return 0;
2509 }
2510 
2511 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
2512 						union iwreq_data *wrqu, char *extra)
2513 {
2514 	int ret = 0;
2515 	return ret;
2516 }
2517 
2518 static int rtw_get_ap_info(struct net_device *dev,
2519                                struct iw_request_info *info,
2520                                union iwreq_data *wrqu, char *extra)
2521 {
2522 	int ret = 0;
2523 	u32 cnt = 0, wpa_ielen;
2524 	struct list_head	*plist, *phead;
2525 	unsigned char *pbuf;
2526 	u8 bssid[ETH_ALEN];
2527 	char data[32];
2528 	struct wlan_network *pnetwork = NULL;
2529 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2530 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2531 	struct __queue *queue = &(pmlmepriv->scanned_queue);
2532 	struct iw_point *pdata = &wrqu->data;
2533 
2534 	DBG_871X("+rtw_get_aplist_info\n");
2535 
2536 	if ((padapter->bDriverStopped) || (pdata == NULL)) {
2537 		ret = -EINVAL;
2538 		goto exit;
2539 	}
2540 
2541 	while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true) {
2542 		msleep(30);
2543 		cnt++;
2544 		if (cnt > 100)
2545 			break;
2546 	}
2547 
2548 
2549 	/* pdata->length = 0;? */
2550 	pdata->flags = 0;
2551 	if (pdata->length>=32) {
2552 		if (copy_from_user(data, pdata->pointer, 32)) {
2553 			ret = -EINVAL;
2554 			goto exit;
2555 		}
2556 	} else {
2557 		ret = -EINVAL;
2558 		goto exit;
2559 	}
2560 
2561 	spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2562 
2563 	phead = get_list_head(queue);
2564 	plist = get_next(phead);
2565 
2566 	while (1) {
2567 		if (phead == plist)
2568 			break;
2569 
2570 
2571 		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2572 
2573 		/* if (hwaddr_aton_i(pdata->pointer, bssid)) */
2574 		if (hwaddr_aton_i(data, bssid)) {
2575 			DBG_871X("Invalid BSSID '%s'.\n", (u8 *)data);
2576 			spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2577 			return -EINVAL;
2578 		}
2579 
2580 
2581 		if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) { /* BSSID match, then check if supporting wpa/wpa2 */
2582 			DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
2583 
2584 			pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
2585 			if (pbuf && (wpa_ielen>0)) {
2586 				pdata->flags = 1;
2587 				break;
2588 			}
2589 
2590 			pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
2591 			if (pbuf && (wpa_ielen>0)) {
2592 				pdata->flags = 2;
2593 				break;
2594 			}
2595 		}
2596 
2597 		plist = get_next(plist);
2598 
2599 	}
2600 
2601 	spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2602 
2603 	if (pdata->length>=34) {
2604 		if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1)) {
2605 			ret = -EINVAL;
2606 			goto exit;
2607 		}
2608 	}
2609 
2610 exit:
2611 
2612 	return ret;
2613 
2614 }
2615 
2616 static int rtw_set_pid(struct net_device *dev,
2617                                struct iw_request_info *info,
2618                                union iwreq_data *wrqu, char *extra)
2619 {
2620 
2621 	int ret = 0;
2622 	struct adapter *padapter = rtw_netdev_priv(dev);
2623 	int *pdata = (int *)wrqu;
2624 	int selector;
2625 
2626 	if ((padapter->bDriverStopped) || (pdata == NULL)) {
2627 		ret = -EINVAL;
2628 		goto exit;
2629 	}
2630 
2631 	selector = *pdata;
2632 	if (selector < 3 && selector >= 0) {
2633 		padapter->pid[selector] = *(pdata+1);
2634 		DBG_871X("%s set pid[%d]=%d\n", __func__, selector , padapter->pid[selector]);
2635 	}
2636 	else
2637 		DBG_871X("%s selector %d error\n", __func__, selector);
2638 
2639 exit:
2640 
2641 	return ret;
2642 
2643 }
2644 
2645 static int rtw_wps_start(struct net_device *dev,
2646                                struct iw_request_info *info,
2647                                union iwreq_data *wrqu, char *extra)
2648 {
2649 
2650 	int ret = 0;
2651 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2652 	struct iw_point *pdata = &wrqu->data;
2653 	u32   u32wps_start = 0;
2654         unsigned int uintRet = 0;
2655 
2656 	if ((true == padapter->bDriverStopped) ||(true ==padapter->bSurpriseRemoved) || (NULL == pdata)) {
2657 		ret = -EINVAL;
2658 		goto exit;
2659 	}
2660 
2661 	uintRet = copy_from_user((void*) &u32wps_start, pdata->pointer, 4);
2662 	if (u32wps_start == 0)
2663 		u32wps_start = *extra;
2664 
2665 	DBG_871X("[%s] wps_start = %d\n", __func__, u32wps_start);
2666 
2667 #ifdef CONFIG_INTEL_WIDI
2668 	process_intel_widi_wps_status(padapter, u32wps_start);
2669 #endif /* CONFIG_INTEL_WIDI */
2670 
2671 exit:
2672 
2673 	return ret;
2674 
2675 }
2676 
2677 static int rtw_p2p_set(struct net_device *dev,
2678                                struct iw_request_info *info,
2679                                union iwreq_data *wrqu, char *extra)
2680 {
2681 
2682 	int ret = 0;
2683 
2684 	return ret;
2685 
2686 }
2687 
2688 static int rtw_p2p_get(struct net_device *dev,
2689                                struct iw_request_info *info,
2690                                union iwreq_data *wrqu, char *extra)
2691 {
2692 
2693 	int ret = 0;
2694 
2695 	return ret;
2696 
2697 }
2698 
2699 static int rtw_p2p_get2(struct net_device *dev,
2700 						struct iw_request_info *info,
2701 						union iwreq_data *wrqu, char *extra)
2702 {
2703 
2704 	int ret = 0;
2705 
2706 	return ret;
2707 
2708 }
2709 
2710 static int rtw_rereg_nd_name(struct net_device *dev,
2711                                struct iw_request_info *info,
2712                                union iwreq_data *wrqu, char *extra)
2713 {
2714 	int ret = 0;
2715 	struct adapter *padapter = rtw_netdev_priv(dev);
2716 	struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
2717 	char new_ifname[IFNAMSIZ];
2718 
2719 	if (rereg_priv->old_ifname[0] == 0) {
2720 		char *reg_ifname;
2721 		reg_ifname = padapter->registrypriv.ifname;
2722 
2723 		strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
2724 		rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
2725 	}
2726 
2727 	/* DBG_871X("%s wrqu->data.length:%d\n", __func__, wrqu->data.length); */
2728 	if (wrqu->data.length > IFNAMSIZ)
2729 		return -EFAULT;
2730 
2731 	if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
2732 		return -EFAULT;
2733 
2734 	if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
2735 		return ret;
2736 
2737 	DBG_871X("%s new_ifname:%s\n", __func__, new_ifname);
2738 	if (0 != (ret = rtw_change_ifname(padapter, new_ifname)))
2739 		goto exit;
2740 
2741 	strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
2742 	rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
2743 
2744 	if (!memcmp(new_ifname, "disable%d", 9)) {
2745 
2746 		DBG_871X("%s disable\n", __func__);
2747 		/*  free network queue for Android's timming issue */
2748 		rtw_free_network_queue(padapter, true);
2749 
2750 		/*  the interface is being "disabled", we can do deeper IPS */
2751 		/* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */
2752 		/* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */
2753 	}
2754 exit:
2755 	return ret;
2756 
2757 }
2758 
2759 static int rtw_dbg_port(struct net_device *dev,
2760                                struct iw_request_info *info,
2761                                union iwreq_data *wrqu, char *extra)
2762 {
2763 	int ret = 0;
2764 	u8 major_cmd, minor_cmd;
2765 	u16 arg;
2766 	u32 extra_arg, *pdata, val32;
2767 	struct sta_info *psta;
2768 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2769 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2770 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2771 	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2772 	struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2773 	struct sta_priv *pstapriv = &padapter->stapriv;
2774 
2775 
2776 	pdata = (u32*)&wrqu->data;
2777 
2778 	val32 = *pdata;
2779 	arg = (u16)(val32&0x0000ffff);
2780 	major_cmd = (u8)(val32>>24);
2781 	minor_cmd = (u8)((val32>>16)&0x00ff);
2782 
2783 	extra_arg = *(pdata+1);
2784 
2785 	switch (major_cmd) {
2786 		case 0x70:/* read_reg */
2787 			switch (minor_cmd) {
2788 				case 1:
2789 					DBG_871X("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
2790 					break;
2791 				case 2:
2792 					DBG_871X("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
2793 					break;
2794 				case 4:
2795 					DBG_871X("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
2796 					break;
2797 			}
2798 			break;
2799 		case 0x71:/* write_reg */
2800 			switch (minor_cmd) {
2801 				case 1:
2802 					rtw_write8(padapter, arg, extra_arg);
2803 					DBG_871X("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
2804 					break;
2805 				case 2:
2806 					rtw_write16(padapter, arg, extra_arg);
2807 					DBG_871X("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
2808 					break;
2809 				case 4:
2810 					rtw_write32(padapter, arg, extra_arg);
2811 					DBG_871X("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
2812 					break;
2813 			}
2814 			break;
2815 		case 0x72:/* read_bb */
2816 			DBG_871X("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
2817 			break;
2818 		case 0x73:/* write_bb */
2819 			rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
2820 			DBG_871X("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
2821 			break;
2822 		case 0x74:/* read_rf */
2823 			DBG_871X("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));
2824 			break;
2825 		case 0x75:/* write_rf */
2826 			rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
2827 			DBG_871X("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));
2828 			break;
2829 
2830 		case 0x76:
2831 			switch (minor_cmd) {
2832 				case 0x00: /* normal mode, */
2833 					padapter->recvpriv.is_signal_dbg = 0;
2834 					break;
2835 				case 0x01: /* dbg mode */
2836 					padapter->recvpriv.is_signal_dbg = 1;
2837 					extra_arg = extra_arg>100?100:extra_arg;
2838 					padapter->recvpriv.signal_strength_dbg =extra_arg;
2839 					break;
2840 			}
2841 			break;
2842 		case 0x78: /* IOL test */
2843 			break;
2844 		case 0x79:
2845 			{
2846 				/*
2847 				* dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
2848 				* dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
2849 				*/
2850 				u8 value =  extra_arg & 0x0f;
2851 				u8 sign = minor_cmd;
2852 				u16 write_value = 0;
2853 
2854 				DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
2855 
2856 				if (sign)
2857 					value = value | 0x10;
2858 
2859 				write_value = value | (value << 5);
2860 				rtw_write16(padapter, 0x6d9, write_value);
2861 			}
2862 			break;
2863 		case 0x7a:
2864 			receive_disconnect(padapter, pmlmeinfo->network.MacAddress
2865 				, WLAN_REASON_EXPIRATION_CHK);
2866 			break;
2867 		case 0x7F:
2868 			switch (minor_cmd) {
2869 				case 0x0:
2870 					DBG_871X("fwstate = 0x%x\n", get_fwstate(pmlmepriv));
2871 					break;
2872 				case 0x01:
2873 					DBG_871X("minor_cmd 0x%x\n", minor_cmd);
2874 					break;
2875 				case 0x02:
2876 					DBG_871X("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state);
2877 					DBG_871X("DrvBcnEarly =%d\n", pmlmeext->DrvBcnEarly);
2878 					DBG_871X("DrvBcnTimeOut =%d\n", pmlmeext->DrvBcnTimeOut);
2879 					break;
2880 				case 0x03:
2881 					DBG_871X("qos_option =%d\n", pmlmepriv->qospriv.qos_option);
2882 					DBG_871X("ht_option =%d\n", pmlmepriv->htpriv.ht_option);
2883 					break;
2884 				case 0x04:
2885 					DBG_871X("cur_ch =%d\n", pmlmeext->cur_channel);
2886 					DBG_871X("cur_bw =%d\n", pmlmeext->cur_bwmode);
2887 					DBG_871X("cur_ch_off =%d\n", pmlmeext->cur_ch_offset);
2888 
2889 					DBG_871X("oper_ch =%d\n", rtw_get_oper_ch(padapter));
2890 					DBG_871X("oper_bw =%d\n", rtw_get_oper_bw(padapter));
2891 					DBG_871X("oper_ch_offet =%d\n", rtw_get_oper_choffset(padapter));
2892 
2893 					break;
2894 				case 0x05:
2895 					psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
2896 					if (psta) {
2897 						int i;
2898 						struct recv_reorder_ctrl *preorder_ctrl;
2899 
2900 						DBG_871X("SSID =%s\n", cur_network->network.Ssid.Ssid);
2901 						DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
2902 						DBG_871X("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
2903 						DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
2904 						DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
2905 						DBG_871X("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
2906 						DBG_871X("bwmode =%d, ch_offset =%d, sgi_20m =%d, sgi_40m =%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
2907 						DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
2908 						DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
2909 
2910 						for (i = 0;i<16;i++) {
2911 							preorder_ctrl = &psta->recvreorder_ctrl[i];
2912 							if (preorder_ctrl->enable)
2913 								DBG_871X("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq);
2914 						}
2915 
2916 					} else {
2917 						DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
2918 					}
2919 					break;
2920 				case 0x06:
2921 					{
2922 						u32 ODMFlag;
2923 						rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
2924 						DBG_871X("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg);
2925 						ODMFlag = (u32)(0x0f&arg);
2926 						DBG_871X("(A)DMFlag = 0x%x\n", ODMFlag);
2927 						rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
2928 					}
2929 					break;
2930 				case 0x07:
2931 					DBG_871X("bSurpriseRemoved =%d, bDriverStopped =%d\n",
2932 						padapter->bSurpriseRemoved, padapter->bDriverStopped);
2933 					break;
2934 				case 0x08:
2935 					{
2936 						DBG_871X("minor_cmd 0x%x\n", minor_cmd);
2937 					}
2938 					break;
2939 				case 0x09:
2940 					{
2941 						int i, j;
2942 						struct list_head	*plist, *phead;
2943 						struct recv_reorder_ctrl *preorder_ctrl;
2944 
2945 						DBG_871X("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
2946 
2947 						spin_lock_bh(&pstapriv->sta_hash_lock);
2948 
2949 						for (i = 0; i< NUM_STA; i++) {
2950 							phead = &(pstapriv->sta_hash[i]);
2951 							plist = get_next(phead);
2952 
2953 							while (phead != plist) {
2954 								psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
2955 
2956 								plist = get_next(plist);
2957 
2958 								if (extra_arg == psta->aid) {
2959 									DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
2960 									DBG_871X("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
2961 									DBG_871X("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
2962 									DBG_871X("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
2963 									DBG_871X("bwmode =%d, ch_offset =%d, sgi_20m =%d, sgi_40m =%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
2964 									DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
2965 									DBG_871X("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
2966 									DBG_871X("capability = 0x%x\n", psta->capability);
2967 									DBG_871X("flags = 0x%x\n", psta->flags);
2968 									DBG_871X("wpa_psk = 0x%x\n", psta->wpa_psk);
2969 									DBG_871X("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher);
2970 									DBG_871X("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher);
2971 									DBG_871X("qos_info = 0x%x\n", psta->qos_info);
2972 									DBG_871X("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy);
2973 
2974 
2975 
2976 									for (j = 0;j<16;j++) {
2977 										preorder_ctrl = &psta->recvreorder_ctrl[j];
2978 										if (preorder_ctrl->enable)
2979 											DBG_871X("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq);
2980 									}
2981 								}
2982 							}
2983 						}
2984 
2985 						spin_unlock_bh(&pstapriv->sta_hash_lock);
2986 
2987 					}
2988 					break;
2989 				case 0x0a:
2990 					{
2991 						int max_mac_id = 0;
2992 						max_mac_id = rtw_search_max_mac_id(padapter);
2993 						printk("%s ==> max_mac_id = %d\n", __func__, max_mac_id);
2994 					}
2995 					break;
2996 				case 0x0b: /* Enable = 1, Disable = 0 driver control vrtl_carrier_sense. */
2997 					if (arg == 0) {
2998 						DBG_871X("disable driver ctrl vcs\n");
2999 						padapter->driver_vcs_en = 0;
3000 					} else if (arg == 1) {
3001 						DBG_871X("enable driver ctrl vcs = %d\n", extra_arg);
3002 						padapter->driver_vcs_en = 1;
3003 
3004 						if (extra_arg>2)
3005 							padapter->driver_vcs_type = 1;
3006 						else
3007 							padapter->driver_vcs_type = extra_arg;
3008 					}
3009 					break;
3010 				case 0x0c:/* dump rx/tx packet */
3011 					{
3012 						if (arg == 0) {
3013 							DBG_871X("dump rx packet (%d)\n", extra_arg);
3014 							/* pHalData->bDumpRxPkt =extra_arg; */
3015 							rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
3016 						} else if (arg == 1) {
3017 							DBG_871X("dump tx packet (%d)\n", extra_arg);
3018 							rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
3019 						}
3020 					}
3021 					break;
3022 				case 0x0e:
3023 					{
3024 						if (arg == 0) {
3025 							DBG_871X("disable driver ctrl rx_ampdu_factor\n");
3026 							padapter->driver_rx_ampdu_factor = 0xFF;
3027 						} else if (arg == 1) {
3028 
3029 							DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
3030 
3031 							if ((extra_arg & 0x03) > 0x03)
3032 								padapter->driver_rx_ampdu_factor = 0xFF;
3033 							else
3034 								padapter->driver_rx_ampdu_factor = extra_arg;
3035 						}
3036 					}
3037 					break;
3038 
3039 				case 0x10:/*  driver version display */
3040 					dump_drv_version(RTW_DBGDUMP);
3041 					break;
3042 				case 0x11:/* dump linked status */
3043 					{
3044 						 linked_info_dump(padapter, extra_arg);
3045 					}
3046 					break;
3047 				case 0x12: /* set rx_stbc */
3048 				{
3049 					struct registry_priv *pregpriv = &padapter->registrypriv;
3050 					/*  0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
3051 					/* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
3052 					if (pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3)) {
3053 						pregpriv->rx_stbc = extra_arg;
3054 						DBG_871X("set rx_stbc =%d\n", pregpriv->rx_stbc);
3055 					} else
3056 						DBG_871X("get rx_stbc =%d\n", pregpriv->rx_stbc);
3057 
3058 				}
3059 				break;
3060 				case 0x13: /* set ampdu_enable */
3061 				{
3062 					struct registry_priv *pregpriv = &padapter->registrypriv;
3063 					/*  0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */
3064 					if (pregpriv && extra_arg < 3) {
3065 						pregpriv->ampdu_enable = extra_arg;
3066 						DBG_871X("set ampdu_enable =%d\n", pregpriv->ampdu_enable);
3067 					} else
3068 						DBG_871X("get ampdu_enable =%d\n", pregpriv->ampdu_enable);
3069 
3070 				}
3071 				break;
3072 				case 0x14:
3073 				{
3074 					DBG_871X("minor_cmd 0x%x\n", minor_cmd);
3075 				}
3076 				break;
3077 				case 0x16:
3078 				{
3079 					if (arg == 0xff) {
3080 						rtw_odm_dbg_comp_msg(RTW_DBGDUMP, padapter);
3081 					} else {
3082 						u64 dbg_comp = (u64)extra_arg;
3083 						rtw_odm_dbg_comp_set(padapter, dbg_comp);
3084 					}
3085 				}
3086 					break;
3087 #ifdef DBG_FIXED_CHAN
3088 				case 0x17:
3089 					{
3090 						struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3091 						printk("===>  Fixed channel to %d\n", extra_arg);
3092 						pmlmeext->fixed_chan = extra_arg;
3093 
3094 					}
3095 					break;
3096 #endif
3097 				case 0x18:
3098 					{
3099 						printk("===>  Switch USB Mode %d\n", extra_arg);
3100 						rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
3101 					}
3102 					break;
3103 				case 0x19:
3104 					{
3105 						struct registry_priv *pregistrypriv = &padapter->registrypriv;
3106 						/*  extra_arg : */
3107 						/*  BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */
3108 						/*  BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */
3109 						if (arg == 0) {
3110 							DBG_871X("driver disable LDPC\n");
3111 							pregistrypriv->ldpc_cap = 0x00;
3112 						} else if (arg == 1) {
3113 							DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg);
3114 							pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33);
3115 						}
3116 					}
3117                                         break;
3118 				case 0x1a:
3119 					{
3120 						struct registry_priv *pregistrypriv = &padapter->registrypriv;
3121 						/*  extra_arg : */
3122 						/*  BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */
3123 						/*  BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */
3124 						if (arg == 0) {
3125 							DBG_871X("driver disable STBC\n");
3126 							pregistrypriv->stbc_cap = 0x00;
3127 						} else if (arg == 1) {
3128 							DBG_871X("driver set STBC cap = 0x%x\n", extra_arg);
3129 							pregistrypriv->stbc_cap = (u8)(extra_arg&0x33);
3130 						}
3131 					}
3132                                         break;
3133 				case 0x1b:
3134 					{
3135 						struct registry_priv *pregistrypriv = &padapter->registrypriv;
3136 
3137 						if (arg == 0) {
3138 							DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
3139 							init_mlme_default_rate_set(padapter);
3140 							pregistrypriv->ht_enable = (u8)rtw_ht_enable;
3141 						} else if (arg == 1) {
3142 
3143 							int i;
3144 							u8 max_rx_rate;
3145 
3146 							DBG_871X("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
3147 
3148 							max_rx_rate = (u8)extra_arg;
3149 
3150 							if (max_rx_rate < 0xc) { /*  max_rx_rate < MSC0 -> B or G -> disable HT */
3151 								pregistrypriv->ht_enable = 0;
3152 								for (i = 0; i<NumRates; i++) {
3153 									if (pmlmeext->datarate[i] > max_rx_rate)
3154 										pmlmeext->datarate[i] = 0xff;
3155 								}
3156 
3157 							}
3158 							else if (max_rx_rate < 0x1c) { /*  mcs0~mcs15 */
3159 								u32 mcs_bitmap = 0x0;
3160 
3161 								for (i = 0; i<((max_rx_rate+1)-0xc); i++)
3162 									mcs_bitmap |= BIT(i);
3163 
3164 								set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
3165 							}
3166 						}
3167 					}
3168                                         break;
3169 				case 0x1c: /* enable/disable driver control AMPDU Density for peer sta's rx */
3170 					{
3171 						if (arg == 0) {
3172 							DBG_871X("disable driver ctrl ampdu density\n");
3173 							padapter->driver_ampdu_spacing = 0xFF;
3174 						} else if (arg == 1) {
3175 
3176 							DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg);
3177 
3178 							if ((extra_arg & 0x07) > 0x07)
3179 								padapter->driver_ampdu_spacing = 0xFF;
3180 							else
3181 								padapter->driver_ampdu_spacing = extra_arg;
3182 						}
3183 					}
3184 					break;
3185 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
3186 				case 0x1e:
3187 					{
3188 						struct hal_com_data	*pHalData = GET_HAL_DATA(padapter);
3189 						PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
3190 						u8 chan = rtw_get_oper_ch(padapter);
3191 						DBG_871X("===========================================\n");
3192 						ODM_InbandNoise_Monitor(pDM_Odm, true, 0x1e, 100);
3193 						DBG_871X("channel(%d), noise_a = %d, noise_b = %d , noise_all:%d\n",
3194 							chan, pDM_Odm->noise_level.noise[ODM_RF_PATH_A],
3195 							pDM_Odm->noise_level.noise[ODM_RF_PATH_B],
3196 							pDM_Odm->noise_level.noise_all);
3197 						DBG_871X("===========================================\n");
3198 
3199 					}
3200 					break;
3201 #endif
3202 				case 0x23:
3203 					{
3204 						DBG_871X("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1)?"on":"off");
3205 						padapter->bNotifyChannelChange = extra_arg;
3206 						break;
3207 					}
3208 				case 0x24:
3209 					{
3210 						break;
3211 					}
3212 #ifdef CONFIG_GPIO_API
3213 		            case 0x25: /* Get GPIO register */
3214 		                    {
3215 			                    /*
3216 			                    * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
3217 			                    */
3218 
3219 			                    int value;
3220 			                    DBG_871X("Read GPIO Value  extra_arg = %d\n", extra_arg);
3221 			                    value = rtw_get_gpio(dev, extra_arg);
3222 			                    DBG_871X("Read GPIO Value = %d\n", value);
3223 			                    break;
3224 		                    }
3225 		            case 0x26: /* Set GPIO direction */
3226 		                    {
3227 
3228 			                    /* dbg 0x7f26000x [y], Set gpio direction,
3229 			                    * x: gpio_num, 4~7  y: indicate direction, 0~1
3230 			                    */
3231 
3232 			                    int value;
3233 			                    DBG_871X("Set GPIO Direction! arg = %d , extra_arg =%d\n", arg , extra_arg);
3234 			                    value = rtw_config_gpio(dev, arg, extra_arg);
3235 			                    DBG_871X("Set GPIO Direction %s\n", (value ==-1)?"Fail!!!":"Success");
3236 			                    break;
3237 					}
3238 				case 0x27: /* Set GPIO output direction value */
3239 					{
3240 						/*
3241 						* dbg 0x7f27000x [y], Set gpio output direction value,
3242 						* x: gpio_num, 4~7  y: indicate direction, 0~1
3243 						*/
3244 
3245 						int value;
3246 						DBG_871X("Set GPIO Value! arg = %d , extra_arg =%d\n", arg , extra_arg);
3247 						value = rtw_set_gpio_output_value(dev, arg, extra_arg);
3248 						DBG_871X("Set GPIO Value %s\n", (value ==-1)?"Fail!!!":"Success");
3249 						break;
3250 					}
3251 #endif
3252 				case 0xaa:
3253 					{
3254 						if ((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF;
3255 						DBG_871X("chang data rate to :0x%02x\n", extra_arg);
3256 						padapter->fix_rate = extra_arg;
3257 					}
3258 					break;
3259 				case 0xdd:/* registers dump , 0 for mac reg, 1 for bb reg, 2 for rf reg */
3260 					{
3261 						if (extra_arg == 0)
3262 							mac_reg_dump(RTW_DBGDUMP, padapter);
3263 						else if (extra_arg == 1)
3264 							bb_reg_dump(RTW_DBGDUMP, padapter);
3265 						else if (extra_arg ==2)
3266 							rf_reg_dump(RTW_DBGDUMP, padapter);
3267 					}
3268 					break;
3269 
3270 				case 0xee:/* turn on/off dynamic funcs */
3271 					{
3272 						u32 odm_flag;
3273 
3274 						if (0xf ==extra_arg) {
3275 							rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
3276 							DBG_871X(" === DMFlag(0x%08x) ===\n", odm_flag);
3277 							DBG_871X("extra_arg = 0  - disable all dynamic func\n");
3278 							DBG_871X("extra_arg = 1  - disable DIG- BIT(0)\n");
3279 							DBG_871X("extra_arg = 2  - disable High power - BIT(1)\n");
3280 							DBG_871X("extra_arg = 3  - disable tx power tracking - BIT(2)\n");
3281 							DBG_871X("extra_arg = 4  - disable BT coexistence - BIT(3)\n");
3282 							DBG_871X("extra_arg = 5  - disable antenna diversity - BIT(4)\n");
3283 							DBG_871X("extra_arg = 6  - enable all dynamic func\n");
3284 						} else {
3285 							/*extra_arg = 0  - disable all dynamic func
3286 								extra_arg = 1  - disable DIG
3287 								extra_arg = 2  - disable tx power tracking
3288 								extra_arg = 3  - turn on all dynamic func
3289 							*/
3290 							rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
3291 							rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC,&odm_flag);
3292 							DBG_871X(" === DMFlag(0x%08x) ===\n", odm_flag);
3293 						}
3294 					}
3295 					break;
3296 
3297 				case 0xfd:
3298 					rtw_write8(padapter, 0xc50, arg);
3299 					DBG_871X("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
3300 					rtw_write8(padapter, 0xc58, arg);
3301 					DBG_871X("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
3302 					break;
3303 				case 0xfe:
3304 					DBG_871X("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
3305 					DBG_871X("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
3306 					break;
3307 				case 0xff:
3308 					{
3309 						DBG_871X("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
3310 						DBG_871X("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
3311 						DBG_871X("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
3312 						DBG_871X("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
3313 						DBG_871X("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
3314 
3315 						DBG_871X("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
3316 
3317 
3318 						DBG_871X("\n");
3319 
3320 						DBG_871X("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
3321 						DBG_871X("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
3322 
3323 						DBG_871X("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
3324 
3325 						DBG_871X("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
3326 
3327 						DBG_871X("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
3328 						DBG_871X("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
3329 
3330 						DBG_871X("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
3331 						DBG_871X("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
3332 						DBG_871X("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
3333 						DBG_871X("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
3334 					}
3335 					break;
3336 			}
3337 			break;
3338 		default:
3339 			DBG_871X("error dbg cmd!\n");
3340 			break;
3341 	}
3342 
3343 
3344 	return ret;
3345 
3346 }
3347 
3348 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
3349 {
3350 	uint ret = 0;
3351 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3352 
3353 	switch (name) {
3354 	case IEEE_PARAM_WPA_ENABLED:
3355 
3356 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
3357 
3358 		/* ret = ieee80211_wpa_enable(ieee, value); */
3359 
3360 		switch ((value)&0xff) {
3361 		case 1 : /* WPA */
3362 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
3363 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
3364 			break;
3365 		case 2: /* WPA2 */
3366 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
3367 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
3368 			break;
3369 		}
3370 
3371 		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("wpa_set_param:padapter->securitypriv.ndisauthtype =%d\n", padapter->securitypriv.ndisauthtype));
3372 
3373 		break;
3374 
3375 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
3376 		/* ieee->tkip_countermeasures =value; */
3377 		break;
3378 
3379 	case IEEE_PARAM_DROP_UNENCRYPTED:
3380 	{
3381 		/* HACK:
3382 		 *
3383 		 * wpa_supplicant calls set_wpa_enabled when the driver
3384 		 * is loaded and unloaded, regardless of if WPA is being
3385 		 * used.  No other calls are made which can be used to
3386 		 * determine if encryption will be used or not prior to
3387 		 * association being expected.  If encryption is not being
3388 		 * used, drop_unencrypted is set to false, else true -- we
3389 		 * can use this to determine if the CAP_PRIVACY_ON bit should
3390 		 * be set.
3391 		 */
3392 		break;
3393 
3394 	}
3395 	case IEEE_PARAM_PRIVACY_INVOKED:
3396 
3397 		/* ieee->privacy_invoked =value; */
3398 
3399 		break;
3400 
3401 	case IEEE_PARAM_AUTH_ALGS:
3402 
3403 		ret = wpa_set_auth_algs(dev, value);
3404 
3405 		break;
3406 
3407 	case IEEE_PARAM_IEEE_802_1X:
3408 
3409 		/* ieee->ieee802_1x =value; */
3410 
3411 		break;
3412 
3413 	case IEEE_PARAM_WPAX_SELECT:
3414 
3415 		/*  added for WPA2 mixed mode */
3416 		/* DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value); */
3417 		/*
3418 		spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
3419 		ieee->wpax_type_set = 1;
3420 		ieee->wpax_type_notify = value;
3421 		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
3422 		*/
3423 
3424 		break;
3425 
3426 	default:
3427 
3428 
3429 
3430 		ret = -EOPNOTSUPP;
3431 
3432 
3433 		break;
3434 
3435 	}
3436 
3437 	return ret;
3438 
3439 }
3440 
3441 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
3442 {
3443 	int ret = 0;
3444 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3445 
3446 	switch (command) {
3447 		case IEEE_MLME_STA_DEAUTH:
3448 
3449 			if (!rtw_set_802_11_disassociate(padapter))
3450 				ret = -1;
3451 
3452 			break;
3453 
3454 		case IEEE_MLME_STA_DISASSOC:
3455 
3456 			if (!rtw_set_802_11_disassociate(padapter))
3457 				ret = -1;
3458 
3459 			break;
3460 
3461 		default:
3462 			ret = -EOPNOTSUPP;
3463 			break;
3464 	}
3465 
3466 	return ret;
3467 
3468 }
3469 
3470 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
3471 {
3472 	struct ieee_param *param;
3473 	uint ret = 0;
3474 
3475 	/* down(&ieee->wx_sem); */
3476 
3477 	if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3478 		ret = -EINVAL;
3479 		goto out;
3480 	}
3481 
3482 	param = rtw_malloc(p->length);
3483 	if (param == NULL) {
3484 		ret = -ENOMEM;
3485 		goto out;
3486 	}
3487 
3488 	if (copy_from_user(param, p->pointer, p->length)) {
3489 		kfree(param);
3490 		ret = -EFAULT;
3491 		goto out;
3492 	}
3493 
3494 	switch (param->cmd) {
3495 
3496 	case IEEE_CMD_SET_WPA_PARAM:
3497 		ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
3498 		break;
3499 
3500 	case IEEE_CMD_SET_WPA_IE:
3501 		/* ret = wpa_set_wpa_ie(dev, param, p->length); */
3502 		ret =  rtw_set_wpa_ie((struct adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
3503 		break;
3504 
3505 	case IEEE_CMD_SET_ENCRYPTION:
3506 		ret = wpa_set_encryption(dev, param, p->length);
3507 		break;
3508 
3509 	case IEEE_CMD_MLME:
3510 		ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
3511 		break;
3512 
3513 	default:
3514 		DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd);
3515 		ret = -EOPNOTSUPP;
3516 		break;
3517 
3518 	}
3519 
3520 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3521 		ret = -EFAULT;
3522 
3523 	kfree(param);
3524 
3525 out:
3526 
3527 	/* up(&ieee->wx_sem); */
3528 
3529 	return ret;
3530 
3531 }
3532 
3533 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
3534 {
3535 	int ret = 0;
3536 	u32 wep_key_idx, wep_key_len, wep_total_len;
3537 	struct ndis_802_11_wep	 *pwep = NULL;
3538 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
3539 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3540 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3541 	struct security_priv* psecuritypriv =&(padapter->securitypriv);
3542 	struct sta_priv *pstapriv = &padapter->stapriv;
3543 
3544 	DBG_871X("%s\n", __func__);
3545 
3546 	param->u.crypt.err = 0;
3547 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3548 
3549 	/* sizeof(struct ieee_param) = 64 bytes; */
3550 	/* if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
3551 	if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
3552 		ret =  -EINVAL;
3553 		goto exit;
3554 	}
3555 
3556 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3557 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3558 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3559 		if (param->u.crypt.idx >= WEP_KEYS) {
3560 			ret = -EINVAL;
3561 			goto exit;
3562 		}
3563 	} else {
3564 		psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3565 		if (!psta) {
3566 			/* ret = -EINVAL; */
3567 			DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
3568 			goto exit;
3569 		}
3570 	}
3571 
3572 	if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
3573 		/* todo:clear default encryption keys */
3574 
3575 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3576 		psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
3577 		psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
3578 		psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3579 
3580 		DBG_871X("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
3581 
3582 		goto exit;
3583 	}
3584 
3585 
3586 	if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
3587 		DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
3588 
3589 		wep_key_idx = param->u.crypt.idx;
3590 		wep_key_len = param->u.crypt.key_len;
3591 
3592 		DBG_871X("r871x_set_encryption, wep_key_idx =%d, len =%d\n", wep_key_idx, wep_key_len);
3593 
3594 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0)) {
3595 			ret = -EINVAL;
3596 			goto exit;
3597 		}
3598 
3599 
3600 		if (wep_key_len > 0) {
3601 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
3602 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
3603 			pwep = rtw_malloc(wep_total_len);
3604 			if (pwep == NULL) {
3605 				DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n");
3606 				goto exit;
3607 			}
3608 
3609 			memset(pwep, 0, wep_total_len);
3610 
3611 			pwep->KeyLength = wep_key_len;
3612 			pwep->Length = wep_total_len;
3613 
3614 		}
3615 
3616 		pwep->KeyIndex = wep_key_idx;
3617 
3618 		memcpy(pwep->KeyMaterial,  param->u.crypt.key, pwep->KeyLength);
3619 
3620 		if (param->u.crypt.set_tx) {
3621 			DBG_871X("wep, set_tx = 1\n");
3622 
3623 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3624 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
3625 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
3626 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3627 
3628 			if (pwep->KeyLength == 13) {
3629 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
3630 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3631 			}
3632 
3633 
3634 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
3635 
3636 			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
3637 
3638 			psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
3639 
3640 			rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
3641 		} else {
3642 			DBG_871X("wep, set_tx = 0\n");
3643 
3644 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
3645 			/* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to cam */
3646 
3647 			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
3648 
3649 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
3650 
3651 			rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
3652 		}
3653 
3654 		goto exit;
3655 
3656 	}
3657 
3658 
3659 	if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /*  group key */
3660 		if (param->u.crypt.set_tx == 1) {
3661 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3662 				DBG_871X("%s, set group_key, WEP\n", __func__);
3663 
3664 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3665 
3666 				psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3667 				if (param->u.crypt.key_len == 13)
3668 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3669 
3670 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3671 				DBG_871X("%s, set group_key, TKIP\n", __func__);
3672 
3673 				psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
3674 
3675 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3676 
3677 				/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
3678 				/* set mic key */
3679 				memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
3680 				memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
3681 
3682 				psecuritypriv->busetkipkey = true;
3683 
3684 			}
3685 			else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3686 				DBG_871X("%s, set group_key, CCMP\n", __func__);
3687 
3688 				psecuritypriv->dot118021XGrpPrivacy = _AES_;
3689 
3690 				memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3691 			} else {
3692 				DBG_871X("%s, set group_key, none\n", __func__);
3693 
3694 				psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3695 			}
3696 
3697 			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
3698 
3699 			psecuritypriv->binstallGrpkey = true;
3700 
3701 			psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
3702 
3703 			rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
3704 
3705 			pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
3706 			if (pbcmc_sta) {
3707 				pbcmc_sta->ieee8021x_blocked = false;
3708 				pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
3709 			}
3710 		}
3711 
3712 		goto exit;
3713 
3714 	}
3715 
3716 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /*  psk/802_1x */
3717 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3718 			if (param->u.crypt.set_tx == 1)	{
3719 				memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3720 
3721 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3722 					DBG_871X("%s, set pairwise key, WEP\n", __func__);
3723 
3724 					psta->dot118021XPrivacy = _WEP40_;
3725 					if (param->u.crypt.key_len == 13)
3726 						psta->dot118021XPrivacy = _WEP104_;
3727 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3728 					DBG_871X("%s, set pairwise key, TKIP\n", __func__);
3729 
3730 					psta->dot118021XPrivacy = _TKIP_;
3731 
3732 					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
3733 					/* set mic key */
3734 					memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
3735 					memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
3736 
3737 					psecuritypriv->busetkipkey = true;
3738 
3739 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3740 
3741 					DBG_871X("%s, set pairwise key, CCMP\n", __func__);
3742 
3743 					psta->dot118021XPrivacy = _AES_;
3744 				} else {
3745 					DBG_871X("%s, set pairwise key, none\n", __func__);
3746 
3747 					psta->dot118021XPrivacy = _NO_PRIVACY_;
3748 				}
3749 
3750 				rtw_ap_set_pairwise_key(padapter, psta);
3751 
3752 				psta->ieee8021x_blocked = false;
3753 
3754 			} else { /* group key??? */
3755 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3756 					memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3757 
3758 					psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3759 					if (param->u.crypt.key_len == 13)
3760 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3761 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3762 					psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
3763 
3764 					memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3765 
3766 					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
3767 					/* set mic key */
3768 					memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
3769 					memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
3770 
3771 					psecuritypriv->busetkipkey = true;
3772 
3773 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3774 					psecuritypriv->dot118021XGrpPrivacy = _AES_;
3775 
3776 					memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
3777 				} else {
3778 					psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3779 				}
3780 
3781 				psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
3782 
3783 				psecuritypriv->binstallGrpkey = true;
3784 
3785 				psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
3786 
3787 				rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
3788 
3789 				pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
3790 				if (pbcmc_sta) {
3791 					pbcmc_sta->ieee8021x_blocked = false;
3792 					pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
3793 				}
3794 			}
3795 		}
3796 	}
3797 
3798 exit:
3799 	kfree(pwep);
3800 
3801 	return ret;
3802 
3803 }
3804 
3805 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
3806 {
3807 	int ret = 0;
3808 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3809 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3810 	struct sta_priv *pstapriv = &padapter->stapriv;
3811 	unsigned char *pbuf = param->u.bcn_ie.buf;
3812 
3813 
3814 	DBG_871X("%s, len =%d\n", __func__, len);
3815 
3816 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3817 		return -EINVAL;
3818 
3819 	memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3820 
3821 	if ((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<= 0))
3822 		pstapriv->max_num_sta = NUM_STA;
3823 
3824 
3825 	if (rtw_check_beacon_data(padapter, pbuf,  (len-12-2)) == _SUCCESS)/*  12 = param header, 2:no packed */
3826 		ret = 0;
3827 	else
3828 		ret = -EINVAL;
3829 
3830 
3831 	return ret;
3832 
3833 }
3834 
3835 static int rtw_hostapd_sta_flush(struct net_device *dev)
3836 {
3837 	/* _irqL irqL; */
3838 	/* struct list_head	*phead, *plist; */
3839 	/* struct sta_info *psta = NULL; */
3840 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3841 	/* struct sta_priv *pstapriv = &padapter->stapriv; */
3842 
3843 	DBG_871X("%s\n", __func__);
3844 
3845 	flush_all_cam_entry(padapter);	/* clear CAM */
3846 
3847 	return rtw_sta_flush(padapter);
3848 
3849 }
3850 
3851 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
3852 {
3853 	int ret = 0;
3854 	struct sta_info *psta = NULL;
3855 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3856 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3857 	struct sta_priv *pstapriv = &padapter->stapriv;
3858 
3859 	DBG_871X("rtw_add_sta(aid =%d) =" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
3860 
3861 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3862 		return -EINVAL;
3863 
3864 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3865 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3866 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3867 		return -EINVAL;
3868 	}
3869 
3870 /*
3871 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3872 	if (psta)
3873 	{
3874 		DBG_871X("rtw_add_sta(), free has been added psta =%p\n", psta);
3875 		spin_lock_bh(&(pstapriv->sta_hash_lock));
3876 		rtw_free_stainfo(padapter,  psta);
3877 		spin_unlock_bh(&(pstapriv->sta_hash_lock));
3878 
3879 		psta = NULL;
3880 	}
3881 */
3882 	/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
3883 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3884 	if (psta) {
3885 		int flags = param->u.add_sta.flags;
3886 
3887 		/* DBG_871X("rtw_add_sta(), init sta's variables, psta =%p\n", psta); */
3888 
3889 		psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */
3890 
3891 		memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
3892 
3893 
3894 		/* check wmm cap. */
3895 		if (WLAN_STA_WME&flags)
3896 			psta->qos_option = 1;
3897 		else
3898 			psta->qos_option = 0;
3899 
3900 		if (pmlmepriv->qospriv.qos_option == 0)
3901 			psta->qos_option = 0;
3902 
3903 		/* chec 802.11n ht cap. */
3904 		if (WLAN_STA_HT&flags) {
3905 			psta->htpriv.ht_option = true;
3906 			psta->qos_option = 1;
3907 			memcpy((void*)&psta->htpriv.ht_cap, (void*)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
3908 		} else {
3909 			psta->htpriv.ht_option = false;
3910 		}
3911 
3912 		if (pmlmepriv->htpriv.ht_option == false)
3913 			psta->htpriv.ht_option = false;
3914 
3915 		update_sta_info_apmode(padapter, psta);
3916 
3917 
3918 	} else {
3919 		ret = -ENOMEM;
3920 	}
3921 
3922 	return ret;
3923 
3924 }
3925 
3926 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
3927 {
3928 	int ret = 0;
3929 	struct sta_info *psta = NULL;
3930 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3931 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3932 	struct sta_priv *pstapriv = &padapter->stapriv;
3933 
3934 	DBG_871X("rtw_del_sta =" MAC_FMT "\n", MAC_ARG(param->sta_addr));
3935 
3936 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3937 		return -EINVAL;
3938 
3939 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3940 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3941 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3942 		return -EINVAL;
3943 	}
3944 
3945 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3946 	if (psta) {
3947 		u8 updated =false;
3948 
3949 		/* DBG_871X("free psta =%p, aid =%d\n", psta, psta->aid); */
3950 
3951 		spin_lock_bh(&pstapriv->asoc_list_lock);
3952 		if (list_empty(&psta->asoc_list) ==false) {
3953 			list_del_init(&psta->asoc_list);
3954 			pstapriv->asoc_list_cnt--;
3955 			updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
3956 
3957 		}
3958 		spin_unlock_bh(&pstapriv->asoc_list_lock);
3959 
3960 		associated_clients_update(padapter, updated);
3961 
3962 		psta = NULL;
3963 
3964 	} else {
3965 		DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
3966 
3967 		/* ret = -1; */
3968 	}
3969 
3970 
3971 	return ret;
3972 
3973 }
3974 
3975 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
3976 {
3977 	int ret = 0;
3978 	struct sta_info *psta = NULL;
3979 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3980 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3981 	struct sta_priv *pstapriv = &padapter->stapriv;
3982 	struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
3983 	struct sta_data *psta_data = (struct sta_data *)param_ex->data;
3984 
3985 	DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
3986 
3987 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3988 		return -EINVAL;
3989 
3990 	if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
3991 	    param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
3992 	    param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
3993 		return -EINVAL;
3994 	}
3995 
3996 	psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
3997 	if (psta) {
3998 		psta_data->aid = (u16)psta->aid;
3999 		psta_data->capability = psta->capability;
4000 		psta_data->flags = psta->flags;
4001 
4002 /*
4003 		nonerp_set : BIT(0)
4004 		no_short_slot_time_set : BIT(1)
4005 		no_short_preamble_set : BIT(2)
4006 		no_ht_gf_set : BIT(3)
4007 		no_ht_set : BIT(4)
4008 		ht_20mhz_set : BIT(5)
4009 */
4010 
4011 		psta_data->sta_set =((psta->nonerp_set) |
4012 							(psta->no_short_slot_time_set <<1) |
4013 							(psta->no_short_preamble_set <<2) |
4014 							(psta->no_ht_gf_set <<3) |
4015 							(psta->no_ht_set <<4) |
4016 							(psta->ht_20mhz_set <<5));
4017 
4018 		psta_data->tx_supp_rates_len =  psta->bssratelen;
4019 		memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
4020 		memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
4021 		psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
4022 		psta_data->rx_bytes = psta->sta_stats.rx_bytes;
4023 		psta_data->rx_drops = psta->sta_stats.rx_drops;
4024 
4025 		psta_data->tx_pkts = psta->sta_stats.tx_pkts;
4026 		psta_data->tx_bytes = psta->sta_stats.tx_bytes;
4027 		psta_data->tx_drops = psta->sta_stats.tx_drops;
4028 
4029 
4030 	} else {
4031 		ret = -1;
4032 	}
4033 
4034 	return ret;
4035 
4036 }
4037 
4038 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
4039 {
4040 	int ret = 0;
4041 	struct sta_info *psta = NULL;
4042 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4043 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4044 	struct sta_priv *pstapriv = &padapter->stapriv;
4045 
4046 	DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
4047 
4048 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
4049 		return -EINVAL;
4050 
4051 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
4052 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
4053 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
4054 		return -EINVAL;
4055 	}
4056 
4057 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
4058 	if (psta) {
4059 		if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
4060 			int wpa_ie_len;
4061 			int copy_len;
4062 
4063 			wpa_ie_len = psta->wpa_ie[1];
4064 
4065 			copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
4066 
4067 			param->u.wpa_ie.len = copy_len;
4068 
4069 			memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
4070 		} else {
4071 			/* ret = -1; */
4072 			DBG_871X("sta's wpa_ie is NONE\n");
4073 		}
4074 	} else {
4075 		ret = -1;
4076 	}
4077 
4078 	return ret;
4079 
4080 }
4081 
4082 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
4083 {
4084 	int ret = 0;
4085 	unsigned char wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
4086 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4087 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4088 	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4089 	int ie_len;
4090 
4091 	DBG_871X("%s, len =%d\n", __func__, len);
4092 
4093 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4094 		return -EINVAL;
4095 
4096 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
4097 
4098 
4099 	kfree(pmlmepriv->wps_beacon_ie);
4100 	pmlmepriv->wps_beacon_ie = NULL;
4101 
4102 	if (ie_len>0) {
4103 		pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
4104 		pmlmepriv->wps_beacon_ie_len = ie_len;
4105 		if (pmlmepriv->wps_beacon_ie == NULL) {
4106 			DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4107 			return -EINVAL;
4108 		}
4109 
4110 		memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
4111 
4112 		update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, true);
4113 
4114 		pmlmeext->bstart_bss = true;
4115 	}
4116 
4117 
4118 	return ret;
4119 
4120 }
4121 
4122 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
4123 {
4124 	int ret = 0;
4125 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4126 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4127 	int ie_len;
4128 
4129 	DBG_871X("%s, len =%d\n", __func__, len);
4130 
4131 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4132 		return -EINVAL;
4133 
4134 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
4135 
4136 
4137 	kfree(pmlmepriv->wps_probe_resp_ie);
4138 	pmlmepriv->wps_probe_resp_ie = NULL;
4139 
4140 	if (ie_len>0) {
4141 		pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
4142 		pmlmepriv->wps_probe_resp_ie_len = ie_len;
4143 		if (pmlmepriv->wps_probe_resp_ie == NULL) {
4144 			DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4145 			return -EINVAL;
4146 		}
4147 		memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
4148 	}
4149 
4150 
4151 	return ret;
4152 
4153 }
4154 
4155 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
4156 {
4157 	int ret = 0;
4158 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4159 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4160 	int ie_len;
4161 
4162 	DBG_871X("%s, len =%d\n", __func__, len);
4163 
4164 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4165 		return -EINVAL;
4166 
4167 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
4168 
4169 
4170 	kfree(pmlmepriv->wps_assoc_resp_ie);
4171 	pmlmepriv->wps_assoc_resp_ie = NULL;
4172 
4173 	if (ie_len>0) {
4174 		pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
4175 		pmlmepriv->wps_assoc_resp_ie_len = ie_len;
4176 		if (pmlmepriv->wps_assoc_resp_ie == NULL) {
4177 			DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4178 			return -EINVAL;
4179 		}
4180 
4181 		memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
4182 	}
4183 
4184 
4185 	return ret;
4186 
4187 }
4188 
4189 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
4190 {
4191 	int ret = 0;
4192 	struct adapter *adapter = (struct adapter *)rtw_netdev_priv(dev);
4193 	struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
4194 	struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
4195 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
4196 	int ie_len;
4197 	u8 *ssid_ie;
4198 	char ssid[NDIS_802_11_LENGTH_SSID + 1];
4199 	sint ssid_len;
4200 	u8 ignore_broadcast_ssid;
4201 
4202 	if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true)
4203 		return -EPERM;
4204 
4205 	if (param->u.bcn_ie.reserved[0] != 0xea)
4206 		return -EINVAL;
4207 
4208 	mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
4209 
4210 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
4211 	ssid_ie = rtw_get_ie(param->u.bcn_ie.buf,  WLAN_EID_SSID, &ssid_len, ie_len);
4212 
4213 	if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
4214 		struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network;
4215 		struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network;
4216 
4217 		memcpy(ssid, ssid_ie+2, ssid_len);
4218 		ssid[ssid_len] = 0x0;
4219 
4220 		if (0)
4221 			DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
4222 				 ssid, ssid_len,
4223 				 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
4224 				 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
4225 
4226 		memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
4227 		pbss_network->Ssid.SsidLength = ssid_len;
4228 		memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
4229 		pbss_network_ext->Ssid.SsidLength = ssid_len;
4230 
4231 		if (0)
4232 			DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
4233 				 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
4234 				 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
4235 	}
4236 
4237 	DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
4238 		ignore_broadcast_ssid, ssid, ssid_len);
4239 
4240 	return ret;
4241 }
4242 
4243 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
4244 {
4245 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4246 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4247 
4248 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4249 		return -EINVAL;
4250 
4251 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
4252 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
4253 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
4254 		return -EINVAL;
4255 	}
4256 
4257 	return rtw_acl_remove_sta(padapter, param->sta_addr);
4258 
4259 }
4260 
4261 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
4262 {
4263 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4264 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4265 
4266 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4267 		return -EINVAL;
4268 
4269 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
4270 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
4271 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
4272 		return -EINVAL;
4273 	}
4274 
4275 	return rtw_acl_add_sta(padapter, param->sta_addr);
4276 
4277 }
4278 
4279 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
4280 {
4281 	int ret = 0;
4282 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4283 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4284 
4285 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
4286 		return -EINVAL;
4287 
4288 	rtw_set_macaddr_acl(padapter, param->u.mlme.command);
4289 
4290 	return ret;
4291 }
4292 
4293 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
4294 {
4295 	struct ieee_param *param;
4296 	int ret = 0;
4297 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4298 
4299 	/* DBG_871X("%s\n", __func__); */
4300 
4301 	/*
4302 	* this function is expect to call in master mode, which allows no power saving
4303 	* so, we just check hw_init_completed
4304 	*/
4305 
4306 	if (padapter->hw_init_completed ==false) {
4307 		ret = -EPERM;
4308 		goto out;
4309 	}
4310 
4311 
4312 	/* if (p->length < sizeof(struct ieee_param) || !p->pointer) { */
4313 	if (!p->pointer) {
4314 		ret = -EINVAL;
4315 		goto out;
4316 	}
4317 
4318 	param = rtw_malloc(p->length);
4319 	if (param == NULL) {
4320 		ret = -ENOMEM;
4321 		goto out;
4322 	}
4323 
4324 	if (copy_from_user(param, p->pointer, p->length)) {
4325 		kfree(param);
4326 		ret = -EFAULT;
4327 		goto out;
4328 	}
4329 
4330 	/* DBG_871X("%s, cmd =%d\n", __func__, param->cmd); */
4331 
4332 	switch (param->cmd) {
4333 		case RTL871X_HOSTAPD_FLUSH:
4334 
4335 			ret = rtw_hostapd_sta_flush(dev);
4336 
4337 			break;
4338 
4339 		case RTL871X_HOSTAPD_ADD_STA:
4340 
4341 			ret = rtw_add_sta(dev, param);
4342 
4343 			break;
4344 
4345 		case RTL871X_HOSTAPD_REMOVE_STA:
4346 
4347 			ret = rtw_del_sta(dev, param);
4348 
4349 			break;
4350 
4351 		case RTL871X_HOSTAPD_SET_BEACON:
4352 
4353 			ret = rtw_set_beacon(dev, param, p->length);
4354 
4355 			break;
4356 
4357 		case RTL871X_SET_ENCRYPTION:
4358 
4359 			ret = rtw_set_encryption(dev, param, p->length);
4360 
4361 			break;
4362 
4363 		case RTL871X_HOSTAPD_GET_WPAIE_STA:
4364 
4365 			ret = rtw_get_sta_wpaie(dev, param);
4366 
4367 			break;
4368 
4369 		case RTL871X_HOSTAPD_SET_WPS_BEACON:
4370 
4371 			ret = rtw_set_wps_beacon(dev, param, p->length);
4372 
4373 			break;
4374 
4375 		case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
4376 
4377 			ret = rtw_set_wps_probe_resp(dev, param, p->length);
4378 
4379 			break;
4380 
4381 		case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
4382 
4383 			ret = rtw_set_wps_assoc_resp(dev, param, p->length);
4384 
4385 			break;
4386 
4387 		case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
4388 
4389 			ret = rtw_set_hidden_ssid(dev, param, p->length);
4390 
4391 			break;
4392 
4393 		case RTL871X_HOSTAPD_GET_INFO_STA:
4394 
4395 			ret = rtw_ioctl_get_sta_data(dev, param, p->length);
4396 
4397 			break;
4398 
4399 		case RTL871X_HOSTAPD_SET_MACADDR_ACL:
4400 
4401 			ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
4402 
4403 			break;
4404 
4405 		case RTL871X_HOSTAPD_ACL_ADD_STA:
4406 
4407 			ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
4408 
4409 			break;
4410 
4411 		case RTL871X_HOSTAPD_ACL_REMOVE_STA:
4412 
4413 			ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
4414 
4415 			break;
4416 
4417 		default:
4418 			DBG_871X("Unknown hostapd request: %d\n", param->cmd);
4419 			ret = -EOPNOTSUPP;
4420 			break;
4421 
4422 	}
4423 
4424 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
4425 		ret = -EFAULT;
4426 
4427 
4428 	kfree(param);
4429 
4430 out:
4431 
4432 	return ret;
4433 
4434 }
4435 
4436 static int rtw_wx_set_priv(struct net_device *dev,
4437 				struct iw_request_info *info,
4438 				union iwreq_data *awrq,
4439 				char *extra)
4440 {
4441 
4442 #ifdef DEBUG_RTW_WX_SET_PRIV
4443 	char *ext_dbg;
4444 #endif
4445 
4446 	int ret = 0;
4447 	int len = 0;
4448 	char *ext;
4449 
4450 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4451 	struct iw_point *dwrq = (struct iw_point*)awrq;
4452 
4453 	/* RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n")); */
4454 	if (dwrq->length == 0)
4455 		return -EFAULT;
4456 
4457 	len = dwrq->length;
4458 	if (!(ext = vmalloc(len)))
4459 		return -ENOMEM;
4460 
4461 	if (copy_from_user(ext, dwrq->pointer, len)) {
4462 		vfree(ext);
4463 		return -EFAULT;
4464 	}
4465 
4466 
4467 	/* RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, */
4468 	/* 	 ("rtw_wx_set_priv: %s req =%s\n", */
4469 	/* 	  dev->name, ext)); */
4470 
4471 	#ifdef DEBUG_RTW_WX_SET_PRIV
4472 	if (!(ext_dbg = vmalloc(len))) {
4473 		vfree(ext, len);
4474 		return -ENOMEM;
4475 	}
4476 
4477 	memcpy(ext_dbg, ext, len);
4478 	#endif
4479 
4480 	/* added for wps2.0 @20110524 */
4481 	if (dwrq->flags == 0x8766 && len > 8) {
4482 		u32 cp_sz;
4483 		struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4484 		u8 *probereq_wpsie = ext;
4485 		int probereq_wpsie_len = len;
4486 		u8 wps_oui[4]={0x0, 0x50, 0xf2, 0x04};
4487 
4488 		if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
4489 			(!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
4490 			cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
4491 
4492 			if (pmlmepriv->wps_probe_req_ie) {
4493 				pmlmepriv->wps_probe_req_ie_len = 0;
4494 				kfree(pmlmepriv->wps_probe_req_ie);
4495 				pmlmepriv->wps_probe_req_ie = NULL;
4496 			}
4497 
4498 			pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
4499 			if (pmlmepriv->wps_probe_req_ie == NULL) {
4500 				printk("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
4501 				ret =  -EINVAL;
4502 				goto FREE_EXT;
4503 
4504 			}
4505 
4506 			memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
4507 			pmlmepriv->wps_probe_req_ie_len = cp_sz;
4508 
4509 		}
4510 
4511 		goto FREE_EXT;
4512 
4513 	}
4514 
4515 	if (len >= WEXT_CSCAN_HEADER_SIZE
4516 		&& !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
4517 		ret = rtw_wx_set_scan(dev, info, awrq, ext);
4518 		goto FREE_EXT;
4519 	}
4520 
4521 FREE_EXT:
4522 
4523 	vfree(ext);
4524 	#ifdef DEBUG_RTW_WX_SET_PRIV
4525 	vfree(ext_dbg);
4526 	#endif
4527 
4528 	/* DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret =%d\n", */
4529 	/* 		dev->name, ret); */
4530 
4531 	return ret;
4532 
4533 }
4534 
4535 static int rtw_pm_set(struct net_device *dev,
4536                                struct iw_request_info *info,
4537                                union iwreq_data *wrqu, char *extra)
4538 {
4539 	int ret = 0;
4540 	unsigned	mode = 0;
4541 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4542 
4543 	DBG_871X("[%s] extra = %s\n", __func__, extra);
4544 
4545 	if (!memcmp(extra, "lps =", 4)) {
4546 		sscanf(extra+4, "%u", &mode);
4547 		ret = rtw_pm_set_lps(padapter, mode);
4548 	} else if (!memcmp(extra, "ips =", 4)) {
4549 		sscanf(extra+4, "%u", &mode);
4550 		ret = rtw_pm_set_ips(padapter, mode);
4551 	} else {
4552 		ret = -EINVAL;
4553 	}
4554 
4555 	return ret;
4556 }
4557 
4558 static int rtw_mp_efuse_get(struct net_device *dev,
4559 			struct iw_request_info *info,
4560 			union iwreq_data *wdata, char *extra)
4561 {
4562 	int err = 0;
4563 	return err;
4564 }
4565 
4566 static int rtw_mp_efuse_set(struct net_device *dev,
4567 			struct iw_request_info *info,
4568 			union iwreq_data *wdata, char *extra)
4569 {
4570 	int err = 0;
4571 	return err;
4572 }
4573 
4574 static int rtw_tdls(struct net_device *dev,
4575 				struct iw_request_info *info,
4576 				union iwreq_data *wrqu, char *extra)
4577 {
4578 	int ret = 0;
4579 	return ret;
4580 }
4581 
4582 
4583 static int rtw_tdls_get(struct net_device *dev,
4584 				struct iw_request_info *info,
4585 				union iwreq_data *wrqu, char *extra)
4586 {
4587 	int ret = 0;
4588 	return ret;
4589 }
4590 
4591 
4592 
4593 
4594 
4595 #ifdef CONFIG_INTEL_WIDI
4596 static int rtw_widi_set(struct net_device *dev,
4597                                struct iw_request_info *info,
4598                                union iwreq_data *wrqu, char *extra)
4599 {
4600 	int ret = 0;
4601 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4602 
4603 	process_intel_widi_cmd(padapter, extra);
4604 
4605 	return ret;
4606 }
4607 
4608 static int rtw_widi_set_probe_request(struct net_device *dev,
4609                                struct iw_request_info *info,
4610                                union iwreq_data *wrqu, char *extra)
4611 {
4612 	int	ret = 0;
4613 	u8 *pbuf = NULL;
4614 	struct adapter	*padapter = (struct adapter *)rtw_netdev_priv(dev);
4615 
4616 	pbuf = rtw_malloc(sizeof(l2_msg_t));
4617 	if (pbuf) {
4618 		if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length))
4619 			ret = -EFAULT;
4620 		/* memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); */
4621 
4622 		if (wrqu->data.flags == 0)
4623 			intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t));
4624 		else if (wrqu->data.flags == 1)
4625 			rtw_set_wfd_rds_sink_info(padapter, (l2_msg_t *)pbuf);
4626 	}
4627 	return ret;
4628 }
4629 #endif /*  CONFIG_INTEL_WIDI */
4630 
4631 static int rtw_test(
4632 	struct net_device *dev,
4633 	struct iw_request_info *info,
4634 	union iwreq_data *wrqu, char *extra)
4635 {
4636 	u32 len;
4637 	u8 *pbuf, *pch;
4638 	char *ptmp;
4639 	u8 *delim = ",";
4640 	struct adapter *padapter = rtw_netdev_priv(dev);
4641 
4642 
4643 	DBG_871X("+%s\n", __func__);
4644 	len = wrqu->data.length;
4645 
4646 	pbuf = rtw_zmalloc(len);
4647 	if (pbuf == NULL) {
4648 		DBG_871X("%s: no memory!\n", __func__);
4649 		return -ENOMEM;
4650 	}
4651 
4652 	if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
4653 		kfree(pbuf);
4654 		DBG_871X("%s: copy from user fail!\n", __func__);
4655 		return -EFAULT;
4656 	}
4657 	DBG_871X("%s: string =\"%s\"\n", __func__, pbuf);
4658 
4659 	ptmp = (char*)pbuf;
4660 	pch = strsep(&ptmp, delim);
4661 	if ((pch == NULL) || (strlen(pch) == 0)) {
4662 		kfree(pbuf);
4663 		DBG_871X("%s: parameter error(level 1)!\n", __func__);
4664 		return -EFAULT;
4665 	}
4666 
4667 	if (strcmp(pch, "bton") == 0)
4668 		rtw_btcoex_SetManualControl(padapter, false);
4669 
4670 	if (strcmp(pch, "btoff") == 0)
4671 		rtw_btcoex_SetManualControl(padapter, true);
4672 
4673 	if (strcmp(pch, "h2c") == 0) {
4674 		u8 param[8];
4675 		u8 count = 0;
4676 		u32 tmp;
4677 		u8 i;
4678 		u32 pos;
4679 		s32 ret;
4680 
4681 
4682 		do {
4683 			pch = strsep(&ptmp, delim);
4684 			if ((pch == NULL) || (strlen(pch) == 0))
4685 				break;
4686 
4687 			sscanf(pch, "%x", &tmp);
4688 			param[count++] = (u8)tmp;
4689 		} while (count < 8);
4690 
4691 		if (count == 0) {
4692 			kfree(pbuf);
4693 			DBG_871X("%s: parameter error(level 2)!\n", __func__);
4694 			return -EFAULT;
4695 		}
4696 
4697 		ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, &param[1]);
4698 
4699 		pos = sprintf(extra, "H2C ID = 0x%02x content =", param[0]);
4700 		for (i = 1; i<count; i++)
4701 			pos += sprintf(extra+pos, "%02x,", param[i]);
4702 		extra[pos] = 0;
4703 		pos--;
4704 		pos += sprintf(extra+pos, " %s", ret == _FAIL?"FAIL":"OK");
4705 
4706 		wrqu->data.length = strlen(extra) + 1;
4707 	}
4708 
4709 	kfree(pbuf);
4710 	return 0;
4711 }
4712 
4713 static iw_handler rtw_handlers[] = {
4714 	NULL,					/* SIOCSIWCOMMIT */
4715 	rtw_wx_get_name,		/* SIOCGIWNAME */
4716 	dummy,					/* SIOCSIWNWID */
4717 	dummy,					/* SIOCGIWNWID */
4718 	rtw_wx_set_freq,		/* SIOCSIWFREQ */
4719 	rtw_wx_get_freq,		/* SIOCGIWFREQ */
4720 	rtw_wx_set_mode,		/* SIOCSIWMODE */
4721 	rtw_wx_get_mode,		/* SIOCGIWMODE */
4722 	dummy,					/* SIOCSIWSENS */
4723 	rtw_wx_get_sens,		/* SIOCGIWSENS */
4724 	NULL,					/* SIOCSIWRANGE */
4725 	rtw_wx_get_range,		/* SIOCGIWRANGE */
4726 	rtw_wx_set_priv,		/* SIOCSIWPRIV */
4727 	NULL,					/* SIOCGIWPRIV */
4728 	NULL,					/* SIOCSIWSTATS */
4729 	NULL,					/* SIOCGIWSTATS */
4730 	dummy,					/* SIOCSIWSPY */
4731 	dummy,					/* SIOCGIWSPY */
4732 	NULL,					/* SIOCGIWTHRSPY */
4733 	NULL,					/* SIOCWIWTHRSPY */
4734 	rtw_wx_set_wap,		/* SIOCSIWAP */
4735 	rtw_wx_get_wap,		/* SIOCGIWAP */
4736 	rtw_wx_set_mlme,		/* request MLME operation; uses struct iw_mlme */
4737 	dummy,					/* SIOCGIWAPLIST -- depricated */
4738 	rtw_wx_set_scan,		/* SIOCSIWSCAN */
4739 	rtw_wx_get_scan,		/* SIOCGIWSCAN */
4740 	rtw_wx_set_essid,		/* SIOCSIWESSID */
4741 	rtw_wx_get_essid,		/* SIOCGIWESSID */
4742 	dummy,					/* SIOCSIWNICKN */
4743 	rtw_wx_get_nick,		/* SIOCGIWNICKN */
4744 	NULL,					/* -- hole -- */
4745 	NULL,					/* -- hole -- */
4746 	rtw_wx_set_rate,		/* SIOCSIWRATE */
4747 	rtw_wx_get_rate,		/* SIOCGIWRATE */
4748 	rtw_wx_set_rts,			/* SIOCSIWRTS */
4749 	rtw_wx_get_rts,			/* SIOCGIWRTS */
4750 	rtw_wx_set_frag,		/* SIOCSIWFRAG */
4751 	rtw_wx_get_frag,		/* SIOCGIWFRAG */
4752 	dummy,					/* SIOCSIWTXPOW */
4753 	dummy,					/* SIOCGIWTXPOW */
4754 	dummy,					/* SIOCSIWRETRY */
4755 	rtw_wx_get_retry,		/* SIOCGIWRETRY */
4756 	rtw_wx_set_enc,			/* SIOCSIWENCODE */
4757 	rtw_wx_get_enc,			/* SIOCGIWENCODE */
4758 	dummy,					/* SIOCSIWPOWER */
4759 	rtw_wx_get_power,		/* SIOCGIWPOWER */
4760 	NULL,					/*---hole---*/
4761 	NULL,					/*---hole---*/
4762 	rtw_wx_set_gen_ie,		/* SIOCSIWGENIE */
4763 	NULL,					/* SIOCGWGENIE */
4764 	rtw_wx_set_auth,		/* SIOCSIWAUTH */
4765 	NULL,					/* SIOCGIWAUTH */
4766 	rtw_wx_set_enc_ext,		/* SIOCSIWENCODEEXT */
4767 	NULL,					/* SIOCGIWENCODEEXT */
4768 	rtw_wx_set_pmkid,		/* SIOCSIWPMKSA */
4769 	NULL,					/*---hole---*/
4770 };
4771 
4772 static const struct iw_priv_args rtw_private_args[] = {
4773 	{
4774 		SIOCIWFIRSTPRIV + 0x0,
4775 		IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
4776 	},
4777 	{
4778 		SIOCIWFIRSTPRIV + 0x1,
4779 		IW_PRIV_TYPE_CHAR | 0x7FF,
4780 		IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
4781 	},
4782 	{
4783 		SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
4784 	},
4785 	{
4786 		SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
4787 	},
4788 	{
4789 		SIOCIWFIRSTPRIV + 0x4,
4790 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
4791 	},
4792 	{
4793 		SIOCIWFIRSTPRIV + 0x5,
4794 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
4795 	},
4796 	{
4797 		SIOCIWFIRSTPRIV + 0x6,
4798 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
4799 	},
4800 /* for PLATFORM_MT53XX */
4801 	{
4802 		SIOCIWFIRSTPRIV + 0x7,
4803 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
4804 	},
4805 	{
4806 		SIOCIWFIRSTPRIV + 0x8,
4807 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
4808 	},
4809 	{
4810 		SIOCIWFIRSTPRIV + 0x9,
4811 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
4812 	},
4813 
4814 /* for RTK_DMP_PLATFORM */
4815 	{
4816 		SIOCIWFIRSTPRIV + 0xA,
4817 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
4818 	},
4819 
4820 	{
4821 		SIOCIWFIRSTPRIV + 0xB,
4822 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
4823 	},
4824 	{
4825 		SIOCIWFIRSTPRIV + 0xC,
4826 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
4827 	},
4828 	{
4829 		SIOCIWFIRSTPRIV + 0xD,
4830 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
4831 	},
4832 	{
4833 		SIOCIWFIRSTPRIV + 0x10,
4834 		IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
4835 	},
4836 	{
4837 		SIOCIWFIRSTPRIV + 0x11,
4838 		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
4839 	},
4840 	{
4841 		SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
4842 	},
4843 	{
4844 		SIOCIWFIRSTPRIV + 0x13,
4845 		IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
4846 	},
4847 	{
4848 		SIOCIWFIRSTPRIV + 0x14,
4849 		IW_PRIV_TYPE_CHAR  | 64, 0, "tdls"
4850 	},
4851 	{
4852 		SIOCIWFIRSTPRIV + 0x15,
4853 		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
4854 	},
4855 	{
4856 		SIOCIWFIRSTPRIV + 0x16,
4857 		IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
4858 	},
4859 
4860 	{SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
4861 	{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
4862 	{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
4863 	{
4864 		SIOCIWFIRSTPRIV + 0x1D,
4865 		IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
4866 	},
4867 
4868 #ifdef CONFIG_INTEL_WIDI
4869 	{
4870 		SIOCIWFIRSTPRIV + 0x1E,
4871 		IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
4872 	},
4873 	{
4874 		SIOCIWFIRSTPRIV + 0x1F,
4875 		IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
4876 	},
4877 #endif /*  CONFIG_INTEL_WIDI */
4878 
4879 #ifdef CONFIG_WOWLAN
4880 		{ MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" }, /* set */
4881 #endif
4882 #ifdef CONFIG_AP_WOWLAN
4883 		{ MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */
4884 #endif
4885 };
4886 
4887 static iw_handler rtw_private_handler[] = {
4888 	rtw_wx_write32,					/* 0x00 */
4889 	rtw_wx_read32,					/* 0x01 */
4890 	rtw_drvext_hdl,					/* 0x02 */
4891 	rtw_mp_ioctl_hdl,				/* 0x03 */
4892 
4893 /*  for MM DTV platform */
4894 	rtw_get_ap_info,					/* 0x04 */
4895 
4896 	rtw_set_pid,						/* 0x05 */
4897 	rtw_wps_start,					/* 0x06 */
4898 
4899 /*  for PLATFORM_MT53XX */
4900 	rtw_wx_get_sensitivity,			/* 0x07 */
4901 	rtw_wx_set_mtk_wps_probe_ie,	/* 0x08 */
4902 	rtw_wx_set_mtk_wps_ie,			/* 0x09 */
4903 
4904 /*  for RTK_DMP_PLATFORM */
4905 /*  Set Channel depend on the country code */
4906 	rtw_wx_set_channel_plan,		/* 0x0A */
4907 
4908 	rtw_dbg_port,					/* 0x0B */
4909 	rtw_wx_write_rf,					/* 0x0C */
4910 	rtw_wx_read_rf,					/* 0x0D */
4911 	rtw_wx_priv_null,				/* 0x0E */
4912 	rtw_wx_priv_null,				/* 0x0F */
4913 	rtw_p2p_set,					/* 0x10 */
4914 	rtw_p2p_get,					/* 0x11 */
4915 	NULL,							/* 0x12 */
4916 	rtw_p2p_get2,					/* 0x13 */
4917 
4918 	rtw_tdls,						/* 0x14 */
4919 	rtw_tdls_get,					/* 0x15 */
4920 
4921 	rtw_pm_set,						/* 0x16 */
4922 	rtw_wx_priv_null,				/* 0x17 */
4923 	rtw_rereg_nd_name,				/* 0x18 */
4924 	rtw_wx_priv_null,				/* 0x19 */
4925 	rtw_mp_efuse_set,				/* 0x1A */
4926 	rtw_mp_efuse_get,				/* 0x1B */
4927 	NULL,							/*  0x1C is reserved for hostapd */
4928 	rtw_test,						/*  0x1D */
4929 #ifdef CONFIG_INTEL_WIDI
4930 	rtw_widi_set,					/* 0x1E */
4931 	rtw_widi_set_probe_request,		/* 0x1F */
4932 #endif /*  CONFIG_INTEL_WIDI */
4933 };
4934 
4935 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
4936 {
4937 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4938 	struct iw_statistics *piwstats =&padapter->iwstats;
4939 	int tmp_level = 0;
4940 	int tmp_qual = 0;
4941 	int tmp_noise = 0;
4942 
4943 	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
4944 		piwstats->qual.qual = 0;
4945 		piwstats->qual.level = 0;
4946 		piwstats->qual.noise = 0;
4947 		/* DBG_871X("No link  level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */
4948 	} else {
4949 		#ifdef CONFIG_SIGNAL_DISPLAY_DBM
4950 		tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
4951 		#else
4952 		#ifdef CONFIG_SKIP_SIGNAL_SCALE_MAPPING
4953 		{
4954 			/* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
4955 
4956 			struct hal_com_data *pHal = GET_HAL_DATA(padapter);
4957 
4958 			tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength);
4959 		}
4960 		#else
4961 		tmp_level = padapter->recvpriv.signal_strength;
4962 		#endif
4963 		#endif
4964 
4965 		tmp_qual = padapter->recvpriv.signal_qual;
4966 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
4967 		if (rtw_linked_check(padapter)) {
4968 			struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4969 			struct noise_info info;
4970 			info.bPauseDIG = true;
4971 			info.IGIValue = 0x1e;
4972 			info.max_time = 100;/* ms */
4973 			info.chan = pmlmeext->cur_channel ;/* rtw_get_oper_ch(padapter); */
4974 			rtw_ps_deny(padapter, PS_DENY_IOCTL);
4975 			LeaveAllPowerSaveModeDirect(padapter);
4976 
4977 			rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&info, false);
4978 			/* ODM_InbandNoise_Monitor(podmpriv, true, 0x20, 100); */
4979 			rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
4980 			rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(info.chan), &(padapter->recvpriv.noise));
4981 			DBG_871X("chan:%d, noise_level:%d\n", info.chan, padapter->recvpriv.noise);
4982 		}
4983 #endif
4984 		tmp_noise = padapter->recvpriv.noise;
4985 		DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise, padapter->recvpriv.rssi);
4986 
4987 		piwstats->qual.level = tmp_level;
4988 		piwstats->qual.qual = tmp_qual;
4989 		piwstats->qual.noise = tmp_noise;
4990 	}
4991 	piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* IW_QUAL_DBM; */
4992 
4993 	#ifdef CONFIG_SIGNAL_DISPLAY_DBM
4994 	piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
4995 	#endif
4996 
4997 	return &padapter->iwstats;
4998 }
4999 
5000 struct iw_handler_def rtw_handlers_def = {
5001 	.standard = rtw_handlers,
5002 	.num_standard = ARRAY_SIZE(rtw_handlers),
5003 #if defined(CONFIG_WEXT_PRIV)
5004 	.private = rtw_private_handler,
5005 	.private_args = (struct iw_priv_args *)rtw_private_args,
5006 	.num_private = ARRAY_SIZE(rtw_private_handler),
5007 	.num_private_args = ARRAY_SIZE(rtw_private_args),
5008 #endif
5009 	.get_wireless_stats = rtw_get_wireless_stats,
5010 };
5011 
5012 /*  copy from net/wireless/wext.c start */
5013 /* ---------------------------------------------------------------- */
5014 /*
5015  * Calculate size of private arguments
5016  */
5017 static const char iw_priv_type_size[] = {
5018 	0,                              /* IW_PRIV_TYPE_NONE */
5019 	1,                              /* IW_PRIV_TYPE_BYTE */
5020 	1,                              /* IW_PRIV_TYPE_CHAR */
5021 	0,                              /* Not defined */
5022 	sizeof(__u32),                  /* IW_PRIV_TYPE_INT */
5023 	sizeof(struct iw_freq),         /* IW_PRIV_TYPE_FLOAT */
5024 	sizeof(struct sockaddr),        /* IW_PRIV_TYPE_ADDR */
5025 	0,                              /* Not defined */
5026 };
5027 
5028 static int get_priv_size(__u16 args)
5029 {
5030 	int num = args & IW_PRIV_SIZE_MASK;
5031 	int type = (args & IW_PRIV_TYPE_MASK) >> 12;
5032 
5033 	return num * iw_priv_type_size[type];
5034 }
5035 /*  copy from net/wireless/wext.c end */
5036 
5037 static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
5038 {
5039 	int err = 0;
5040 	u8 *input = NULL;
5041 	u32 input_len = 0;
5042 	const char delim[] = " ";
5043 	u8 *output = NULL;
5044 	u32 output_len = 0;
5045 	u32 count = 0;
5046 	u8 *buffer = NULL;
5047 	u32 buffer_len = 0;
5048 	char *ptr = NULL;
5049 	u8 cmdname[17] = {0}; /*  IFNAMSIZ+1 */
5050 	u32 cmdlen;
5051 	s32 len;
5052 	u8 *extra = NULL;
5053 	u32 extra_size = 0;
5054 
5055 	s32 k;
5056 	const iw_handler *priv;		/* Private ioctl */
5057 	const struct iw_priv_args *priv_args;	/* Private ioctl description */
5058 	u32 num_priv;				/* Number of ioctl */
5059 	u32 num_priv_args;			/* Number of descriptions */
5060 	iw_handler handler;
5061 	int temp;
5062 	int subcmd = 0;				/* sub-ioctl index */
5063 	int offset = 0;				/* Space for sub-ioctl index */
5064 
5065 	union iwreq_data wdata;
5066 
5067 
5068 	memcpy(&wdata, wrq_data, sizeof(wdata));
5069 
5070 	input_len = 2048;
5071 	input = rtw_zmalloc(input_len);
5072 	if (NULL == input)
5073 		return -ENOMEM;
5074 	if (copy_from_user(input, wdata.data.pointer, input_len)) {
5075 		err = -EFAULT;
5076 		goto exit;
5077 	}
5078 	ptr = input;
5079 	len = strlen(input);
5080 
5081 	sscanf(ptr, "%16s", cmdname);
5082 	cmdlen = strlen(cmdname);
5083 	DBG_8192C("%s: cmd =%s\n", __func__, cmdname);
5084 
5085 	/*  skip command string */
5086 	if (cmdlen > 0)
5087 		cmdlen += 1; /*  skip one space */
5088 	ptr += cmdlen;
5089 	len -= cmdlen;
5090 	DBG_8192C("%s: parameters =%s\n", __func__, ptr);
5091 
5092 	priv = rtw_private_handler;
5093 	priv_args = rtw_private_args;
5094 	num_priv = ARRAY_SIZE(rtw_private_handler);
5095 	num_priv_args = ARRAY_SIZE(rtw_private_args);
5096 
5097 	if (num_priv_args == 0) {
5098 		err = -EOPNOTSUPP;
5099 		goto exit;
5100 	}
5101 
5102 	/* Search the correct ioctl */
5103 	k = -1;
5104 	while ((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
5105 
5106 	/* If not found... */
5107 	if (k == num_priv_args) {
5108 		err = -EOPNOTSUPP;
5109 		goto exit;
5110 	}
5111 
5112 	/* Watch out for sub-ioctls ! */
5113 	if (priv_args[k].cmd < SIOCDEVPRIVATE) {
5114 		int j = -1;
5115 
5116 		/* Find the matching *real* ioctl */
5117 		while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
5118 			(priv_args[j].set_args != priv_args[k].set_args) ||
5119 			(priv_args[j].get_args != priv_args[k].get_args)));
5120 
5121 		/* If not found... */
5122 		if (j == num_priv_args) {
5123 			err = -EINVAL;
5124 			goto exit;
5125 		}
5126 
5127 		/* Save sub-ioctl number */
5128 		subcmd = priv_args[k].cmd;
5129 		/* Reserve one int (simplify alignment issues) */
5130 		offset = sizeof(__u32);
5131 		/* Use real ioctl definition from now on */
5132 		k = j;
5133 	}
5134 
5135 	buffer = rtw_zmalloc(4096);
5136 	if (NULL == buffer) {
5137 		err = -ENOMEM;
5138 		goto exit;
5139 	}
5140 
5141 	/* If we have to set some data */
5142 	if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
5143 		(priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
5144 		u8 *str;
5145 
5146 		switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
5147 			case IW_PRIV_TYPE_BYTE:
5148 				/* Fetch args */
5149 				count = 0;
5150 				do {
5151 					str = strsep(&ptr, delim);
5152 					if (NULL == str) break;
5153 					sscanf(str, "%i", &temp);
5154 					buffer[count++] = (u8)temp;
5155 				} while (1);
5156 				buffer_len = count;
5157 
5158 				/* Number of args to fetch */
5159 				wdata.data.length = count;
5160 				if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
5161 					wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
5162 
5163 				break;
5164 
5165 			case IW_PRIV_TYPE_INT:
5166 				/* Fetch args */
5167 				count = 0;
5168 				do {
5169 					str = strsep(&ptr, delim);
5170 					if (NULL == str) break;
5171 					sscanf(str, "%i", &temp);
5172 					((s32*)buffer)[count++] = (s32)temp;
5173 				} while (1);
5174 				buffer_len = count * sizeof(s32);
5175 
5176 				/* Number of args to fetch */
5177 				wdata.data.length = count;
5178 				if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
5179 					wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
5180 
5181 				break;
5182 
5183 			case IW_PRIV_TYPE_CHAR:
5184 				if (len > 0) {
5185 					/* Size of the string to fetch */
5186 					wdata.data.length = len;
5187 					if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
5188 						wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
5189 
5190 					/* Fetch string */
5191 					memcpy(buffer, ptr, wdata.data.length);
5192 				} else {
5193 					wdata.data.length = 1;
5194 					buffer[0] = '\0';
5195 				}
5196 				buffer_len = wdata.data.length;
5197 				break;
5198 
5199 			default:
5200 				DBG_8192C("%s: Not yet implemented...\n", __func__);
5201 				err = -1;
5202 				goto exit;
5203 		}
5204 
5205 		if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
5206 			(wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
5207 			DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
5208 					__func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
5209 			err = -EINVAL;
5210 			goto exit;
5211 		}
5212 	} else { /* if args to set */
5213 		wdata.data.length = 0L;
5214 	}
5215 
5216 	/* Those two tests are important. They define how the driver
5217 	* will have to handle the data */
5218 	if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
5219 		((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
5220 		/* First case : all SET args fit within wrq */
5221 		if (offset)
5222 			wdata.mode = subcmd;
5223 		memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
5224 	} else {
5225 		if ((priv_args[k].set_args == 0) &&
5226 			(priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
5227 			(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
5228 			/* Second case : no SET args, GET args fit within wrq */
5229 			if (offset)
5230 				wdata.mode = subcmd;
5231 		} else {
5232 			/* Third case : args won't fit in wrq, or variable number of args */
5233 			if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
5234 				err = -EFAULT;
5235 				goto exit;
5236 			}
5237 			wdata.data.flags = subcmd;
5238 		}
5239 	}
5240 
5241 	kfree(input);
5242 	input = NULL;
5243 
5244 	extra_size = 0;
5245 	if (IW_IS_SET(priv_args[k].cmd)) {
5246 		/* Size of set arguments */
5247 		extra_size = get_priv_size(priv_args[k].set_args);
5248 
5249 		/* Does it fits in iwr ? */
5250 		if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
5251 			((extra_size + offset) <= IFNAMSIZ))
5252 			extra_size = 0;
5253 	} else {
5254 		/* Size of get arguments */
5255 		extra_size = get_priv_size(priv_args[k].get_args);
5256 
5257 		/* Does it fits in iwr ? */
5258 		if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
5259 			(extra_size <= IFNAMSIZ))
5260 			extra_size = 0;
5261 	}
5262 
5263 	if (extra_size == 0) {
5264 		extra = (u8 *)&wdata;
5265 		kfree(buffer);
5266 		buffer = NULL;
5267 	} else
5268 		extra = buffer;
5269 
5270 	handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
5271 	err = handler(dev, NULL, &wdata, extra);
5272 
5273 	/* If we have to get some data */
5274 	if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
5275 		(priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
5276 		int j;
5277 		int n = 0;	/* number of args */
5278 		u8 str[20] = {0};
5279 
5280 		/* Check where is the returned data */
5281 		if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
5282 			(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
5283 			n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
5284 		else
5285 			n = wdata.data.length;
5286 
5287 		output = rtw_zmalloc(4096);
5288 		if (NULL == output) {
5289 			err =  -ENOMEM;
5290 			goto exit;
5291 		}
5292 
5293 		switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
5294 			case IW_PRIV_TYPE_BYTE:
5295 				/* Display args */
5296 				for (j = 0; j < n; j++) {
5297 					sprintf(str, "%d  ", extra[j]);
5298 					len = strlen(str);
5299 					output_len = strlen(output);
5300 					if ((output_len + len + 1) > 4096) {
5301 						err = -E2BIG;
5302 						goto exit;
5303 					}
5304 					memcpy(output+output_len, str, len);
5305 				}
5306 				break;
5307 
5308 			case IW_PRIV_TYPE_INT:
5309 				/* Display args */
5310 				for (j = 0; j < n; j++) {
5311 					sprintf(str, "%d  ", ((__s32*)extra)[j]);
5312 					len = strlen(str);
5313 					output_len = strlen(output);
5314 					if ((output_len + len + 1) > 4096) {
5315 						err = -E2BIG;
5316 						goto exit;
5317 					}
5318 					memcpy(output+output_len, str, len);
5319 				}
5320 				break;
5321 
5322 			case IW_PRIV_TYPE_CHAR:
5323 				/* Display args */
5324 				memcpy(output, extra, n);
5325 				break;
5326 
5327 			default:
5328 				DBG_8192C("%s: Not yet implemented...\n", __func__);
5329 				err = -1;
5330 				goto exit;
5331 		}
5332 
5333 		output_len = strlen(output) + 1;
5334 		wrq_data->data.length = output_len;
5335 		if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
5336 			err = -EFAULT;
5337 			goto exit;
5338 		}
5339 	} else { /* if args to set */
5340 		wrq_data->data.length = 0;
5341 	}
5342 
5343 exit:
5344 	kfree(input);
5345 	kfree(buffer);
5346 	kfree(output);
5347 
5348 	return err;
5349 }
5350 
5351 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5352 {
5353 	struct iwreq *wrq = (struct iwreq *)rq;
5354 	int ret = 0;
5355 
5356 	switch (cmd) {
5357 		case RTL_IOCTL_WPA_SUPPLICANT:
5358 			ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
5359 			break;
5360 		case RTL_IOCTL_HOSTAPD:
5361 			ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
5362 			break;
5363 		case SIOCDEVPRIVATE:
5364 			ret = rtw_ioctl_wext_private(dev, &wrq->u);
5365 			break;
5366 		default:
5367 			ret = -EOPNOTSUPP;
5368 			break;
5369 	}
5370 
5371 	return ret;
5372 }
5373