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