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