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