1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 
8 #include <linux/etherdevice.h>
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <rtw_mp.h>
12 #include <hal_btcoex.h>
13 #include <linux/jiffies.h>
14 #include <linux/kernel.h>
15 
16 #define RTL_IOCTL_WPA_SUPPLICANT	(SIOCIWFIRSTPRIV + 30)
17 
18 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
19 {
20 	struct adapter *padapter = rtw_netdev_priv(dev);
21 	int ret = 0;
22 
23 	if ((value & IW_AUTH_ALG_SHARED_KEY) && (value & IW_AUTH_ALG_OPEN_SYSTEM)) {
24 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
25 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
26 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
27 	} else if (value & IW_AUTH_ALG_SHARED_KEY)	{
28 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
29 
30 		padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
31 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
32 	} else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
33 		/* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
34 		if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
35 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
36 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
37 		}
38 	} else {
39 		ret = -EINVAL;
40 	}
41 
42 	return ret;
43 }
44 
45 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
46 {
47 	int ret = 0;
48 	u8 max_idx;
49 	u32 wep_key_idx, wep_key_len, wep_total_len;
50 	struct ndis_802_11_wep	 *pwep = NULL;
51 	struct adapter *padapter = rtw_netdev_priv(dev);
52 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
53 	struct security_priv *psecuritypriv = &padapter->securitypriv;
54 
55 	param->u.crypt.err = 0;
56 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
57 
58 	if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
59 		ret =  -EINVAL;
60 		goto exit;
61 	}
62 
63 	if (param->sta_addr[0] != 0xff || param->sta_addr[1] != 0xff ||
64 	    param->sta_addr[2] != 0xff || param->sta_addr[3] != 0xff ||
65 	    param->sta_addr[4] != 0xff || param->sta_addr[5] != 0xff) {
66 		ret = -EINVAL;
67 		goto exit;
68 	}
69 
70 	if (strcmp(param->u.crypt.alg, "WEP") == 0)
71 		max_idx = WEP_KEYS - 1;
72 	else
73 		max_idx = BIP_MAX_KEYID;
74 
75 	if (param->u.crypt.idx > max_idx) {
76 		netdev_err(dev, "Error crypt.idx %d > %d\n", param->u.crypt.idx, max_idx);
77 		ret = -EINVAL;
78 		goto exit;
79 	}
80 
81 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
82 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
83 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
84 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
85 
86 		wep_key_idx = param->u.crypt.idx;
87 		wep_key_len = param->u.crypt.key_len;
88 
89 		if (wep_key_len > 0) {
90 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
91 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
92 			/* Allocate a full structure to avoid potentially running off the end. */
93 			pwep = kzalloc(sizeof(*pwep), GFP_KERNEL);
94 			if (!pwep) {
95 				ret = -ENOMEM;
96 				goto exit;
97 			}
98 
99 			pwep->key_length = wep_key_len;
100 			pwep->length = wep_total_len;
101 
102 			if (wep_key_len == 13) {
103 				padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
104 				padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
105 			}
106 		} else {
107 			ret = -EINVAL;
108 			goto exit;
109 		}
110 
111 		pwep->key_index = wep_key_idx;
112 		pwep->key_index |= 0x80000000;
113 
114 		memcpy(pwep->key_material,  param->u.crypt.key, pwep->key_length);
115 
116 		if (param->u.crypt.set_tx) {
117 			if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
118 				ret = -EOPNOTSUPP;
119 		} else {
120 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
121 			/* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to fw/cam */
122 
123 			if (wep_key_idx >= WEP_KEYS) {
124 				ret = -EOPNOTSUPP;
125 				goto exit;
126 			}
127 
128 			memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->key_material, pwep->key_length);
129 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->key_length;
130 			rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true);
131 		}
132 
133 		goto exit;
134 	}
135 
136 	if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /*  802_1x */
137 		struct sta_info *psta, *pbcmc_sta;
138 		struct sta_priv *pstapriv = &padapter->stapriv;
139 
140 		if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) { /* sta mode */
141 			psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
142 			if (!psta) {
143 				/* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
144 			} else {
145 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
146 				if (strcmp(param->u.crypt.alg, "none") != 0)
147 					psta->ieee8021x_blocked = false;
148 
149 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
150 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled)) {
151 					psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
152 				}
153 
154 				if (param->u.crypt.set_tx == 1) { /* pairwise key */
155 					memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
156 
157 					if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
158 						/* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
159 						memcpy(psta->dot11tkiptxmickey.skey, &param->u.crypt.key[16], 8);
160 						memcpy(psta->dot11tkiprxmickey.skey, &param->u.crypt.key[24], 8);
161 
162 						padapter->securitypriv.busetkipkey = false;
163 						/* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
164 					}
165 
166 					rtw_setstakey_cmd(padapter, psta, true, true);
167 				} else { /* group key */
168 					if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
169 						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));
170 						/* only TKIP group key need to install this */
171 						if (param->u.crypt.key_len > 16) {
172 							memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[16], 8);
173 							memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[24], 8);
174 						}
175 						padapter->securitypriv.binstallGrpkey = true;
176 
177 						padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
178 
179 						rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, true);
180 					} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
181 						/* printk("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
182 						/* save the IGTK key, length 16 bytes */
183 						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));
184 						/*printk("IGTK key below:\n");
185 						for (no = 0;no<16;no++)
186 							printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
187 						printk("\n");*/
188 						padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
189 						padapter->securitypriv.binstallBIPkey = true;
190 					}
191 				}
192 			}
193 
194 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
195 			if (!pbcmc_sta) {
196 				/* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
197 			} else {
198 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
199 				if (strcmp(param->u.crypt.alg, "none") != 0)
200 					pbcmc_sta->ieee8021x_blocked = false;
201 
202 				if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
203 				    (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled)) {
204 					pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
205 				}
206 			}
207 		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
208 			/* adhoc mode */
209 		}
210 	}
211 
212 exit:
213 
214 	kfree(pwep);
215 	return ret;
216 }
217 
218 static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
219 {
220 	u8 *buf = NULL;
221 	int group_cipher = 0, pairwise_cipher = 0;
222 	int ret = 0;
223 	u8 null_addr[] = {0, 0, 0, 0, 0, 0};
224 
225 	if (ielen > MAX_WPA_IE_LEN || !pie) {
226 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
227 		if (!pie)
228 			return ret;
229 		else
230 			return -EINVAL;
231 	}
232 
233 	if (ielen) {
234 		buf = rtw_zmalloc(ielen);
235 		if (!buf) {
236 			ret =  -ENOMEM;
237 			goto exit;
238 		}
239 
240 		memcpy(buf, pie, ielen);
241 
242 		if (ielen < RSN_HEADER_LEN) {
243 			ret  = -1;
244 			goto exit;
245 		}
246 
247 		if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
248 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
249 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
250 			memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
251 		}
252 
253 		if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
254 			padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
255 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
256 			memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
257 		}
258 
259 		if (group_cipher == 0)
260 			group_cipher = WPA_CIPHER_NONE;
261 		if (pairwise_cipher == 0)
262 			pairwise_cipher = WPA_CIPHER_NONE;
263 
264 		switch (group_cipher) {
265 		case WPA_CIPHER_NONE:
266 			padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
267 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
268 			break;
269 		case WPA_CIPHER_WEP40:
270 			padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
271 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
272 			break;
273 		case WPA_CIPHER_TKIP:
274 			padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
275 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
276 			break;
277 		case WPA_CIPHER_CCMP:
278 			padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
279 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
280 			break;
281 		case WPA_CIPHER_WEP104:
282 			padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
283 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
284 			break;
285 		}
286 
287 		switch (pairwise_cipher) {
288 		case WPA_CIPHER_NONE:
289 			padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
290 			padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
291 			break;
292 		case WPA_CIPHER_WEP40:
293 			padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
294 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
295 			break;
296 		case WPA_CIPHER_TKIP:
297 			padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
298 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
299 			break;
300 		case WPA_CIPHER_CCMP:
301 			padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
302 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
303 			break;
304 		case WPA_CIPHER_WEP104:
305 			padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
306 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
307 			break;
308 		}
309 
310 		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
311 		{/* set wps_ie */
312 			u16 cnt = 0;
313 			u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
314 
315 			while (cnt < ielen) {
316 				eid = buf[cnt];
317 
318 				if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
319 					padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < MAX_WPS_IE_LEN) ? (buf[cnt + 1] + 2) : MAX_WPS_IE_LEN;
320 
321 					memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
322 
323 					set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
324 
325 					cnt += buf[cnt + 1] + 2;
326 
327 					break;
328 				} else {
329 					cnt += buf[cnt + 1] + 2; /* goto next */
330 				}
331 			}
332 		}
333 	}
334 
335 	/* TKIP and AES disallow multicast packets until installing group key */
336 	if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ ||
337 	    padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ ||
338 	    padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
339 		/* WPS open need to enable multicast */
340 		/*  check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true) */
341 		rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
342 
343 exit:
344 
345 	kfree(buf);
346 
347 	return ret;
348 }
349 
350 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
351 {
352 	uint ret = 0;
353 	struct adapter *padapter = rtw_netdev_priv(dev);
354 
355 	switch (name) {
356 	case IEEE_PARAM_WPA_ENABLED:
357 
358 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
359 
360 		/* ret = ieee80211_wpa_enable(ieee, value); */
361 
362 		switch ((value) & 0xff) {
363 		case 1: /* WPA */
364 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
365 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
366 			break;
367 		case 2: /* WPA2 */
368 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
369 			padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
370 			break;
371 		}
372 
373 		break;
374 
375 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
376 		/* ieee->tkip_countermeasures =value; */
377 		break;
378 
379 	case IEEE_PARAM_DROP_UNENCRYPTED:
380 	{
381 		/* HACK:
382 		 *
383 		 * wpa_supplicant calls set_wpa_enabled when the driver
384 		 * is loaded and unloaded, regardless of if WPA is being
385 		 * used.  No other calls are made which can be used to
386 		 * determine if encryption will be used or not prior to
387 		 * association being expected.  If encryption is not being
388 		 * used, drop_unencrypted is set to false, else true -- we
389 		 * can use this to determine if the CAP_PRIVACY_ON bit should
390 		 * be set.
391 		 */
392 		break;
393 	}
394 	case IEEE_PARAM_PRIVACY_INVOKED:
395 
396 		/* ieee->privacy_invoked =value; */
397 
398 		break;
399 
400 	case IEEE_PARAM_AUTH_ALGS:
401 
402 		ret = wpa_set_auth_algs(dev, value);
403 
404 		break;
405 
406 	case IEEE_PARAM_IEEE_802_1X:
407 
408 		/* ieee->ieee802_1x =value; */
409 
410 		break;
411 
412 	case IEEE_PARAM_WPAX_SELECT:
413 
414 		/*  added for WPA2 mixed mode */
415 		/*
416 		spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
417 		ieee->wpax_type_set = 1;
418 		ieee->wpax_type_notify = value;
419 		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
420 		*/
421 
422 		break;
423 
424 	default:
425 
426 		ret = -EOPNOTSUPP;
427 
428 		break;
429 	}
430 
431 	return ret;
432 }
433 
434 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
435 {
436 	int ret = 0;
437 	struct adapter *padapter = rtw_netdev_priv(dev);
438 
439 	switch (command) {
440 	case IEEE_MLME_STA_DEAUTH:
441 
442 		if (!rtw_set_802_11_disassociate(padapter))
443 			ret = -1;
444 
445 		break;
446 
447 	case IEEE_MLME_STA_DISASSOC:
448 
449 		if (!rtw_set_802_11_disassociate(padapter))
450 			ret = -1;
451 
452 		break;
453 
454 	default:
455 		ret = -EOPNOTSUPP;
456 		break;
457 	}
458 
459 	return ret;
460 }
461 
462 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
463 {
464 	struct ieee_param *param;
465 	uint ret = 0;
466 
467 	/* down(&ieee->wx_sem); */
468 
469 	if (!p->pointer || p->length != sizeof(struct ieee_param))
470 		return -EINVAL;
471 
472 	param = rtw_malloc(p->length);
473 	if (!param)
474 		return -ENOMEM;
475 
476 	if (copy_from_user(param, p->pointer, p->length)) {
477 		kfree(param);
478 		return -EFAULT;
479 	}
480 
481 	switch (param->cmd) {
482 	case IEEE_CMD_SET_WPA_PARAM:
483 		ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
484 		break;
485 
486 	case IEEE_CMD_SET_WPA_IE:
487 		/* ret = wpa_set_wpa_ie(dev, param, p->length); */
488 		ret =  rtw_set_wpa_ie(rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
489 		break;
490 
491 	case IEEE_CMD_SET_ENCRYPTION:
492 		ret = wpa_set_encryption(dev, param, p->length);
493 		break;
494 
495 	case IEEE_CMD_MLME:
496 		ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
497 		break;
498 
499 	default:
500 		ret = -EOPNOTSUPP;
501 		break;
502 	}
503 
504 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
505 		ret = -EFAULT;
506 
507 	kfree(param);
508 
509 	/* up(&ieee->wx_sem); */
510 	return ret;
511 }
512 
513 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
514 {
515 	int ret = 0;
516 	u32 wep_key_idx, wep_key_len, wep_total_len;
517 	struct ndis_802_11_wep	 *pwep = NULL;
518 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
519 	struct adapter *padapter = rtw_netdev_priv(dev);
520 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
521 	struct security_priv *psecuritypriv = &padapter->securitypriv;
522 	struct sta_priv *pstapriv = &padapter->stapriv;
523 	char *txkey = padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey;
524 	char *rxkey = padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey;
525 	char *grpkey = psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey;
526 
527 	param->u.crypt.err = 0;
528 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
529 
530 	/* sizeof(struct ieee_param) = 64 bytes; */
531 	/* if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
532 	if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
533 		ret =  -EINVAL;
534 		goto exit;
535 	}
536 
537 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
538 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
539 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
540 		if (param->u.crypt.idx >= WEP_KEYS) {
541 			ret = -EINVAL;
542 			goto exit;
543 		}
544 	} else {
545 		psta = rtw_get_stainfo(pstapriv, param->sta_addr);
546 		if (!psta)
547 			/* ret = -EINVAL; */
548 			goto exit;
549 	}
550 
551 	if (strcmp(param->u.crypt.alg, "none") == 0 && !psta) {
552 		/* todo:clear default encryption keys */
553 
554 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
555 		psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
556 		psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
557 		psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
558 
559 		goto exit;
560 	}
561 
562 	if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta) {
563 		wep_key_idx = param->u.crypt.idx;
564 		wep_key_len = param->u.crypt.key_len;
565 
566 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
567 			ret = -EINVAL;
568 			goto exit;
569 		}
570 
571 		if (wep_key_len > 0) {
572 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
573 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
574 			/* Allocate a full structure to avoid potentially running off the end. */
575 			pwep = kzalloc(sizeof(*pwep), GFP_KERNEL);
576 			if (!pwep)
577 				goto exit;
578 
579 			pwep->key_length = wep_key_len;
580 			pwep->length = wep_total_len;
581 		}
582 
583 		pwep->key_index = wep_key_idx;
584 
585 		memcpy(pwep->key_material,  param->u.crypt.key, pwep->key_length);
586 
587 		if (param->u.crypt.set_tx) {
588 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
589 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
590 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
591 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
592 
593 			if (pwep->key_length == 13) {
594 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
595 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
596 			}
597 
598 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
599 
600 			memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->key_material, pwep->key_length);
601 
602 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->key_length;
603 
604 			rtw_ap_set_wep_key(padapter, pwep->key_material, pwep->key_length, wep_key_idx, 1);
605 		} else {
606 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
607 			/* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to cam */
608 
609 			memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->key_material, pwep->key_length);
610 
611 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->key_length;
612 
613 			rtw_ap_set_wep_key(padapter, pwep->key_material, pwep->key_length, wep_key_idx, 0);
614 		}
615 
616 		goto exit;
617 	}
618 
619 	if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /*  group key */
620 		if (param->u.crypt.set_tx == 1) {
621 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
622 				memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
623 
624 				psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
625 				if (param->u.crypt.key_len == 13)
626 					psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
627 
628 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
629 				psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
630 
631 				memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
632 
633 				/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
634 				/* set mic key */
635 				memcpy(txkey, &param->u.crypt.key[16], 8);
636 				memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->u.crypt.key[24], 8);
637 
638 				psecuritypriv->busetkipkey = true;
639 
640 			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
641 				psecuritypriv->dot118021XGrpPrivacy = _AES_;
642 
643 				memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
644 			} else {
645 				psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
646 			}
647 
648 			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
649 
650 			psecuritypriv->binstallGrpkey = true;
651 
652 			psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
653 
654 			rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
655 
656 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
657 			if (pbcmc_sta) {
658 				pbcmc_sta->ieee8021x_blocked = false;
659 				pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
660 			}
661 		}
662 
663 		goto exit;
664 	}
665 
666 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /*  psk/802_1x */
667 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
668 			if (param->u.crypt.set_tx == 1)	{
669 				memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
670 
671 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
672 					psta->dot118021XPrivacy = _WEP40_;
673 					if (param->u.crypt.key_len == 13)
674 						psta->dot118021XPrivacy = _WEP104_;
675 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
676 					psta->dot118021XPrivacy = _TKIP_;
677 
678 					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
679 					/* set mic key */
680 					memcpy(psta->dot11tkiptxmickey.skey, &param->u.crypt.key[16], 8);
681 					memcpy(psta->dot11tkiprxmickey.skey, &param->u.crypt.key[24], 8);
682 
683 					psecuritypriv->busetkipkey = true;
684 
685 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
686 					psta->dot118021XPrivacy = _AES_;
687 				} else {
688 					psta->dot118021XPrivacy = _NO_PRIVACY_;
689 				}
690 
691 				rtw_ap_set_pairwise_key(padapter, psta);
692 
693 				psta->ieee8021x_blocked = false;
694 
695 			} else { /* group key??? */
696 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
697 					memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
698 
699 					psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
700 					if (param->u.crypt.key_len == 13)
701 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
702 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
703 					psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
704 
705 					memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
706 
707 					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
708 					/* set mic key */
709 					memcpy(txkey, &param->u.crypt.key[16], 8);
710 					memcpy(rxkey, &param->u.crypt.key[24], 8);
711 
712 					psecuritypriv->busetkipkey = true;
713 
714 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
715 					psecuritypriv->dot118021XGrpPrivacy = _AES_;
716 
717 					memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
718 				} else {
719 					psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
720 				}
721 
722 				psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
723 
724 				psecuritypriv->binstallGrpkey = true;
725 
726 				psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
727 
728 				rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
729 
730 				pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
731 				if (pbcmc_sta) {
732 					pbcmc_sta->ieee8021x_blocked = false;
733 					pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
734 				}
735 			}
736 		}
737 	}
738 
739 exit:
740 	kfree(pwep);
741 
742 	return ret;
743 }
744 
745 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
746 {
747 	int ret = 0;
748 	struct adapter *padapter = rtw_netdev_priv(dev);
749 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
750 	struct sta_priv *pstapriv = &padapter->stapriv;
751 	unsigned char *pbuf = param->u.bcn_ie.buf;
752 
753 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
754 		return -EINVAL;
755 
756 	memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
757 
758 	if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
759 		pstapriv->max_num_sta = NUM_STA;
760 
761 	if (rtw_check_beacon_data(padapter, pbuf,  (len - 12 - 2)) == _SUCCESS)/*  12 = param header, 2:no packed */
762 		ret = 0;
763 	else
764 		ret = -EINVAL;
765 
766 	return ret;
767 }
768 
769 static void rtw_hostapd_sta_flush(struct net_device *dev)
770 {
771 	/* _irqL irqL; */
772 	/* struct list_head	*phead, *plist; */
773 	/* struct sta_info *psta = NULL; */
774 	struct adapter *padapter = rtw_netdev_priv(dev);
775 	/* struct sta_priv *pstapriv = &padapter->stapriv; */
776 
777 	flush_all_cam_entry(padapter);	/* clear CAM */
778 
779 	rtw_sta_flush(padapter);
780 }
781 
782 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
783 {
784 	int ret = 0;
785 	struct sta_info *psta = NULL;
786 	struct adapter *padapter = rtw_netdev_priv(dev);
787 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
788 	struct sta_priv *pstapriv = &padapter->stapriv;
789 
790 	if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true)
791 		return -EINVAL;
792 
793 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
794 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
795 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
796 		return -EINVAL;
797 	}
798 
799 /*
800 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
801 	if (psta)
802 	{
803 		rtw_free_stainfo(padapter,  psta);
804 
805 		psta = NULL;
806 	}
807 */
808 	/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
809 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
810 	if (psta) {
811 		int flags = param->u.add_sta.flags;
812 
813 		psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */
814 
815 		memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
816 
817 		/* check wmm cap. */
818 		if (WLAN_STA_WME & flags)
819 			psta->qos_option = 1;
820 		else
821 			psta->qos_option = 0;
822 
823 		if (pmlmepriv->qospriv.qos_option == 0)
824 			psta->qos_option = 0;
825 
826 		/* chec 802.11n ht cap. */
827 		if (WLAN_STA_HT & flags) {
828 			psta->htpriv.ht_option = true;
829 			psta->qos_option = 1;
830 			memcpy((void *)&psta->htpriv.ht_cap, (void *)&param->u.add_sta.ht_cap, sizeof(struct ieee80211_ht_cap));
831 		} else {
832 			psta->htpriv.ht_option = false;
833 		}
834 
835 		if (!pmlmepriv->htpriv.ht_option)
836 			psta->htpriv.ht_option = false;
837 
838 		update_sta_info_apmode(padapter, psta);
839 
840 	} else {
841 		ret = -ENOMEM;
842 	}
843 
844 	return ret;
845 }
846 
847 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
848 {
849 	int ret = 0;
850 	struct sta_info *psta = NULL;
851 	struct adapter *padapter = rtw_netdev_priv(dev);
852 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
853 	struct sta_priv *pstapriv = &padapter->stapriv;
854 
855 	if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true)
856 		return -EINVAL;
857 
858 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
859 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
860 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
861 		return -EINVAL;
862 	}
863 
864 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
865 	if (psta) {
866 		u8 updated = false;
867 
868 		spin_lock_bh(&pstapriv->asoc_list_lock);
869 		if (list_empty(&psta->asoc_list) == false) {
870 			list_del_init(&psta->asoc_list);
871 			pstapriv->asoc_list_cnt--;
872 			updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
873 		}
874 		spin_unlock_bh(&pstapriv->asoc_list_lock);
875 
876 		associated_clients_update(padapter, updated);
877 
878 		psta = NULL;
879 	}
880 
881 	return ret;
882 }
883 
884 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
885 {
886 	int ret = 0;
887 	struct sta_info *psta = NULL;
888 	struct adapter *padapter = rtw_netdev_priv(dev);
889 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
890 	struct sta_priv *pstapriv = &padapter->stapriv;
891 	struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
892 	struct sta_data *psta_data = (struct sta_data *)param_ex->data;
893 
894 	if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true)
895 		return -EINVAL;
896 
897 	if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
898 	    param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
899 	    param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
900 		return -EINVAL;
901 	}
902 
903 	psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
904 	if (psta) {
905 		psta_data->aid = (u16)psta->aid;
906 		psta_data->capability = psta->capability;
907 		psta_data->flags = psta->flags;
908 
909 /*
910 		nonerp_set : BIT(0)
911 		no_short_slot_time_set : BIT(1)
912 		no_short_preamble_set : BIT(2)
913 		no_ht_gf_set : BIT(3)
914 		no_ht_set : BIT(4)
915 		ht_20mhz_set : BIT(5)
916 */
917 
918 		psta_data->sta_set = ((psta->nonerp_set) |
919 							 (psta->no_short_slot_time_set << 1) |
920 							 (psta->no_short_preamble_set << 2) |
921 							 (psta->no_ht_gf_set << 3) |
922 							 (psta->no_ht_set << 4) |
923 							 (psta->ht_20mhz_set << 5));
924 
925 		psta_data->tx_supp_rates_len =  psta->bssratelen;
926 		memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
927 		memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
928 		psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
929 		psta_data->rx_bytes = psta->sta_stats.rx_bytes;
930 		psta_data->rx_drops = psta->sta_stats.rx_drops;
931 
932 		psta_data->tx_pkts = psta->sta_stats.tx_pkts;
933 		psta_data->tx_bytes = psta->sta_stats.tx_bytes;
934 		psta_data->tx_drops = psta->sta_stats.tx_drops;
935 
936 	} else {
937 		ret = -1;
938 	}
939 
940 	return ret;
941 }
942 
943 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
944 {
945 	int ret = 0;
946 	struct sta_info *psta = NULL;
947 	struct adapter *padapter = rtw_netdev_priv(dev);
948 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
949 	struct sta_priv *pstapriv = &padapter->stapriv;
950 
951 	if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true)
952 		return -EINVAL;
953 
954 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
955 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
956 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
957 		return -EINVAL;
958 	}
959 
960 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
961 	if (psta) {
962 		if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC)) {
963 			int wpa_ie_len;
964 			int copy_len;
965 
966 			wpa_ie_len = psta->wpa_ie[1];
967 
968 			copy_len = ((wpa_ie_len + 2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len + 2);
969 
970 			param->u.wpa_ie.len = copy_len;
971 
972 			memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
973 		}
974 	} else {
975 		ret = -1;
976 	}
977 
978 	return ret;
979 }
980 
981 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
982 {
983 	int ret = 0;
984 	unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
985 	struct adapter *padapter = rtw_netdev_priv(dev);
986 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
987 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
988 	int ie_len;
989 
990 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
991 		return -EINVAL;
992 
993 	ie_len = len - 12 - 2;/*  12 = param header, 2:no packed */
994 
995 	kfree(pmlmepriv->wps_beacon_ie);
996 	pmlmepriv->wps_beacon_ie = NULL;
997 
998 	if (ie_len > 0) {
999 		pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
1000 		pmlmepriv->wps_beacon_ie_len = ie_len;
1001 		if (!pmlmepriv->wps_beacon_ie)
1002 			return -EINVAL;
1003 
1004 		memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
1005 
1006 		update_beacon(padapter, WLAN_EID_VENDOR_SPECIFIC, wps_oui, true);
1007 
1008 		pmlmeext->bstart_bss = true;
1009 	}
1010 
1011 	return ret;
1012 }
1013 
1014 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
1015 {
1016 	int ret = 0;
1017 	struct adapter *padapter = rtw_netdev_priv(dev);
1018 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1019 	int ie_len;
1020 
1021 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1022 		return -EINVAL;
1023 
1024 	ie_len = len - 12 - 2;/*  12 = param header, 2:no packed */
1025 
1026 	kfree(pmlmepriv->wps_probe_resp_ie);
1027 	pmlmepriv->wps_probe_resp_ie = NULL;
1028 
1029 	if (ie_len > 0) {
1030 		pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
1031 		pmlmepriv->wps_probe_resp_ie_len = ie_len;
1032 		if (!pmlmepriv->wps_probe_resp_ie)
1033 			return -EINVAL;
1034 
1035 		memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
1036 	}
1037 
1038 	return ret;
1039 }
1040 
1041 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
1042 {
1043 	int ret = 0;
1044 	struct adapter *padapter = rtw_netdev_priv(dev);
1045 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1046 	int ie_len;
1047 
1048 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1049 		return -EINVAL;
1050 
1051 	ie_len = len - 12 - 2;/*  12 = param header, 2:no packed */
1052 
1053 	kfree(pmlmepriv->wps_assoc_resp_ie);
1054 	pmlmepriv->wps_assoc_resp_ie = NULL;
1055 
1056 	if (ie_len > 0) {
1057 		pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
1058 		pmlmepriv->wps_assoc_resp_ie_len = ie_len;
1059 		if (!pmlmepriv->wps_assoc_resp_ie)
1060 			return -EINVAL;
1061 
1062 		memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
1063 	}
1064 
1065 	return ret;
1066 }
1067 
1068 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
1069 {
1070 	int ret = 0;
1071 	struct adapter *adapter = rtw_netdev_priv(dev);
1072 	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1073 	struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
1074 	struct mlme_ext_info *mlmeinfo = &mlmeext->mlmext_info;
1075 	int ie_len;
1076 	u8 *ssid_ie;
1077 	char ssid[NDIS_802_11_LENGTH_SSID + 1];
1078 	signed int ssid_len;
1079 	u8 ignore_broadcast_ssid;
1080 
1081 	if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true)
1082 		return -EPERM;
1083 
1084 	if (param->u.bcn_ie.reserved[0] != 0xea)
1085 		return -EINVAL;
1086 
1087 	mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
1088 
1089 	ie_len = len - 12 - 2;/*  12 = param header, 2:no packed */
1090 	ssid_ie = rtw_get_ie(param->u.bcn_ie.buf,  WLAN_EID_SSID, &ssid_len, ie_len);
1091 
1092 	if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
1093 		struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network;
1094 		struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network;
1095 
1096 		memcpy(ssid, ssid_ie + 2, ssid_len);
1097 		ssid[ssid_len] = 0x0;
1098 
1099 		memcpy(pbss_network->ssid.ssid, (void *)ssid, ssid_len);
1100 		pbss_network->ssid.ssid_length = ssid_len;
1101 		memcpy(pbss_network_ext->ssid.ssid, (void *)ssid, ssid_len);
1102 		pbss_network_ext->ssid.ssid_length = ssid_len;
1103 	}
1104 
1105 	return ret;
1106 }
1107 
1108 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
1109 {
1110 	struct adapter *padapter = rtw_netdev_priv(dev);
1111 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1112 
1113 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1114 		return -EINVAL;
1115 
1116 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1117 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1118 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
1119 		return -EINVAL;
1120 	}
1121 
1122 	rtw_acl_remove_sta(padapter, param->sta_addr);
1123 	return 0;
1124 }
1125 
1126 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
1127 {
1128 	struct adapter *padapter = rtw_netdev_priv(dev);
1129 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1130 
1131 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1132 		return -EINVAL;
1133 
1134 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1135 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1136 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
1137 		return -EINVAL;
1138 	}
1139 
1140 	return rtw_acl_add_sta(padapter, param->sta_addr);
1141 }
1142 
1143 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
1144 {
1145 	int ret = 0;
1146 	struct adapter *padapter = rtw_netdev_priv(dev);
1147 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1148 
1149 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1150 		return -EINVAL;
1151 
1152 	rtw_set_macaddr_acl(padapter, param->u.mlme.command);
1153 
1154 	return ret;
1155 }
1156 
1157 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
1158 {
1159 	struct ieee_param *param;
1160 	int ret = 0;
1161 	struct adapter *padapter = rtw_netdev_priv(dev);
1162 
1163 	/*
1164 	 * this function is expect to call in master mode, which allows no power saving
1165 	 * so, we just check hw_init_completed
1166 	 */
1167 
1168 	if (!padapter->hw_init_completed)
1169 		return -EPERM;
1170 
1171 	if (!p->pointer || p->length != sizeof(*param))
1172 		return -EINVAL;
1173 
1174 	param = rtw_malloc(p->length);
1175 	if (!param)
1176 		return -ENOMEM;
1177 
1178 	if (copy_from_user(param, p->pointer, p->length)) {
1179 		kfree(param);
1180 		return -EFAULT;
1181 	}
1182 
1183 	switch (param->cmd) {
1184 	case RTL871X_HOSTAPD_FLUSH:
1185 
1186 		rtw_hostapd_sta_flush(dev);
1187 
1188 		break;
1189 
1190 	case RTL871X_HOSTAPD_ADD_STA:
1191 
1192 		ret = rtw_add_sta(dev, param);
1193 
1194 		break;
1195 
1196 	case RTL871X_HOSTAPD_REMOVE_STA:
1197 
1198 		ret = rtw_del_sta(dev, param);
1199 
1200 		break;
1201 
1202 	case RTL871X_HOSTAPD_SET_BEACON:
1203 
1204 		ret = rtw_set_beacon(dev, param, p->length);
1205 
1206 		break;
1207 
1208 	case RTL871X_SET_ENCRYPTION:
1209 
1210 		ret = rtw_set_encryption(dev, param, p->length);
1211 
1212 		break;
1213 
1214 	case RTL871X_HOSTAPD_GET_WPAIE_STA:
1215 
1216 		ret = rtw_get_sta_wpaie(dev, param);
1217 
1218 		break;
1219 
1220 	case RTL871X_HOSTAPD_SET_WPS_BEACON:
1221 
1222 		ret = rtw_set_wps_beacon(dev, param, p->length);
1223 
1224 		break;
1225 
1226 	case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
1227 
1228 		ret = rtw_set_wps_probe_resp(dev, param, p->length);
1229 
1230 		break;
1231 
1232 	case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
1233 
1234 		ret = rtw_set_wps_assoc_resp(dev, param, p->length);
1235 
1236 		break;
1237 
1238 	case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
1239 
1240 		ret = rtw_set_hidden_ssid(dev, param, p->length);
1241 
1242 		break;
1243 
1244 	case RTL871X_HOSTAPD_GET_INFO_STA:
1245 
1246 		ret = rtw_ioctl_get_sta_data(dev, param, p->length);
1247 
1248 		break;
1249 
1250 	case RTL871X_HOSTAPD_SET_MACADDR_ACL:
1251 
1252 		ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
1253 
1254 		break;
1255 
1256 	case RTL871X_HOSTAPD_ACL_ADD_STA:
1257 
1258 		ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
1259 
1260 		break;
1261 
1262 	case RTL871X_HOSTAPD_ACL_REMOVE_STA:
1263 
1264 		ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
1265 
1266 		break;
1267 
1268 	default:
1269 		ret = -EOPNOTSUPP;
1270 		break;
1271 	}
1272 
1273 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
1274 		ret = -EFAULT;
1275 
1276 	kfree(param);
1277 	return ret;
1278 }
1279 
1280 /*  copy from net/wireless/wext.c end */
1281 
1282 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1283 {
1284 	struct iwreq *wrq = (struct iwreq *)rq;
1285 	int ret = 0;
1286 
1287 	switch (cmd) {
1288 	case RTL_IOCTL_WPA_SUPPLICANT:
1289 		ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
1290 		break;
1291 	case RTL_IOCTL_HOSTAPD:
1292 		ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
1293 		break;
1294 	default:
1295 		ret = -EOPNOTSUPP;
1296 		break;
1297 	}
1298 
1299 	return ret;
1300 }
1301