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
18static 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
45static 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
212exit:
213
214	kfree(pwep);
215	return ret;
216}
217
218static 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
343exit:
344
345	kfree(buf);
346
347	return ret;
348}
349
350static 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
434static 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
462static 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
513static 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
739exit:
740	kfree(pwep);
741
742	return ret;
743}
744
745static 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
769static 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
782static 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
847static 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
884static 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
943static 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
981static 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
1014static 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
1041static 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
1068static 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
1108static 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
1126static 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
1143static 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
1157static 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
1282int 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