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