xref: /linux/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c (revision 164666fa66669d437bdcc8d5f1744a2aee73be41)
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 
46 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
47 {
48 	int ret = 0;
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 		if (param->u.crypt.idx >= WEP_KEYS ||
67 		    param->u.crypt.idx >= BIP_MAX_KEYID) {
68 			ret = -EINVAL;
69 			goto exit;
70 		}
71 	} else {
72 		{
73 			ret = -EINVAL;
74 			goto exit;
75 		}
76 	}
77 
78 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
79 
80 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
81 		padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
82 		padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
83 
84 		wep_key_idx = param->u.crypt.idx;
85 		wep_key_len = param->u.crypt.key_len;
86 
87 		if (wep_key_idx > WEP_KEYS)
88 			return -EINVAL;
89 
90 		if (wep_key_len > 0) {
91 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
92 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
93 			pwep = kzalloc(wep_total_len, 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 	}
395 	case IEEE_PARAM_PRIVACY_INVOKED:
396 
397 		/* ieee->privacy_invoked =value; */
398 
399 		break;
400 
401 	case IEEE_PARAM_AUTH_ALGS:
402 
403 		ret = wpa_set_auth_algs(dev, value);
404 
405 		break;
406 
407 	case IEEE_PARAM_IEEE_802_1X:
408 
409 		/* ieee->ieee802_1x =value; */
410 
411 		break;
412 
413 	case IEEE_PARAM_WPAX_SELECT:
414 
415 		/*  added for WPA2 mixed mode */
416 		/*
417 		spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
418 		ieee->wpax_type_set = 1;
419 		ieee->wpax_type_notify = value;
420 		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
421 		*/
422 
423 		break;
424 
425 	default:
426 
427 
428 
429 		ret = -EOPNOTSUPP;
430 
431 
432 		break;
433 
434 	}
435 
436 	return ret;
437 
438 }
439 
440 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
441 {
442 	int ret = 0;
443 	struct adapter *padapter = rtw_netdev_priv(dev);
444 
445 	switch (command) {
446 	case IEEE_MLME_STA_DEAUTH:
447 
448 		if (!rtw_set_802_11_disassociate(padapter))
449 			ret = -1;
450 
451 		break;
452 
453 	case IEEE_MLME_STA_DISASSOC:
454 
455 		if (!rtw_set_802_11_disassociate(padapter))
456 			ret = -1;
457 
458 		break;
459 
460 	default:
461 		ret = -EOPNOTSUPP;
462 		break;
463 	}
464 
465 	return ret;
466 
467 }
468 
469 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
470 {
471 	struct ieee_param *param;
472 	uint ret = 0;
473 
474 	/* down(&ieee->wx_sem); */
475 
476 	if (!p->pointer || p->length != sizeof(struct ieee_param))
477 		return -EINVAL;
478 
479 	param = rtw_malloc(p->length);
480 	if (!param)
481 		return -ENOMEM;
482 
483 	if (copy_from_user(param, p->pointer, p->length)) {
484 		kfree(param);
485 		return -EFAULT;
486 	}
487 
488 	switch (param->cmd) {
489 
490 	case IEEE_CMD_SET_WPA_PARAM:
491 		ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
492 		break;
493 
494 	case IEEE_CMD_SET_WPA_IE:
495 		/* ret = wpa_set_wpa_ie(dev, param, p->length); */
496 		ret =  rtw_set_wpa_ie(rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
497 		break;
498 
499 	case IEEE_CMD_SET_ENCRYPTION:
500 		ret = wpa_set_encryption(dev, param, p->length);
501 		break;
502 
503 	case IEEE_CMD_MLME:
504 		ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
505 		break;
506 
507 	default:
508 		ret = -EOPNOTSUPP;
509 		break;
510 
511 	}
512 
513 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
514 		ret = -EFAULT;
515 
516 	kfree(param);
517 
518 	/* up(&ieee->wx_sem); */
519 	return ret;
520 }
521 
522 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
523 {
524 	int ret = 0;
525 	u32 wep_key_idx, wep_key_len, wep_total_len;
526 	struct ndis_802_11_wep	 *pwep = NULL;
527 	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
528 	struct adapter *padapter = rtw_netdev_priv(dev);
529 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
530 	struct security_priv *psecuritypriv = &(padapter->securitypriv);
531 	struct sta_priv *pstapriv = &padapter->stapriv;
532 	char *txkey = padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey;
533 	char *rxkey = padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey;
534 	char *grpkey = psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey;
535 
536 	param->u.crypt.err = 0;
537 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
538 
539 	/* sizeof(struct ieee_param) = 64 bytes; */
540 	/* if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
541 	if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
542 		ret =  -EINVAL;
543 		goto exit;
544 	}
545 
546 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
547 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
548 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
549 		if (param->u.crypt.idx >= WEP_KEYS) {
550 			ret = -EINVAL;
551 			goto exit;
552 		}
553 	} else {
554 		psta = rtw_get_stainfo(pstapriv, param->sta_addr);
555 		if (!psta)
556 			/* ret = -EINVAL; */
557 			goto exit;
558 	}
559 
560 	if (strcmp(param->u.crypt.alg, "none") == 0 && !psta) {
561 		/* todo:clear default encryption keys */
562 
563 		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
564 		psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
565 		psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
566 		psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
567 
568 		goto exit;
569 	}
570 
571 
572 	if (strcmp(param->u.crypt.alg, "WEP") == 0 && !psta) {
573 		wep_key_idx = param->u.crypt.idx;
574 		wep_key_len = param->u.crypt.key_len;
575 
576 		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
577 			ret = -EINVAL;
578 			goto exit;
579 		}
580 
581 
582 		if (wep_key_len > 0) {
583 			wep_key_len = wep_key_len <= 5 ? 5 : 13;
584 			wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, key_material);
585 			pwep = kzalloc(wep_total_len, GFP_KERNEL);
586 			if (!pwep)
587 				goto exit;
588 
589 			pwep->key_length = wep_key_len;
590 			pwep->length = wep_total_len;
591 
592 		}
593 
594 		pwep->key_index = wep_key_idx;
595 
596 		memcpy(pwep->key_material,  param->u.crypt.key, pwep->key_length);
597 
598 		if (param->u.crypt.set_tx) {
599 			psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
600 			psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
601 			psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
602 			psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
603 
604 			if (pwep->key_length == 13) {
605 				psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
606 				psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
607 			}
608 
609 
610 			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
611 
612 			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->key_material, pwep->key_length);
613 
614 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->key_length;
615 
616 			rtw_ap_set_wep_key(padapter, pwep->key_material, pwep->key_length, wep_key_idx, 1);
617 		} else {
618 			/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
619 			/* psecuritypriv->dot11PrivacyKeyIndex =keyid", but can rtw_set_key to cam */
620 
621 			memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->key_material, pwep->key_length);
622 
623 			psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->key_length;
624 
625 			rtw_ap_set_wep_key(padapter, pwep->key_material, pwep->key_length, wep_key_idx, 0);
626 		}
627 
628 		goto exit;
629 
630 	}
631 
632 
633 	if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /*  group key */
634 		if (param->u.crypt.set_tx == 1) {
635 			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
636 				memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
637 
638 				psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
639 				if (param->u.crypt.key_len == 13)
640 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
641 
642 			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
643 				psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
644 
645 				memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
646 
647 				/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
648 				/* set mic key */
649 				memcpy(txkey, &(param->u.crypt.key[16]), 8);
650 				memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
651 
652 				psecuritypriv->busetkipkey = true;
653 
654 			}
655 			else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
656 				psecuritypriv->dot118021XGrpPrivacy = _AES_;
657 
658 				memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
659 			} else {
660 				psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
661 			}
662 
663 			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
664 
665 			psecuritypriv->binstallGrpkey = true;
666 
667 			psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
668 
669 			rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
670 
671 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
672 			if (pbcmc_sta) {
673 				pbcmc_sta->ieee8021x_blocked = false;
674 				pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
675 			}
676 		}
677 
678 		goto exit;
679 
680 	}
681 
682 	if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /*  psk/802_1x */
683 		if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
684 			if (param->u.crypt.set_tx == 1)	{
685 				memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
686 
687 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
688 					psta->dot118021XPrivacy = _WEP40_;
689 					if (param->u.crypt.key_len == 13)
690 						psta->dot118021XPrivacy = _WEP104_;
691 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
692 					psta->dot118021XPrivacy = _TKIP_;
693 
694 					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
695 					/* set mic key */
696 					memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
697 					memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
698 
699 					psecuritypriv->busetkipkey = true;
700 
701 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
702 
703 					psta->dot118021XPrivacy = _AES_;
704 				} else {
705 					psta->dot118021XPrivacy = _NO_PRIVACY_;
706 				}
707 
708 				rtw_ap_set_pairwise_key(padapter, psta);
709 
710 				psta->ieee8021x_blocked = false;
711 
712 			} else { /* group key??? */
713 				if (strcmp(param->u.crypt.alg, "WEP") == 0) {
714 					memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
715 
716 					psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
717 					if (param->u.crypt.key_len == 13)
718 						psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
719 				} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
720 					psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
721 
722 					memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
723 
724 					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
725 					/* set mic key */
726 					memcpy(txkey, &(param->u.crypt.key[16]), 8);
727 					memcpy(rxkey, &(param->u.crypt.key[24]), 8);
728 
729 					psecuritypriv->busetkipkey = true;
730 
731 				} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
732 					psecuritypriv->dot118021XGrpPrivacy = _AES_;
733 
734 					memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
735 				} else {
736 					psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
737 				}
738 
739 				psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
740 
741 				psecuritypriv->binstallGrpkey = true;
742 
743 				psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
744 
745 				rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
746 
747 				pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
748 				if (pbcmc_sta) {
749 					pbcmc_sta->ieee8021x_blocked = false;
750 					pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
751 				}
752 			}
753 		}
754 	}
755 
756 exit:
757 	kfree(pwep);
758 
759 	return ret;
760 
761 }
762 
763 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
764 {
765 	int ret = 0;
766 	struct adapter *padapter = rtw_netdev_priv(dev);
767 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
768 	struct sta_priv *pstapriv = &padapter->stapriv;
769 	unsigned char *pbuf = param->u.bcn_ie.buf;
770 
771 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
772 		return -EINVAL;
773 
774 	memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
775 
776 	if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
777 		pstapriv->max_num_sta = NUM_STA;
778 
779 
780 	if (rtw_check_beacon_data(padapter, pbuf,  (len-12-2)) == _SUCCESS)/*  12 = param header, 2:no packed */
781 		ret = 0;
782 	else
783 		ret = -EINVAL;
784 
785 
786 	return ret;
787 
788 }
789 
790 static void rtw_hostapd_sta_flush(struct net_device *dev)
791 {
792 	/* _irqL irqL; */
793 	/* struct list_head	*phead, *plist; */
794 	/* struct sta_info *psta = NULL; */
795 	struct adapter *padapter = rtw_netdev_priv(dev);
796 	/* struct sta_priv *pstapriv = &padapter->stapriv; */
797 
798 	flush_all_cam_entry(padapter);	/* clear CAM */
799 
800 	rtw_sta_flush(padapter);
801 }
802 
803 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
804 {
805 	int ret = 0;
806 	struct sta_info *psta = NULL;
807 	struct adapter *padapter = rtw_netdev_priv(dev);
808 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
809 	struct sta_priv *pstapriv = &padapter->stapriv;
810 
811 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
812 		return -EINVAL;
813 
814 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
815 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
816 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
817 		return -EINVAL;
818 	}
819 
820 /*
821 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
822 	if (psta)
823 	{
824 		rtw_free_stainfo(padapter,  psta);
825 
826 		psta = NULL;
827 	}
828 */
829 	/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
830 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
831 	if (psta) {
832 		int flags = param->u.add_sta.flags;
833 
834 		psta->aid = param->u.add_sta.aid;/* aid = 1~2007 */
835 
836 		memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
837 
838 
839 		/* check wmm cap. */
840 		if (WLAN_STA_WME&flags)
841 			psta->qos_option = 1;
842 		else
843 			psta->qos_option = 0;
844 
845 		if (pmlmepriv->qospriv.qos_option == 0)
846 			psta->qos_option = 0;
847 
848 		/* chec 802.11n ht cap. */
849 		if (WLAN_STA_HT&flags) {
850 			psta->htpriv.ht_option = true;
851 			psta->qos_option = 1;
852 			memcpy((void *)&psta->htpriv.ht_cap, (void *)&param->u.add_sta.ht_cap, sizeof(struct ieee80211_ht_cap));
853 		} else {
854 			psta->htpriv.ht_option = false;
855 		}
856 
857 		if (pmlmepriv->htpriv.ht_option == false)
858 			psta->htpriv.ht_option = false;
859 
860 		update_sta_info_apmode(padapter, psta);
861 
862 
863 	} else {
864 		ret = -ENOMEM;
865 	}
866 
867 	return ret;
868 
869 }
870 
871 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
872 {
873 	int ret = 0;
874 	struct sta_info *psta = NULL;
875 	struct adapter *padapter = rtw_netdev_priv(dev);
876 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
877 	struct sta_priv *pstapriv = &padapter->stapriv;
878 
879 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
880 		return -EINVAL;
881 
882 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
883 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
884 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
885 		return -EINVAL;
886 	}
887 
888 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
889 	if (psta) {
890 		u8 updated = false;
891 
892 		spin_lock_bh(&pstapriv->asoc_list_lock);
893 		if (list_empty(&psta->asoc_list) == false) {
894 			list_del_init(&psta->asoc_list);
895 			pstapriv->asoc_list_cnt--;
896 			updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
897 
898 		}
899 		spin_unlock_bh(&pstapriv->asoc_list_lock);
900 
901 		associated_clients_update(padapter, updated);
902 
903 		psta = NULL;
904 
905 	}
906 
907 	return ret;
908 
909 }
910 
911 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
912 {
913 	int ret = 0;
914 	struct sta_info *psta = NULL;
915 	struct adapter *padapter = rtw_netdev_priv(dev);
916 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
917 	struct sta_priv *pstapriv = &padapter->stapriv;
918 	struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
919 	struct sta_data *psta_data = (struct sta_data *)param_ex->data;
920 
921 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
922 		return -EINVAL;
923 
924 	if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
925 	    param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
926 	    param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
927 		return -EINVAL;
928 	}
929 
930 	psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
931 	if (psta) {
932 		psta_data->aid = (u16)psta->aid;
933 		psta_data->capability = psta->capability;
934 		psta_data->flags = psta->flags;
935 
936 /*
937 		nonerp_set : BIT(0)
938 		no_short_slot_time_set : BIT(1)
939 		no_short_preamble_set : BIT(2)
940 		no_ht_gf_set : BIT(3)
941 		no_ht_set : BIT(4)
942 		ht_20mhz_set : BIT(5)
943 */
944 
945 		psta_data->sta_set = ((psta->nonerp_set) |
946 							 (psta->no_short_slot_time_set << 1) |
947 							 (psta->no_short_preamble_set << 2) |
948 							 (psta->no_ht_gf_set << 3) |
949 							 (psta->no_ht_set << 4) |
950 							 (psta->ht_20mhz_set << 5));
951 
952 		psta_data->tx_supp_rates_len =  psta->bssratelen;
953 		memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
954 		memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
955 		psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
956 		psta_data->rx_bytes = psta->sta_stats.rx_bytes;
957 		psta_data->rx_drops = psta->sta_stats.rx_drops;
958 
959 		psta_data->tx_pkts = psta->sta_stats.tx_pkts;
960 		psta_data->tx_bytes = psta->sta_stats.tx_bytes;
961 		psta_data->tx_drops = psta->sta_stats.tx_drops;
962 
963 
964 	} else {
965 		ret = -1;
966 	}
967 
968 	return ret;
969 
970 }
971 
972 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
973 {
974 	int ret = 0;
975 	struct sta_info *psta = NULL;
976 	struct adapter *padapter = rtw_netdev_priv(dev);
977 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
978 	struct sta_priv *pstapriv = &padapter->stapriv;
979 
980 	if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
981 		return -EINVAL;
982 
983 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
984 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
985 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
986 		return -EINVAL;
987 	}
988 
989 	psta = rtw_get_stainfo(pstapriv, param->sta_addr);
990 	if (psta) {
991 		if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC)) {
992 			int wpa_ie_len;
993 			int copy_len;
994 
995 			wpa_ie_len = psta->wpa_ie[1];
996 
997 			copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
998 
999 			param->u.wpa_ie.len = copy_len;
1000 
1001 			memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
1002 		}
1003 	} else {
1004 		ret = -1;
1005 	}
1006 
1007 	return ret;
1008 
1009 }
1010 
1011 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
1012 {
1013 	int ret = 0;
1014 	unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
1015 	struct adapter *padapter = rtw_netdev_priv(dev);
1016 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1017 	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1018 	int ie_len;
1019 
1020 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1021 		return -EINVAL;
1022 
1023 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
1024 
1025 
1026 	kfree(pmlmepriv->wps_beacon_ie);
1027 	pmlmepriv->wps_beacon_ie = NULL;
1028 
1029 	if (ie_len > 0) {
1030 		pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
1031 		pmlmepriv->wps_beacon_ie_len = ie_len;
1032 		if (!pmlmepriv->wps_beacon_ie)
1033 			return -EINVAL;
1034 
1035 		memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
1036 
1037 		update_beacon(padapter, WLAN_EID_VENDOR_SPECIFIC, wps_oui, true);
1038 
1039 		pmlmeext->bstart_bss = true;
1040 	}
1041 
1042 
1043 	return ret;
1044 
1045 }
1046 
1047 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
1048 {
1049 	int ret = 0;
1050 	struct adapter *padapter = rtw_netdev_priv(dev);
1051 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1052 	int ie_len;
1053 
1054 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1055 		return -EINVAL;
1056 
1057 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
1058 
1059 
1060 	kfree(pmlmepriv->wps_probe_resp_ie);
1061 	pmlmepriv->wps_probe_resp_ie = NULL;
1062 
1063 	if (ie_len > 0) {
1064 		pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
1065 		pmlmepriv->wps_probe_resp_ie_len = ie_len;
1066 		if (!pmlmepriv->wps_probe_resp_ie)
1067 			return -EINVAL;
1068 
1069 		memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
1070 	}
1071 
1072 
1073 	return ret;
1074 
1075 }
1076 
1077 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
1078 {
1079 	int ret = 0;
1080 	struct adapter *padapter = rtw_netdev_priv(dev);
1081 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1082 	int ie_len;
1083 
1084 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1085 		return -EINVAL;
1086 
1087 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
1088 
1089 
1090 	kfree(pmlmepriv->wps_assoc_resp_ie);
1091 	pmlmepriv->wps_assoc_resp_ie = NULL;
1092 
1093 	if (ie_len > 0) {
1094 		pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
1095 		pmlmepriv->wps_assoc_resp_ie_len = ie_len;
1096 		if (!pmlmepriv->wps_assoc_resp_ie)
1097 			return -EINVAL;
1098 
1099 		memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
1100 	}
1101 
1102 
1103 	return ret;
1104 
1105 }
1106 
1107 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
1108 {
1109 	int ret = 0;
1110 	struct adapter *adapter = rtw_netdev_priv(dev);
1111 	struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
1112 	struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
1113 	struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
1114 	int ie_len;
1115 	u8 *ssid_ie;
1116 	char ssid[NDIS_802_11_LENGTH_SSID + 1];
1117 	signed int ssid_len;
1118 	u8 ignore_broadcast_ssid;
1119 
1120 	if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true)
1121 		return -EPERM;
1122 
1123 	if (param->u.bcn_ie.reserved[0] != 0xea)
1124 		return -EINVAL;
1125 
1126 	mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
1127 
1128 	ie_len = len-12-2;/*  12 = param header, 2:no packed */
1129 	ssid_ie = rtw_get_ie(param->u.bcn_ie.buf,  WLAN_EID_SSID, &ssid_len, ie_len);
1130 
1131 	if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
1132 		struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network;
1133 		struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network;
1134 
1135 		memcpy(ssid, ssid_ie+2, ssid_len);
1136 		ssid[ssid_len] = 0x0;
1137 
1138 		memcpy(pbss_network->ssid.ssid, (void *)ssid, ssid_len);
1139 		pbss_network->ssid.ssid_length = ssid_len;
1140 		memcpy(pbss_network_ext->ssid.ssid, (void *)ssid, ssid_len);
1141 		pbss_network_ext->ssid.ssid_length = ssid_len;
1142 	}
1143 
1144 	return ret;
1145 }
1146 
1147 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
1148 {
1149 	struct adapter *padapter = rtw_netdev_priv(dev);
1150 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1151 
1152 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1153 		return -EINVAL;
1154 
1155 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1156 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1157 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
1158 		return -EINVAL;
1159 	}
1160 
1161 	rtw_acl_remove_sta(padapter, param->sta_addr);
1162 	return 0;
1163 
1164 }
1165 
1166 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
1167 {
1168 	struct adapter *padapter = rtw_netdev_priv(dev);
1169 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1170 
1171 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1172 		return -EINVAL;
1173 
1174 	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1175 	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1176 	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
1177 		return -EINVAL;
1178 	}
1179 
1180 	return rtw_acl_add_sta(padapter, param->sta_addr);
1181 
1182 }
1183 
1184 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
1185 {
1186 	int ret = 0;
1187 	struct adapter *padapter = rtw_netdev_priv(dev);
1188 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1189 
1190 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
1191 		return -EINVAL;
1192 
1193 	rtw_set_macaddr_acl(padapter, param->u.mlme.command);
1194 
1195 	return ret;
1196 }
1197 
1198 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
1199 {
1200 	struct ieee_param *param;
1201 	int ret = 0;
1202 	struct adapter *padapter = rtw_netdev_priv(dev);
1203 
1204 	/*
1205 	* this function is expect to call in master mode, which allows no power saving
1206 	* so, we just check hw_init_completed
1207 	*/
1208 
1209 	if (!padapter->hw_init_completed)
1210 		return -EPERM;
1211 
1212 	if (!p->pointer || p->length != sizeof(*param))
1213 		return -EINVAL;
1214 
1215 	param = rtw_malloc(p->length);
1216 	if (!param)
1217 		return -ENOMEM;
1218 
1219 	if (copy_from_user(param, p->pointer, p->length)) {
1220 		kfree(param);
1221 		return -EFAULT;
1222 	}
1223 
1224 	switch (param->cmd) {
1225 	case RTL871X_HOSTAPD_FLUSH:
1226 
1227 		rtw_hostapd_sta_flush(dev);
1228 
1229 		break;
1230 
1231 	case RTL871X_HOSTAPD_ADD_STA:
1232 
1233 		ret = rtw_add_sta(dev, param);
1234 
1235 		break;
1236 
1237 	case RTL871X_HOSTAPD_REMOVE_STA:
1238 
1239 		ret = rtw_del_sta(dev, param);
1240 
1241 		break;
1242 
1243 	case RTL871X_HOSTAPD_SET_BEACON:
1244 
1245 		ret = rtw_set_beacon(dev, param, p->length);
1246 
1247 		break;
1248 
1249 	case RTL871X_SET_ENCRYPTION:
1250 
1251 		ret = rtw_set_encryption(dev, param, p->length);
1252 
1253 		break;
1254 
1255 	case RTL871X_HOSTAPD_GET_WPAIE_STA:
1256 
1257 		ret = rtw_get_sta_wpaie(dev, param);
1258 
1259 		break;
1260 
1261 	case RTL871X_HOSTAPD_SET_WPS_BEACON:
1262 
1263 		ret = rtw_set_wps_beacon(dev, param, p->length);
1264 
1265 		break;
1266 
1267 	case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
1268 
1269 		ret = rtw_set_wps_probe_resp(dev, param, p->length);
1270 
1271 		break;
1272 
1273 	case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
1274 
1275 		ret = rtw_set_wps_assoc_resp(dev, param, p->length);
1276 
1277 		break;
1278 
1279 	case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
1280 
1281 		ret = rtw_set_hidden_ssid(dev, param, p->length);
1282 
1283 		break;
1284 
1285 	case RTL871X_HOSTAPD_GET_INFO_STA:
1286 
1287 		ret = rtw_ioctl_get_sta_data(dev, param, p->length);
1288 
1289 		break;
1290 
1291 	case RTL871X_HOSTAPD_SET_MACADDR_ACL:
1292 
1293 		ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
1294 
1295 		break;
1296 
1297 	case RTL871X_HOSTAPD_ACL_ADD_STA:
1298 
1299 		ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
1300 
1301 		break;
1302 
1303 	case RTL871X_HOSTAPD_ACL_REMOVE_STA:
1304 
1305 		ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
1306 
1307 		break;
1308 
1309 	default:
1310 		ret = -EOPNOTSUPP;
1311 		break;
1312 
1313 	}
1314 
1315 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
1316 		ret = -EFAULT;
1317 
1318 	kfree(param);
1319 	return ret;
1320 }
1321 
1322 /*  copy from net/wireless/wext.c end */
1323 
1324 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1325 {
1326 	struct iwreq *wrq = (struct iwreq *)rq;
1327 	int ret = 0;
1328 
1329 	switch (cmd) {
1330 	case RTL_IOCTL_WPA_SUPPLICANT:
1331 		ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
1332 		break;
1333 	case RTL_IOCTL_HOSTAPD:
1334 		ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
1335 		break;
1336 	default:
1337 		ret = -EOPNOTSUPP;
1338 		break;
1339 	}
1340 
1341 	return ret;
1342 }
1343