1
2
3
4
5
6
7#define _IOCTL_LINUX_C_
8
9#include <linux/ieee80211.h>
10
11#include <osdep_service.h>
12#include <drv_types.h>
13#include <wlan_bssdef.h>
14#include <wifi.h>
15#include <rtw_mlme.h>
16#include <rtw_mlme_ext.h>
17#include <rtw_ioctl.h>
18#include <rtw_ioctl_set.h>
19#include <rtl8188e_hal.h>
20
21#include <linux/vmalloc.h>
22#include <linux/etherdevice.h>
23
24#include "osdep_intf.h"
25
26#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
27
28#define SCAN_ITEM_SIZE 768
29#define MAX_CUSTOM_LEN 64
30#define RATE_COUNT 4
31
32
33#define WEXT_CSCAN_AMOUNT 9
34#define WEXT_CSCAN_BUF_LEN 360
35#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
36#define WEXT_CSCAN_HEADER_SIZE 12
37#define WEXT_CSCAN_SSID_SECTION 'S'
38#define WEXT_CSCAN_CHANNEL_SECTION 'C'
39#define WEXT_CSCAN_NPROBE_SECTION 'N'
40#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
41#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
42#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
43#define WEXT_CSCAN_TYPE_SECTION 'T'
44
45static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
46 6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
47 48000000, 54000000};
48
49static const char * const iw_operation_mode[] = {
50 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater",
51 "Secondary", "Monitor"
52};
53
54void indicate_wx_scan_complete_event(struct adapter *padapter)
55{
56 union iwreq_data wrqu;
57
58 memset(&wrqu, 0, sizeof(union iwreq_data));
59 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
60}
61
62void rtw_indicate_wx_assoc_event(struct adapter *padapter)
63{
64 union iwreq_data wrqu;
65 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
66
67 memset(&wrqu, 0, sizeof(union iwreq_data));
68
69 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
70
71 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
72
73 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
74}
75
76void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
77{
78 union iwreq_data wrqu;
79
80 memset(&wrqu, 0, sizeof(union iwreq_data));
81
82 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
83 eth_zero_addr(wrqu.ap_addr.sa_data);
84
85 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
86}
87
88static char *translate_scan(struct adapter *padapter,
89 struct iw_request_info *info,
90 struct wlan_network *pnetwork,
91 char *start, char *stop)
92{
93 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
94 struct iw_event iwe;
95 u16 cap;
96 __le16 le_tmp;
97 u32 ht_ielen = 0;
98 char custom[MAX_CUSTOM_LEN];
99 char *p;
100 u16 max_rate = 0, rate, ht_cap = false;
101 u32 i = 0;
102 u8 bw_40MHz = 0, short_GI = 0;
103 u16 mcs_rate = 0;
104 u8 ss, sq;
105
106
107 iwe.cmd = SIOCGIWAP;
108 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
109
110 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
111 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
112
113
114 iwe.cmd = SIOCGIWESSID;
115 iwe.u.data.flags = 1;
116 iwe.u.data.length = min_t(u16, pnetwork->network.ssid.ssid_length, 32);
117 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid);
118
119
120 p = rtw_get_ie(&pnetwork->network.ies[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, pnetwork->network.ie_length - 12);
121
122 if (p && ht_ielen > 0) {
123 struct ieee80211_ht_cap *pht_capie;
124
125 ht_cap = true;
126
127 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
128 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
129 bw_40MHz = !!(le16_to_cpu(pht_capie->cap_info) &
130 IEEE80211_HT_CAP_SUP_WIDTH_20_40);
131 short_GI = !!(le16_to_cpu(pht_capie->cap_info) &
132 (IEEE80211_HT_CAP_SGI_20 |
133 IEEE80211_HT_CAP_SGI_40));
134 }
135
136
137 iwe.cmd = SIOCGIWNAME;
138 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) {
139 if (ht_cap)
140 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
141 else
142 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
143 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) {
144 if (ht_cap)
145 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
146 else
147 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
148 } else {
149 if (ht_cap)
150 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
151 else
152 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
153 }
154
155 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
156
157
158 iwe.cmd = SIOCGIWMODE;
159 memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.ies), 2);
160
161 cap = le16_to_cpu(le_tmp);
162
163 if (!WLAN_CAPABILITY_IS_STA_BSS(cap)) {
164 if (cap & WLAN_CAPABILITY_ESS)
165 iwe.u.mode = IW_MODE_MASTER;
166 else
167 iwe.u.mode = IW_MODE_ADHOC;
168
169 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
170 }
171
172 if (pnetwork->network.Configuration.DSConfig < 1)
173 pnetwork->network.Configuration.DSConfig = 1;
174
175
176 iwe.cmd = SIOCGIWFREQ;
177 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
178 iwe.u.freq.e = 1;
179 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
180 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
181
182
183 iwe.cmd = SIOCGIWENCODE;
184 if (cap & WLAN_CAPABILITY_PRIVACY)
185 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
186 else
187 iwe.u.data.flags = IW_ENCODE_DISABLED;
188 iwe.u.data.length = 0;
189 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.ssid.ssid);
190
191
192 max_rate = 0;
193 p = custom;
194 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
195 while (pnetwork->network.SupportedRates[i] != 0) {
196 rate = pnetwork->network.SupportedRates[i] & 0x7F;
197 if (rate > max_rate)
198 max_rate = rate;
199 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
200 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
201 i++;
202 }
203
204 if (ht_cap) {
205 if (mcs_rate & 0x8000)
206 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
207 else if (mcs_rate & 0x0080)
208 ;
209 else
210 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
211
212 max_rate *= 2;
213 }
214
215 iwe.cmd = SIOCGIWRATE;
216 iwe.u.bitrate.fixed = 0;
217 iwe.u.bitrate.disabled = 0;
218 iwe.u.bitrate.value = max_rate * 500000;
219 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
220
221
222 {
223 u8 *buf;
224 u8 *wpa_ie, *rsn_ie;
225 u16 wpa_len = 0, rsn_len = 0;
226 u8 *p;
227
228 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
229 if (!buf)
230 return start;
231
232 wpa_ie = kzalloc(255, GFP_ATOMIC);
233 if (!wpa_ie)
234 return start;
235
236 rsn_ie = kzalloc(255, GFP_ATOMIC);
237 if (!rsn_ie)
238 return start;
239
240 rtw_get_sec_ie(pnetwork->network.ies, pnetwork->network.ie_length, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
241
242 if (wpa_len > 0) {
243 p = buf;
244 p += sprintf(p, "wpa_ie=");
245 for (i = 0; i < wpa_len; i++)
246 p += sprintf(p, "%02x", wpa_ie[i]);
247
248 memset(&iwe, 0, sizeof(iwe));
249 iwe.cmd = IWEVCUSTOM;
250 iwe.u.data.length = strlen(buf);
251 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
252
253 memset(&iwe, 0, sizeof(iwe));
254 iwe.cmd = IWEVGENIE;
255 iwe.u.data.length = wpa_len;
256 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
257 }
258 if (rsn_len > 0) {
259 p = buf;
260 p += sprintf(p, "rsn_ie=");
261 for (i = 0; i < rsn_len; i++)
262 p += sprintf(p, "%02x", rsn_ie[i]);
263 memset(&iwe, 0, sizeof(iwe));
264 iwe.cmd = IWEVCUSTOM;
265 iwe.u.data.length = strlen(buf);
266 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
267
268 memset(&iwe, 0, sizeof(iwe));
269 iwe.cmd = IWEVGENIE;
270 iwe.u.data.length = rsn_len;
271 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
272 }
273 kfree(buf);
274 kfree(wpa_ie);
275 kfree(rsn_ie);
276 }
277
278 {
279 uint cnt = 0, total_ielen;
280 u8 *wpsie_ptr = NULL;
281 uint wps_ielen = 0;
282 u8 *ie_ptr = pnetwork->network.ies + _FIXED_IE_LENGTH_;
283
284 total_ielen = pnetwork->network.ie_length - _FIXED_IE_LENGTH_;
285
286 while (cnt < total_ielen) {
287 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
288 wpsie_ptr = &ie_ptr[cnt];
289 iwe.cmd = IWEVGENIE;
290 iwe.u.data.length = (u16)wps_ielen;
291 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
292 }
293 cnt += ie_ptr[cnt + 1] + 2;
294 }
295 }
296
297
298 iwe.cmd = IWEVQUAL;
299 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
300
301 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
302 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
303 ss = padapter->recvpriv.signal_strength;
304 sq = padapter->recvpriv.signal_qual;
305 } else {
306 ss = pnetwork->network.PhyInfo.SignalStrength;
307 sq = pnetwork->network.PhyInfo.SignalQuality;
308 }
309
310 iwe.u.qual.level = (u8)ss;
311 iwe.u.qual.qual = (u8)sq;
312 iwe.u.qual.noise = 0;
313 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
314 return start;
315}
316
317static int wpa_set_auth_algs(struct net_device *dev, u32 value)
318{
319 struct adapter *padapter = netdev_priv(dev);
320 int ret = 0;
321
322 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
323 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
324 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
325 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
326 } else if (value & AUTH_ALG_SHARED_KEY) {
327 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
328
329 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
330 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
331 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
332 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
333 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
334 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
335 }
336 } else {
337 ret = -EINVAL;
338 }
339 return ret;
340}
341
342static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
343{
344 int ret = 0;
345 u32 wep_key_idx, wep_key_len, wep_total_len;
346 struct ndis_802_11_wep *pwep = NULL;
347 struct adapter *padapter = netdev_priv(dev);
348 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
349 struct security_priv *psecuritypriv = &padapter->securitypriv;
350
351 param->u.crypt.err = 0;
352 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
353
354 if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
355 ret = -EINVAL;
356 goto exit;
357 }
358
359 if (is_broadcast_ether_addr(param->sta_addr)) {
360 if (param->u.crypt.idx >= WEP_KEYS) {
361 ret = -EINVAL;
362 goto exit;
363 }
364 } else {
365 ret = -EINVAL;
366 goto exit;
367 }
368
369 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
370 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
371 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
372 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
373
374 wep_key_idx = param->u.crypt.idx;
375 wep_key_len = param->u.crypt.key_len;
376
377 if (wep_key_idx > WEP_KEYS)
378 return -EINVAL;
379
380 if (wep_key_len > 0) {
381 wep_key_len = wep_key_len <= 5 ? 5 : 13;
382 wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
383 pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
384 if (!pwep)
385 goto exit;
386 memset(pwep, 0, wep_total_len);
387 pwep->KeyLength = wep_key_len;
388 pwep->Length = wep_total_len;
389 if (wep_key_len == 13) {
390 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
391 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
392 }
393 } else {
394 ret = -EINVAL;
395 goto exit;
396 }
397 pwep->KeyIndex = wep_key_idx;
398 pwep->KeyIndex |= 0x80000000;
399 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
400 if (param->u.crypt.set_tx) {
401 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
402 ret = -EOPNOTSUPP;
403 } else {
404 if (wep_key_idx >= WEP_KEYS) {
405 ret = -EOPNOTSUPP;
406 goto exit;
407 }
408 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
409 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
410 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
411 }
412 goto exit;
413 }
414
415 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
416 struct sta_info *psta, *pbcmc_sta;
417 struct sta_priv *pstapriv = &padapter->stapriv;
418
419 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
420 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
421 if (!psta) {
422 ;
423 } else {
424 if (strcmp(param->u.crypt.alg, "none") != 0)
425 psta->ieee8021x_blocked = false;
426
427 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
428 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
429 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
430
431 if (param->u.crypt.set_tx == 1) {
432 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
433
434 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
435 memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8);
436 memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8);
437 padapter->securitypriv.busetkipkey = false;
438 }
439
440 rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
441 } else {
442 memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
443 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8);
444 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8);
445 padapter->securitypriv.binstallGrpkey = true;
446
447 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
448
449 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1);
450 }
451 }
452 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
453 if (!pbcmc_sta) {
454 ;
455 } else {
456
457 if (strcmp(param->u.crypt.alg, "none") != 0)
458 pbcmc_sta->ieee8021x_blocked = false;
459
460 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
461 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
462 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
463 }
464 }
465 }
466
467exit:
468
469 kfree(pwep);
470 return ret;
471}
472
473static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
474{
475 u8 *buf = NULL;
476 int group_cipher = 0, pairwise_cipher = 0;
477 int ret = 0;
478
479 if ((ielen > MAX_WPA_IE_LEN) || (!pie)) {
480 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
481 if (!pie)
482 return ret;
483 else
484 return -EINVAL;
485 }
486
487 if (ielen) {
488 buf = kmemdup(pie, ielen, GFP_KERNEL);
489 if (!buf) {
490 ret = -ENOMEM;
491 goto exit;
492 }
493
494 if (ielen < RSN_HEADER_LEN) {
495 ret = -1;
496 goto exit;
497 }
498
499 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
500 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
501 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
502 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
503 }
504
505 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
506 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
507 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
508 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
509 }
510
511 switch (group_cipher) {
512 case WPA_CIPHER_NONE:
513 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
514 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
515 break;
516 case WPA_CIPHER_WEP40:
517 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
518 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
519 break;
520 case WPA_CIPHER_TKIP:
521 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
522 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
523 break;
524 case WPA_CIPHER_CCMP:
525 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
526 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
527 break;
528 case WPA_CIPHER_WEP104:
529 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
530 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
531 break;
532 }
533
534 switch (pairwise_cipher) {
535 case WPA_CIPHER_NONE:
536 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
537 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
538 break;
539 case WPA_CIPHER_WEP40:
540 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
541 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
542 break;
543 case WPA_CIPHER_TKIP:
544 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
545 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
546 break;
547 case WPA_CIPHER_CCMP:
548 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
549 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
550 break;
551 case WPA_CIPHER_WEP104:
552 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
553 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
554 break;
555 }
556
557 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
558 {
559 u16 cnt = 0;
560 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
561
562 while (cnt < ielen) {
563 eid = buf[cnt];
564 if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
565 padapter->securitypriv.wps_ie_len = min(buf[cnt + 1] + 2, MAX_WPA_IE_LEN << 2);
566
567 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
568
569 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
570 cnt += buf[cnt + 1] + 2;
571 break;
572 }
573 cnt += buf[cnt + 1] + 2;
574 }
575 }
576 }
577exit:
578 kfree(buf);
579 return ret;
580}
581
582typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
583
584static int rtw_wx_get_name(struct net_device *dev,
585 struct iw_request_info *info,
586 union iwreq_data *wrqu, char *extra)
587{
588 struct adapter *padapter = netdev_priv(dev);
589 u32 ht_ielen = 0;
590 char *p;
591 u8 ht_cap = false;
592 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
593 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
594 NDIS_802_11_RATES_EX *prates = NULL;
595
596 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
597
598 p = rtw_get_ie(&pcur_bss->ies[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, pcur_bss->ie_length - 12);
599 if (p && ht_ielen > 0)
600 ht_cap = true;
601
602 prates = &pcur_bss->SupportedRates;
603
604 if (rtw_is_cckratesonly_included((u8 *)prates)) {
605 if (ht_cap)
606 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
607 else
608 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
609 } else if (rtw_is_cckrates_included((u8 *)prates)) {
610 if (ht_cap)
611 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
612 else
613 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
614 } else {
615 if (ht_cap)
616 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
617 else
618 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
619 }
620 } else {
621 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
622 }
623 return 0;
624}
625
626static int rtw_wx_get_freq(struct net_device *dev,
627 struct iw_request_info *info,
628 union iwreq_data *wrqu, char *extra)
629{
630 struct adapter *padapter = netdev_priv(dev);
631 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
632 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
633
634 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
635
636 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
637 wrqu->freq.e = 1;
638 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
639 } else {
640 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
641 wrqu->freq.e = 1;
642 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
643 }
644
645 return 0;
646}
647
648static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
649 union iwreq_data *wrqu, char *b)
650{
651 struct adapter *padapter = netdev_priv(dev);
652 enum ndis_802_11_network_infra networkType;
653 int ret = 0;
654
655 if (!rtw_pwr_wakeup(padapter)) {
656 ret = -EPERM;
657 goto exit;
658 }
659
660 if (!padapter->hw_init_completed) {
661 ret = -EPERM;
662 goto exit;
663 }
664
665 switch (wrqu->mode) {
666 case IW_MODE_AUTO:
667 networkType = Ndis802_11AutoUnknown;
668 break;
669 case IW_MODE_ADHOC:
670 networkType = Ndis802_11IBSS;
671 break;
672 case IW_MODE_MASTER:
673 networkType = Ndis802_11APMode;
674 break;
675 case IW_MODE_INFRA:
676 networkType = Ndis802_11Infrastructure;
677 break;
678 default:
679 ret = -EINVAL;
680 goto exit;
681 }
682 if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) {
683 ret = -EPERM;
684 goto exit;
685 }
686 rtw_setopmode_cmd(padapter, networkType);
687exit:
688 return ret;
689}
690
691static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
692 union iwreq_data *wrqu, char *b)
693{
694 struct adapter *padapter = netdev_priv(dev);
695 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
696
697 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
698 wrqu->mode = IW_MODE_INFRA;
699 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
700 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
701 wrqu->mode = IW_MODE_ADHOC;
702 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
703 wrqu->mode = IW_MODE_MASTER;
704 else
705 wrqu->mode = IW_MODE_AUTO;
706
707 return 0;
708}
709
710static int rtw_wx_set_pmkid(struct net_device *dev,
711 struct iw_request_info *a,
712 union iwreq_data *wrqu, char *extra)
713{
714 struct adapter *padapter = netdev_priv(dev);
715 u8 j, blInserted = false;
716 int ret = false;
717 struct security_priv *psecuritypriv = &padapter->securitypriv;
718 struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
719 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
720 u8 strIssueBssid[ETH_ALEN] = {0x00};
721
722 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
723 if (pPMK->cmd == IW_PMKSA_ADD) {
724 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
725 return ret;
726 ret = true;
727 blInserted = false;
728
729
730 for (j = 0; j < NUM_PMKID_CACHE; j++) {
731 if (!memcmp(psecuritypriv->PMKIDList[j].bssid, strIssueBssid, ETH_ALEN)) {
732
733 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
734 psecuritypriv->PMKIDList[j].used = true;
735 psecuritypriv->PMKIDIndex = j + 1;
736 blInserted = true;
737 break;
738 }
739 }
740
741 if (!blInserted) {
742
743 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bssid, strIssueBssid, ETH_ALEN);
744 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
745
746 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].used = true;
747 psecuritypriv->PMKIDIndex++;
748 if (psecuritypriv->PMKIDIndex == 16)
749 psecuritypriv->PMKIDIndex = 0;
750 }
751 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
752 ret = true;
753 for (j = 0; j < NUM_PMKID_CACHE; j++) {
754 if (!memcmp(psecuritypriv->PMKIDList[j].bssid, strIssueBssid, ETH_ALEN)) {
755
756 eth_zero_addr(psecuritypriv->PMKIDList[j].bssid);
757 psecuritypriv->PMKIDList[j].used = false;
758 break;
759 }
760 }
761 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
762 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
763 psecuritypriv->PMKIDIndex = 0;
764 ret = true;
765 }
766 return ret;
767}
768
769static int rtw_wx_get_sens(struct net_device *dev,
770 struct iw_request_info *info,
771 union iwreq_data *wrqu, char *extra)
772{
773 wrqu->sens.value = 0;
774 wrqu->sens.fixed = 0;
775 wrqu->sens.disabled = 1;
776 return 0;
777}
778
779static int rtw_wx_get_range(struct net_device *dev,
780 struct iw_request_info *info,
781 union iwreq_data *wrqu, char *extra)
782{
783 struct iw_range *range = (struct iw_range *)extra;
784 struct adapter *padapter = netdev_priv(dev);
785 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
786
787 u16 val;
788 int i;
789
790 wrqu->data.length = sizeof(*range);
791 memset(range, 0, sizeof(*range));
792
793
794
795
796
797
798
799
800
801
802 range->throughput = 5 * 1000 * 1000;
803
804
805
806
807 range->max_qual.qual = 100;
808 range->max_qual.level = 100;
809 range->max_qual.noise = 100;
810 range->max_qual.updated = 7;
811
812 range->avg_qual.qual = 92;
813
814 range->avg_qual.level = 178;
815 range->avg_qual.noise = 0;
816 range->avg_qual.updated = 7;
817
818 range->num_bitrates = RATE_COUNT;
819
820 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
821 range->bitrate[i] = rtw_rates[i];
822
823 range->min_frag = MIN_FRAG_THRESHOLD;
824 range->max_frag = MAX_FRAG_THRESHOLD;
825
826 range->pm_capa = 0;
827
828 range->we_version_compiled = WIRELESS_EXT;
829 range->we_version_source = 16;
830
831 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
832
833 if (pmlmeext->channel_set[i].ChannelNum != 0) {
834 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
835 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
836 range->freq[val].e = 1;
837 val++;
838 }
839
840 if (val == IW_MAX_FREQUENCIES)
841 break;
842 }
843
844 range->num_channels = val;
845 range->num_frequency = val;
846
847
848
849
850
851 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
852 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
853
854 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |
855 IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL |
856 IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
857 return 0;
858}
859
860
861
862
863
864
865static int rtw_wx_set_wap(struct net_device *dev,
866 struct iw_request_info *info,
867 union iwreq_data *awrq, char *extra)
868{
869 uint ret = 0;
870 struct adapter *padapter = netdev_priv(dev);
871 struct sockaddr *temp = (struct sockaddr *)awrq;
872 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
873 struct list_head *phead;
874 u8 *dst_bssid, *src_bssid;
875 struct __queue *queue = &pmlmepriv->scanned_queue;
876 struct wlan_network *pnetwork = NULL;
877 enum ndis_802_11_auth_mode authmode;
878
879 if (!rtw_pwr_wakeup(padapter)) {
880 ret = -1;
881 goto exit;
882 }
883
884 if (!padapter->bup) {
885 ret = -1;
886 goto exit;
887 }
888
889 if (temp->sa_family != ARPHRD_ETHER) {
890 ret = -EINVAL;
891 goto exit;
892 }
893
894 authmode = padapter->securitypriv.ndisauthtype;
895 spin_lock_bh(&queue->lock);
896 phead = get_list_head(queue);
897 list_for_each(pmlmepriv->pscanned, phead) {
898 pnetwork = list_entry(pmlmepriv->pscanned,
899 struct wlan_network, list);
900
901 dst_bssid = pnetwork->network.MacAddress;
902
903 src_bssid = temp->sa_data;
904
905 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
906 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
907 ret = -1;
908 spin_unlock_bh(&queue->lock);
909 goto exit;
910 }
911
912 break;
913 }
914 }
915 spin_unlock_bh(&queue->lock);
916
917 rtw_set_802_11_authentication_mode(padapter, authmode);
918 if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
919 ret = -1;
920 goto exit;
921 }
922
923exit:
924
925 return ret;
926}
927
928static int rtw_wx_get_wap(struct net_device *dev,
929 struct iw_request_info *info,
930 union iwreq_data *wrqu, char *extra)
931{
932 struct adapter *padapter = netdev_priv(dev);
933 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
934 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
935
936 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
937
938 eth_zero_addr(wrqu->ap_addr.sa_data);
939
940 if (check_fwstate(pmlmepriv, _FW_LINKED) ||
941 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
942 check_fwstate(pmlmepriv, WIFI_AP_STATE))
943 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
944 else
945 eth_zero_addr(wrqu->ap_addr.sa_data);
946 return 0;
947}
948
949static int rtw_wx_set_mlme(struct net_device *dev,
950 struct iw_request_info *info,
951 union iwreq_data *wrqu, char *extra)
952{
953 int ret = 0;
954 struct adapter *padapter = netdev_priv(dev);
955 struct iw_mlme *mlme = (struct iw_mlme *)extra;
956
957 if (!mlme)
958 return -1;
959
960 switch (mlme->cmd) {
961 case IW_MLME_DEAUTH:
962 if (!rtw_set_802_11_disassociate(padapter))
963 ret = -1;
964 break;
965 case IW_MLME_DISASSOC:
966 if (!rtw_set_802_11_disassociate(padapter))
967 ret = -1;
968 break;
969 default:
970 return -EOPNOTSUPP;
971 }
972 return ret;
973}
974
975static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
976 union iwreq_data *wrqu, char *extra)
977{
978 u8 _status = false;
979 int ret = 0;
980 struct adapter *padapter = netdev_priv(dev);
981 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
982 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
983
984 if (!rtw_pwr_wakeup(padapter)) {
985 ret = -1;
986 goto exit;
987 }
988
989 if (padapter->bDriverStopped) {
990 ret = -1;
991 goto exit;
992 }
993
994 if (!padapter->bup) {
995 ret = -1;
996 goto exit;
997 }
998
999 if (!padapter->hw_init_completed) {
1000 ret = -1;
1001 goto exit;
1002 }
1003
1004
1005
1006
1007 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1008 indicate_wx_scan_complete_event(padapter);
1009 goto exit;
1010 }
1011
1012 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
1013 indicate_wx_scan_complete_event(padapter);
1014 goto exit;
1015 }
1016
1017
1018
1019
1020
1021 memset(ssid, 0, sizeof(struct ndis_802_11_ssid) * RTW_SSID_SCAN_AMOUNT);
1022
1023 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1024 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1025
1026 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1027 int len = min_t(int, req->essid_len,
1028 IW_ESSID_MAX_SIZE);
1029
1030 memcpy(ssid[0].ssid, req->essid, len);
1031 ssid[0].ssid_length = len;
1032
1033 spin_lock_bh(&pmlmepriv->lock);
1034
1035 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1036
1037 spin_unlock_bh(&pmlmepriv->lock);
1038 }
1039 } else {
1040 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
1041 !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1042 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
1043 char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
1044 char section;
1045 char sec_len;
1046 int ssid_index = 0;
1047
1048 while (len >= 1) {
1049 section = *(pos++);
1050 len -= 1;
1051
1052 switch (section) {
1053 case WEXT_CSCAN_SSID_SECTION:
1054 if (len < 1) {
1055 len = 0;
1056 break;
1057 }
1058 sec_len = *(pos++); len -= 1;
1059 if (sec_len > 0 &&
1060 sec_len <= len &&
1061 sec_len <= 32) {
1062 ssid[ssid_index].ssid_length = sec_len;
1063 memcpy(ssid[ssid_index].ssid, pos, sec_len);
1064 ssid_index++;
1065 }
1066 pos += sec_len;
1067 len -= sec_len;
1068 break;
1069 case WEXT_CSCAN_TYPE_SECTION:
1070 case WEXT_CSCAN_CHANNEL_SECTION:
1071 pos += 1;
1072 len -= 1;
1073 break;
1074 case WEXT_CSCAN_PASV_DWELL_SECTION:
1075 case WEXT_CSCAN_HOME_DWELL_SECTION:
1076 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1077 pos += 2;
1078 len -= 2;
1079 break;
1080 default:
1081 len = 0;
1082 }
1083 }
1084
1085
1086 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1087 } else {
1088 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1089 }
1090 }
1091
1092 if (!_status)
1093 ret = -1;
1094
1095exit:
1096
1097 return ret;
1098}
1099
1100static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1101 union iwreq_data *wrqu, char *extra)
1102{
1103 struct list_head *plist, *phead;
1104 struct adapter *padapter = netdev_priv(dev);
1105 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1106 struct __queue *queue = &pmlmepriv->scanned_queue;
1107 struct wlan_network *pnetwork = NULL;
1108 char *ev = extra;
1109 char *stop = ev + wrqu->data.length;
1110 u32 ret = 0;
1111 u32 cnt = 0;
1112 u32 wait_for_surveydone;
1113 int wait_status;
1114
1115 if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) {
1116 ret = -EINVAL;
1117 goto exit;
1118 }
1119
1120 wait_for_surveydone = 100;
1121
1122 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1123
1124 while (check_fwstate(pmlmepriv, wait_status)) {
1125 msleep(30);
1126 cnt++;
1127 if (cnt > wait_for_surveydone)
1128 break;
1129 }
1130
1131 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1132
1133 phead = get_list_head(queue);
1134 list_for_each(plist, phead) {
1135 if ((stop - ev) < SCAN_ITEM_SIZE) {
1136 ret = -E2BIG;
1137 break;
1138 }
1139
1140 pnetwork = list_entry(plist, struct wlan_network, list);
1141
1142
1143 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0)
1144 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1145 }
1146
1147 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1148
1149 wrqu->data.length = ev - extra;
1150 wrqu->data.flags = 0;
1151
1152exit:
1153 return ret;
1154}
1155
1156
1157
1158
1159
1160
1161static int rtw_wx_set_essid(struct net_device *dev,
1162 struct iw_request_info *a,
1163 union iwreq_data *wrqu, char *extra)
1164{
1165 struct adapter *padapter = netdev_priv(dev);
1166 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1167 struct __queue *queue = &pmlmepriv->scanned_queue;
1168 struct list_head *phead;
1169 struct wlan_network *pnetwork = NULL;
1170 enum ndis_802_11_auth_mode authmode;
1171 struct ndis_802_11_ssid ndis_ssid;
1172 u8 *dst_ssid, *src_ssid;
1173
1174 uint ret = 0, len;
1175
1176 if (!rtw_pwr_wakeup(padapter)) {
1177 ret = -1;
1178 goto exit;
1179 }
1180
1181 if (!padapter->bup) {
1182 ret = -1;
1183 goto exit;
1184 }
1185
1186 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1187 ret = -E2BIG;
1188 goto exit;
1189 }
1190
1191 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1192 ret = -1;
1193 goto exit;
1194 }
1195
1196 authmode = padapter->securitypriv.ndisauthtype;
1197 if (wrqu->essid.flags && wrqu->essid.length) {
1198 len = min_t(uint, wrqu->essid.length, IW_ESSID_MAX_SIZE);
1199
1200 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1201 ndis_ssid.ssid_length = len;
1202 memcpy(ndis_ssid.ssid, extra, len);
1203 src_ssid = ndis_ssid.ssid;
1204
1205 spin_lock_bh(&queue->lock);
1206 phead = get_list_head(queue);
1207 list_for_each(pmlmepriv->pscanned, phead) {
1208 pnetwork = list_entry(pmlmepriv->pscanned,
1209 struct wlan_network, list);
1210
1211 dst_ssid = pnetwork->network.ssid.ssid;
1212
1213 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_length)) &&
1214 (pnetwork->network.ssid.ssid_length == ndis_ssid.ssid_length)) {
1215
1216 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1217 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1218 continue;
1219 }
1220
1221 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1222 ret = -1;
1223 spin_unlock_bh(&queue->lock);
1224 goto exit;
1225 }
1226
1227 break;
1228 }
1229 }
1230 spin_unlock_bh(&queue->lock);
1231 rtw_set_802_11_authentication_mode(padapter, authmode);
1232 if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) {
1233 ret = -1;
1234 goto exit;
1235 }
1236 }
1237
1238exit:
1239 return ret;
1240}
1241
1242static int rtw_wx_get_essid(struct net_device *dev,
1243 struct iw_request_info *a,
1244 union iwreq_data *wrqu, char *extra)
1245{
1246 u32 len;
1247 struct adapter *padapter = netdev_priv(dev);
1248 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1249 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1250
1251 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
1252 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) {
1253 len = pcur_bss->ssid.ssid_length;
1254 memcpy(extra, pcur_bss->ssid.ssid, len);
1255 } else {
1256 len = 0;
1257 *extra = 0;
1258 }
1259 wrqu->essid.length = len;
1260 wrqu->essid.flags = 1;
1261
1262 return 0;
1263}
1264
1265static int rtw_wx_set_rate(struct net_device *dev,
1266 struct iw_request_info *a,
1267 union iwreq_data *wrqu, char *extra)
1268{
1269 int i;
1270 u8 datarates[NumRates];
1271 u32 target_rate = wrqu->bitrate.value;
1272 u32 fixed = wrqu->bitrate.fixed;
1273 u32 ratevalue = 0;
1274 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1275
1276 if (target_rate == -1) {
1277 ratevalue = 11;
1278 goto set_rate;
1279 }
1280 target_rate /= 100000;
1281
1282 switch (target_rate) {
1283 case 10:
1284 ratevalue = 0;
1285 break;
1286 case 20:
1287 ratevalue = 1;
1288 break;
1289 case 55:
1290 ratevalue = 2;
1291 break;
1292 case 60:
1293 ratevalue = 3;
1294 break;
1295 case 90:
1296 ratevalue = 4;
1297 break;
1298 case 110:
1299 ratevalue = 5;
1300 break;
1301 case 120:
1302 ratevalue = 6;
1303 break;
1304 case 180:
1305 ratevalue = 7;
1306 break;
1307 case 240:
1308 ratevalue = 8;
1309 break;
1310 case 360:
1311 ratevalue = 9;
1312 break;
1313 case 480:
1314 ratevalue = 10;
1315 break;
1316 case 540:
1317 ratevalue = 11;
1318 break;
1319 default:
1320 ratevalue = 11;
1321 break;
1322 }
1323
1324set_rate:
1325
1326 for (i = 0; i < NumRates; i++) {
1327 if (ratevalue == mpdatarate[i]) {
1328 datarates[i] = mpdatarate[i];
1329 if (fixed == 0)
1330 break;
1331 } else {
1332 datarates[i] = 0xff;
1333 }
1334 }
1335
1336 return 0;
1337}
1338
1339static int rtw_wx_get_rate(struct net_device *dev,
1340 struct iw_request_info *info,
1341 union iwreq_data *wrqu, char *extra)
1342{
1343 u16 max_rate = 0;
1344
1345 max_rate = rtw_get_cur_max_rate(netdev_priv(dev));
1346
1347 if (max_rate == 0)
1348 return -EPERM;
1349
1350 wrqu->bitrate.fixed = 0;
1351 wrqu->bitrate.value = max_rate * 100000;
1352
1353 return 0;
1354}
1355
1356static int rtw_wx_set_rts(struct net_device *dev,
1357 struct iw_request_info *info,
1358 union iwreq_data *wrqu, char *extra)
1359{
1360 struct adapter *padapter = netdev_priv(dev);
1361
1362 if (wrqu->rts.disabled) {
1363 padapter->registrypriv.rts_thresh = 2347;
1364 } else {
1365 if (wrqu->rts.value < 0 ||
1366 wrqu->rts.value > 2347)
1367 return -EINVAL;
1368
1369 padapter->registrypriv.rts_thresh = wrqu->rts.value;
1370 }
1371
1372 return 0;
1373}
1374
1375static int rtw_wx_get_rts(struct net_device *dev,
1376 struct iw_request_info *info,
1377 union iwreq_data *wrqu, char *extra)
1378{
1379 struct adapter *padapter = netdev_priv(dev);
1380
1381 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1382 wrqu->rts.fixed = 0;
1383
1384
1385 return 0;
1386}
1387
1388static int rtw_wx_set_frag(struct net_device *dev,
1389 struct iw_request_info *info,
1390 union iwreq_data *wrqu, char *extra)
1391{
1392 struct adapter *padapter = netdev_priv(dev);
1393
1394 if (wrqu->frag.disabled) {
1395 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1396 } else {
1397 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1398 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1399 return -EINVAL;
1400
1401 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1402 }
1403
1404 return 0;
1405}
1406
1407static int rtw_wx_get_frag(struct net_device *dev,
1408 struct iw_request_info *info,
1409 union iwreq_data *wrqu, char *extra)
1410{
1411 struct adapter *padapter = netdev_priv(dev);
1412
1413 wrqu->frag.value = padapter->xmitpriv.frag_len;
1414 wrqu->frag.fixed = 0;
1415
1416 return 0;
1417}
1418
1419static int rtw_wx_get_retry(struct net_device *dev,
1420 struct iw_request_info *info,
1421 union iwreq_data *wrqu, char *extra)
1422{
1423 wrqu->retry.value = 7;
1424 wrqu->retry.fixed = 0;
1425 wrqu->retry.disabled = 1;
1426
1427 return 0;
1428}
1429
1430static int rtw_wx_set_enc(struct net_device *dev,
1431 struct iw_request_info *info,
1432 union iwreq_data *wrqu, char *keybuf)
1433{
1434 u32 key, ret = 0;
1435 u32 keyindex_provided;
1436 struct ndis_802_11_wep wep;
1437 enum ndis_802_11_auth_mode authmode;
1438
1439 struct iw_point *erq = &wrqu->encoding;
1440 struct adapter *padapter = netdev_priv(dev);
1441 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1442
1443 memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1444
1445 key = erq->flags & IW_ENCODE_INDEX;
1446
1447 if (erq->flags & IW_ENCODE_DISABLED) {
1448 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1449 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1450 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1451 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1452 authmode = Ndis802_11AuthModeOpen;
1453 padapter->securitypriv.ndisauthtype = authmode;
1454
1455 goto exit;
1456 }
1457
1458 if (key) {
1459 if (key > WEP_KEYS)
1460 return -EINVAL;
1461 key--;
1462 keyindex_provided = 1;
1463 } else {
1464 keyindex_provided = 0;
1465 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1466 }
1467
1468
1469 if (erq->flags & IW_ENCODE_OPEN) {
1470 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1471 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1472 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1473 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1474 authmode = Ndis802_11AuthModeOpen;
1475 padapter->securitypriv.ndisauthtype = authmode;
1476 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1477 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1478 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1479 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1480 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1481 authmode = Ndis802_11AuthModeShared;
1482 padapter->securitypriv.ndisauthtype = authmode;
1483 } else {
1484 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1485 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1486 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1487 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1488 authmode = Ndis802_11AuthModeOpen;
1489 padapter->securitypriv.ndisauthtype = authmode;
1490 }
1491
1492 wep.KeyIndex = key;
1493 if (erq->length > 0) {
1494 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1495
1496 wep.Length = wep.KeyLength + offsetof(struct ndis_802_11_wep, KeyMaterial);
1497 } else {
1498 wep.KeyLength = 0;
1499
1500 if (keyindex_provided == 1) {
1501
1502 padapter->securitypriv.dot11PrivacyKeyIndex = key;
1503
1504 switch (padapter->securitypriv.dot11DefKeylen[key]) {
1505 case 5:
1506 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1507 break;
1508 case 13:
1509 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1510 break;
1511 default:
1512 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1513 break;
1514 }
1515
1516 goto exit;
1517 }
1518 }
1519
1520 wep.KeyIndex |= 0x80000000;
1521
1522 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1523
1524 if (!rtw_set_802_11_add_wep(padapter, &wep)) {
1525 if (rf_on == pwrpriv->rf_pwrstate)
1526 ret = -EOPNOTSUPP;
1527 goto exit;
1528 }
1529
1530exit:
1531 return ret;
1532}
1533
1534static int rtw_wx_get_enc(struct net_device *dev,
1535 struct iw_request_info *info,
1536 union iwreq_data *wrqu, char *keybuf)
1537{
1538 uint key;
1539 struct adapter *padapter = netdev_priv(dev);
1540 struct iw_point *erq = &wrqu->encoding;
1541 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1542
1543 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
1544 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1545 erq->length = 0;
1546 erq->flags |= IW_ENCODE_DISABLED;
1547 return 0;
1548 }
1549 }
1550
1551 key = erq->flags & IW_ENCODE_INDEX;
1552
1553 if (key) {
1554 if (key > WEP_KEYS)
1555 return -EINVAL;
1556 key--;
1557 } else {
1558 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1559 }
1560
1561 erq->flags = key + 1;
1562
1563 switch (padapter->securitypriv.ndisencryptstatus) {
1564 case Ndis802_11EncryptionNotSupported:
1565 case Ndis802_11EncryptionDisabled:
1566 erq->length = 0;
1567 erq->flags |= IW_ENCODE_DISABLED;
1568 break;
1569 case Ndis802_11Encryption1Enabled:
1570 erq->length = padapter->securitypriv.dot11DefKeylen[key];
1571 if (erq->length) {
1572 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1573
1574 erq->flags |= IW_ENCODE_ENABLED;
1575
1576 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
1577 erq->flags |= IW_ENCODE_OPEN;
1578 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
1579 erq->flags |= IW_ENCODE_RESTRICTED;
1580 } else {
1581 erq->length = 0;
1582 erq->flags |= IW_ENCODE_DISABLED;
1583 }
1584 break;
1585 case Ndis802_11Encryption2Enabled:
1586 case Ndis802_11Encryption3Enabled:
1587 erq->length = 16;
1588 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
1589 break;
1590 default:
1591 erq->length = 0;
1592 erq->flags |= IW_ENCODE_DISABLED;
1593 break;
1594 }
1595
1596 return 0;
1597}
1598
1599static int rtw_wx_get_power(struct net_device *dev,
1600 struct iw_request_info *info,
1601 union iwreq_data *wrqu, char *extra)
1602{
1603 wrqu->power.value = 0;
1604 wrqu->power.fixed = 0;
1605 wrqu->power.disabled = 1;
1606
1607 return 0;
1608}
1609
1610static int rtw_wx_set_gen_ie(struct net_device *dev,
1611 struct iw_request_info *info,
1612 union iwreq_data *wrqu, char *extra)
1613{
1614 struct adapter *padapter = netdev_priv(dev);
1615
1616 return rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
1617}
1618
1619static int rtw_wx_set_auth(struct net_device *dev,
1620 struct iw_request_info *info,
1621 union iwreq_data *wrqu, char *extra)
1622{
1623 struct adapter *padapter = netdev_priv(dev);
1624 struct iw_param *param = (struct iw_param *)&wrqu->param;
1625 int ret = 0;
1626
1627 switch (param->flags & IW_AUTH_INDEX) {
1628 case IW_AUTH_WPA_VERSION:
1629 break;
1630 case IW_AUTH_CIPHER_PAIRWISE:
1631
1632 break;
1633 case IW_AUTH_CIPHER_GROUP:
1634
1635 break;
1636 case IW_AUTH_KEY_MGMT:
1637
1638
1639
1640 break;
1641 case IW_AUTH_TKIP_COUNTERMEASURES:
1642 if (param->value) {
1643
1644 padapter->securitypriv.btkip_countermeasure = true;
1645 } else {
1646
1647 padapter->securitypriv.btkip_countermeasure = false;
1648 }
1649 break;
1650 case IW_AUTH_DROP_UNENCRYPTED:
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1664 break;
1665
1666
1667 if (param->value) {
1668 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1669 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1670 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1671 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1672 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1673 }
1674
1675 break;
1676 case IW_AUTH_80211_AUTH_ALG:
1677
1678 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
1679 LeaveAllPowerSaveMode(padapter);
1680 rtw_disassoc_cmd(padapter, 500, false);
1681 rtw_indicate_disconnect(padapter);
1682 rtw_free_assoc_resources(padapter);
1683 }
1684 ret = wpa_set_auth_algs(dev, (u32)param->value);
1685 break;
1686 case IW_AUTH_WPA_ENABLED:
1687 break;
1688 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1689 break;
1690 case IW_AUTH_PRIVACY_INVOKED:
1691 break;
1692 default:
1693 return -EOPNOTSUPP;
1694 }
1695
1696 return ret;
1697}
1698
1699static int rtw_wx_set_enc_ext(struct net_device *dev,
1700 struct iw_request_info *info,
1701 union iwreq_data *wrqu, char *extra)
1702{
1703 char *alg_name;
1704 u32 param_len;
1705 struct ieee_param *param = NULL;
1706 struct iw_point *pencoding = &wrqu->encoding;
1707 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1708 int ret = 0;
1709
1710 param_len = sizeof(struct ieee_param) + pext->key_len;
1711 param = (struct ieee_param *)rtw_malloc(param_len);
1712 if (!param)
1713 return -1;
1714
1715 memset(param, 0, param_len);
1716
1717 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1718 eth_broadcast_addr(param->sta_addr);
1719
1720 switch (pext->alg) {
1721 case IW_ENCODE_ALG_NONE:
1722
1723
1724 alg_name = "none";
1725 break;
1726 case IW_ENCODE_ALG_WEP:
1727 alg_name = "WEP";
1728 break;
1729 case IW_ENCODE_ALG_TKIP:
1730 alg_name = "TKIP";
1731 break;
1732 case IW_ENCODE_ALG_CCMP:
1733 alg_name = "CCMP";
1734 break;
1735 default:
1736 ret = -1;
1737 goto exit;
1738 }
1739
1740 strscpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1741
1742 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1743 param->u.crypt.set_tx = 1;
1744
1745
1746
1747
1748 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
1749 (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
1750 param->u.crypt.set_tx = 0;
1751
1752 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1753
1754 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1755 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1756
1757 if (pext->key_len) {
1758 param->u.crypt.key_len = pext->key_len;
1759 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
1760 }
1761
1762 ret = wpa_set_encryption(dev, param, param_len);
1763
1764exit:
1765 kfree(param);
1766 return ret;
1767}
1768
1769static int rtw_wx_get_nick(struct net_device *dev,
1770 struct iw_request_info *info,
1771 union iwreq_data *wrqu, char *extra)
1772{
1773 if (extra) {
1774 wrqu->data.length = 14;
1775 wrqu->data.flags = 1;
1776 memcpy(extra, "<WIFI@REALTEK>", 14);
1777 }
1778
1779
1780 return 0;
1781}
1782
1783static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
1784{
1785 uint ret = 0;
1786 struct adapter *padapter = netdev_priv(dev);
1787
1788 switch (name) {
1789 case IEEE_PARAM_WPA_ENABLED:
1790 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1791 switch (value & 0xff) {
1792 case 1:
1793 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
1794 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1795 break;
1796 case 2:
1797 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1798 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1799 break;
1800 }
1801 break;
1802 case IEEE_PARAM_TKIP_COUNTERMEASURES:
1803 break;
1804 case IEEE_PARAM_DROP_UNENCRYPTED: {
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817 break;
1818 }
1819 case IEEE_PARAM_PRIVACY_INVOKED:
1820 break;
1821
1822 case IEEE_PARAM_AUTH_ALGS:
1823 ret = wpa_set_auth_algs(dev, value);
1824 break;
1825 case IEEE_PARAM_IEEE_802_1X:
1826 break;
1827 case IEEE_PARAM_WPAX_SELECT:
1828 break;
1829 default:
1830 ret = -EOPNOTSUPP;
1831 break;
1832 }
1833 return ret;
1834}
1835
1836static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
1837{
1838 int ret = 0;
1839 struct adapter *padapter = netdev_priv(dev);
1840
1841 switch (command) {
1842 case IEEE_MLME_STA_DEAUTH:
1843 if (!rtw_set_802_11_disassociate(padapter))
1844 ret = -1;
1845 break;
1846 case IEEE_MLME_STA_DISASSOC:
1847 if (!rtw_set_802_11_disassociate(padapter))
1848 ret = -1;
1849 break;
1850 default:
1851 ret = -EOPNOTSUPP;
1852 break;
1853 }
1854
1855 return ret;
1856}
1857
1858static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
1859{
1860 struct ieee_param *param;
1861 uint ret = 0;
1862
1863 if (!p->pointer || p->length != sizeof(struct ieee_param))
1864 return -EINVAL;
1865
1866 param = memdup_user(p->pointer, p->length);
1867 if (IS_ERR(param))
1868 return PTR_ERR(param);
1869
1870 switch (param->cmd) {
1871 case IEEE_CMD_SET_WPA_PARAM:
1872 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
1873 break;
1874
1875 case IEEE_CMD_SET_WPA_IE:
1876 ret = rtw_set_wpa_ie(netdev_priv(dev),
1877 (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
1878 break;
1879
1880 case IEEE_CMD_SET_ENCRYPTION:
1881 ret = wpa_set_encryption(dev, param, p->length);
1882 break;
1883
1884 case IEEE_CMD_MLME:
1885 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
1886 break;
1887
1888 default:
1889 ret = -EOPNOTSUPP;
1890 break;
1891 }
1892
1893 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
1894 ret = -EFAULT;
1895
1896 kfree(param);
1897 return ret;
1898}
1899
1900#ifdef CONFIG_88EU_AP_MODE
1901static u8 set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
1902{
1903 struct cmd_obj *ph2c;
1904 struct set_stakey_parm *psetstakey_para;
1905 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1906 u8 res = _SUCCESS;
1907
1908 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1909 if (!ph2c) {
1910 res = _FAIL;
1911 goto exit;
1912 }
1913
1914 psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
1915 if (!psetstakey_para) {
1916 kfree(ph2c);
1917 res = _FAIL;
1918 goto exit;
1919 }
1920
1921 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1922
1923 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
1924
1925 memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
1926
1927 memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
1928
1929 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1930
1931exit:
1932
1933 return res;
1934}
1935
1936static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
1937{
1938 u8 keylen;
1939 struct cmd_obj *pcmd;
1940 struct setkey_parm *psetkeyparm;
1941 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1942 int res = _SUCCESS;
1943
1944 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1945 if (!pcmd) {
1946 res = _FAIL;
1947 goto exit;
1948 }
1949 psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
1950 if (!psetkeyparm) {
1951 kfree(pcmd);
1952 res = _FAIL;
1953 goto exit;
1954 }
1955
1956 psetkeyparm->keyid = (u8)keyid;
1957
1958 psetkeyparm->algorithm = alg;
1959
1960 psetkeyparm->set_tx = 1;
1961
1962 switch (alg) {
1963 case _WEP40_:
1964 keylen = 5;
1965 break;
1966 case _WEP104_:
1967 keylen = 13;
1968 break;
1969 case _TKIP_:
1970 case _TKIP_WTMIC_:
1971 case _AES_:
1972 default:
1973 keylen = 16;
1974 }
1975
1976 memcpy(&psetkeyparm->key[0], key, keylen);
1977
1978 pcmd->cmdcode = _SetKey_CMD_;
1979 pcmd->parmbuf = (u8 *)psetkeyparm;
1980 pcmd->cmdsz = (sizeof(struct setkey_parm));
1981 pcmd->rsp = NULL;
1982 pcmd->rspsz = 0;
1983
1984 INIT_LIST_HEAD(&pcmd->list);
1985
1986 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1987
1988exit:
1989
1990 return res;
1991}
1992
1993static int set_wep_key(struct adapter *padapter, u8 *key, u8 keylen, int keyid)
1994{
1995 u8 alg;
1996
1997 switch (keylen) {
1998 case 5:
1999 alg = _WEP40_;
2000 break;
2001 case 13:
2002 alg = _WEP104_;
2003 break;
2004 default:
2005 alg = _NO_PRIVACY_;
2006 }
2007
2008 return set_group_key(padapter, key, alg, keyid);
2009}
2010
2011static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
2012{
2013 int ret = 0;
2014 u32 wep_key_idx, wep_key_len, wep_total_len;
2015 struct ndis_802_11_wep *pwep = NULL;
2016 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
2017 struct adapter *padapter = netdev_priv(dev);
2018 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2019 struct security_priv *psecuritypriv = &padapter->securitypriv;
2020 struct sta_priv *pstapriv = &padapter->stapriv;
2021
2022 param->u.crypt.err = 0;
2023 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2024 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
2025 ret = -EINVAL;
2026 goto exit;
2027 }
2028 if (is_broadcast_ether_addr(param->sta_addr)) {
2029 if (param->u.crypt.idx >= WEP_KEYS) {
2030 ret = -EINVAL;
2031 goto exit;
2032 }
2033 } else {
2034 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2035 if (!psta)
2036 goto exit;
2037 }
2038
2039 if (strcmp(param->u.crypt.alg, "none") == 0 && (!psta))
2040
2041 goto exit;
2042
2043 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (!psta)) {
2044 wep_key_idx = param->u.crypt.idx;
2045 wep_key_len = param->u.crypt.key_len;
2046 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
2047 ret = -EINVAL;
2048 goto exit;
2049 }
2050
2051 if (wep_key_len > 0) {
2052 wep_key_len = wep_key_len <= 5 ? 5 : 13;
2053 wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, KeyMaterial);
2054 pwep = (struct ndis_802_11_wep *)rtw_malloc(wep_total_len);
2055 if (!pwep)
2056 goto exit;
2057
2058 memset(pwep, 0, wep_total_len);
2059
2060 pwep->KeyLength = wep_key_len;
2061 pwep->Length = wep_total_len;
2062 }
2063
2064 pwep->KeyIndex = wep_key_idx;
2065
2066 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
2067
2068 if (param->u.crypt.set_tx) {
2069 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2070 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
2071 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2072
2073 if (pwep->KeyLength == 13) {
2074 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
2075 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2076 }
2077
2078 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
2079
2080 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
2081
2082 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
2083
2084 set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
2085 } else {
2086
2087
2088
2089 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
2090
2091 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
2092
2093 set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx);
2094 }
2095
2096 goto exit;
2097 }
2098
2099 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2100 if (param->u.crypt.set_tx == 1) {
2101 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2102 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2103 param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2104
2105 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2106 if (param->u.crypt.key_len == 13)
2107 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2108 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2109 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
2110 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2111 param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2112
2113 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8);
2114 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8);
2115
2116 psecuritypriv->busetkipkey = true;
2117 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2118 psecuritypriv->dot118021XGrpPrivacy = _AES_;
2119 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2120 param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2121 } else {
2122 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2123 }
2124 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
2125 psecuritypriv->binstallGrpkey = true;
2126 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
2127 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
2128 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
2129 if (pbcmc_sta) {
2130 pbcmc_sta->ieee8021x_blocked = false;
2131 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
2132 }
2133 }
2134 goto exit;
2135 }
2136
2137 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) {
2138 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2139 if (param->u.crypt.set_tx == 1) {
2140 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2141
2142 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2143 psta->dot118021XPrivacy = _WEP40_;
2144 if (param->u.crypt.key_len == 13)
2145 psta->dot118021XPrivacy = _WEP104_;
2146 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2147 psta->dot118021XPrivacy = _TKIP_;
2148
2149
2150 memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8);
2151 memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8);
2152
2153 psecuritypriv->busetkipkey = true;
2154 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2155 psta->dot118021XPrivacy = _AES_;
2156 } else {
2157 psta->dot118021XPrivacy = _NO_PRIVACY_;
2158 }
2159
2160 set_pairwise_key(padapter, psta);
2161
2162 psta->ieee8021x_blocked = false;
2163 } else {
2164 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2165 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2166 param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2167 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2168 if (param->u.crypt.key_len == 13)
2169 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2170 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2171 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
2172
2173 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2174 param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2175
2176
2177 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8);
2178 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8);
2179
2180 psecuritypriv->busetkipkey = true;
2181 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2182 psecuritypriv->dot118021XGrpPrivacy = _AES_;
2183
2184 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,
2185 param->u.crypt.key, min_t(u16, param->u.crypt.key_len, 16));
2186 } else {
2187 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2188 }
2189
2190 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
2191
2192 psecuritypriv->binstallGrpkey = true;
2193
2194 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
2195
2196 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
2197
2198 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
2199 if (pbcmc_sta) {
2200 pbcmc_sta->ieee8021x_blocked = false;
2201 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
2202 }
2203 }
2204 }
2205 }
2206
2207exit:
2208
2209 kfree(pwep);
2210
2211 return ret;
2212}
2213
2214static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
2215{
2216 int ret = 0;
2217 struct adapter *padapter = netdev_priv(dev);
2218 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2219 struct sta_priv *pstapriv = &padapter->stapriv;
2220 unsigned char *pbuf = param->u.bcn_ie.buf;
2221
2222 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2223 return -EINVAL;
2224
2225 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
2226
2227 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
2228 pstapriv->max_num_sta = NUM_STA;
2229
2230 if (rtw_check_beacon_data(padapter, pbuf, len - 12 - 2) == _SUCCESS)
2231 ret = 0;
2232 else
2233 ret = -EINVAL;
2234
2235 return ret;
2236}
2237
2238static int rtw_hostapd_sta_flush(struct net_device *dev)
2239{
2240 struct adapter *padapter = netdev_priv(dev);
2241
2242 flush_all_cam_entry(padapter);
2243
2244 return rtw_sta_flush(padapter);
2245}
2246
2247static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
2248{
2249 int ret = 0;
2250 struct sta_info *psta = NULL;
2251 struct adapter *padapter = netdev_priv(dev);
2252 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2253 struct sta_priv *pstapriv = &padapter->stapriv;
2254
2255 if (!check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)))
2256 return -EINVAL;
2257
2258 if (is_broadcast_ether_addr(param->sta_addr))
2259 return -EINVAL;
2260
2261 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2262 if (psta) {
2263 int flags = param->u.add_sta.flags;
2264
2265 psta->aid = param->u.add_sta.aid;
2266
2267 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
2268
2269
2270 if (WLAN_STA_WME & flags)
2271 psta->qos_option = 1;
2272 else
2273 psta->qos_option = 0;
2274
2275 if (pmlmepriv->qospriv.qos_option == 0)
2276 psta->qos_option = 0;
2277
2278
2279 if (WLAN_STA_HT & flags) {
2280 psta->htpriv.ht_option = true;
2281 psta->qos_option = 1;
2282 memcpy(&psta->htpriv.ht_cap, ¶m->u.add_sta.ht_cap,
2283 sizeof(struct ieee80211_ht_cap));
2284 } else {
2285 psta->htpriv.ht_option = false;
2286 }
2287
2288 if (!pmlmepriv->htpriv.ht_option)
2289 psta->htpriv.ht_option = false;
2290
2291 update_sta_info_apmode(padapter, psta);
2292 } else {
2293 ret = -ENOMEM;
2294 }
2295
2296 return ret;
2297}
2298
2299static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
2300{
2301 struct sta_info *psta = NULL;
2302 struct adapter *padapter = netdev_priv(dev);
2303 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2304 struct sta_priv *pstapriv = &padapter->stapriv;
2305 int updated = 0;
2306
2307 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE))
2308 return -EINVAL;
2309
2310 if (is_broadcast_ether_addr(param->sta_addr))
2311 return -EINVAL;
2312
2313 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2314 if (psta) {
2315 spin_lock_bh(&pstapriv->asoc_list_lock);
2316 if (!list_empty(&psta->asoc_list)) {
2317 list_del_init(&psta->asoc_list);
2318 pstapriv->asoc_list_cnt--;
2319 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
2320 }
2321 spin_unlock_bh(&pstapriv->asoc_list_lock);
2322 associated_clients_update(padapter, updated);
2323 psta = NULL;
2324 }
2325
2326 return 0;
2327}
2328
2329static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
2330{
2331 int ret = 0;
2332 struct sta_info *psta = NULL;
2333 struct adapter *padapter = netdev_priv(dev);
2334 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2335 struct sta_priv *pstapriv = &padapter->stapriv;
2336 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
2337 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
2338
2339 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE))
2340 return -EINVAL;
2341
2342 if (is_broadcast_ether_addr(param_ex->sta_addr))
2343 return -EINVAL;
2344
2345 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
2346 if (psta) {
2347 psta_data->aid = (u16)psta->aid;
2348 psta_data->capability = psta->capability;
2349 psta_data->flags = psta->flags;
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360 psta_data->sta_set = ((psta->nonerp_set) |
2361 (psta->no_short_slot_time_set << 1) |
2362 (psta->no_short_preamble_set << 2) |
2363 (psta->no_ht_gf_set << 3) |
2364 (psta->no_ht_set << 4) |
2365 (psta->ht_20mhz_set << 5));
2366 psta_data->tx_supp_rates_len = psta->bssratelen;
2367 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
2368 memcpy(&psta_data->ht_cap,
2369 &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
2370 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
2371 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
2372 psta_data->rx_drops = psta->sta_stats.rx_drops;
2373 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
2374 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
2375 psta_data->tx_drops = psta->sta_stats.tx_drops;
2376 } else {
2377 ret = -1;
2378 }
2379
2380 return ret;
2381}
2382
2383static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
2384{
2385 int ret = 0;
2386 struct sta_info *psta = NULL;
2387 struct adapter *padapter = netdev_priv(dev);
2388 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2389 struct sta_priv *pstapriv = &padapter->stapriv;
2390
2391 if (!check_fwstate(pmlmepriv, _FW_LINKED | WIFI_AP_STATE))
2392 return -EINVAL;
2393
2394 if (is_broadcast_ether_addr(param->sta_addr))
2395 return -EINVAL;
2396
2397 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2398 if (psta) {
2399 if (psta->wpa_ie[0] == WLAN_EID_RSN ||
2400 psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC) {
2401 int wpa_ie_len;
2402 int copy_len;
2403
2404 wpa_ie_len = psta->wpa_ie[1];
2405 copy_len = min_t(int, wpa_ie_len + 2, sizeof(psta->wpa_ie));
2406 param->u.wpa_ie.len = copy_len;
2407 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
2408 }
2409 } else {
2410 ret = -1;
2411 }
2412
2413 return ret;
2414}
2415
2416static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
2417{
2418 unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
2419 struct adapter *padapter = netdev_priv(dev);
2420 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2421 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2422 int ie_len;
2423
2424 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2425 return -EINVAL;
2426
2427 ie_len = len - 12 - 2;
2428
2429 kfree(pmlmepriv->wps_beacon_ie);
2430 pmlmepriv->wps_beacon_ie = NULL;
2431
2432 if (ie_len > 0) {
2433 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
2434 pmlmepriv->wps_beacon_ie_len = ie_len;
2435 if (!pmlmepriv->wps_beacon_ie)
2436 return -EINVAL;
2437
2438 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
2439
2440 update_beacon(padapter, WLAN_EID_VENDOR_SPECIFIC, wps_oui, true);
2441
2442 pmlmeext->bstart_bss = true;
2443 }
2444
2445 return 0;
2446}
2447
2448static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
2449{
2450 struct adapter *padapter = netdev_priv(dev);
2451 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2452 int ie_len;
2453
2454 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2455 return -EINVAL;
2456
2457 ie_len = len - 12 - 2;
2458
2459 kfree(pmlmepriv->wps_probe_resp_ie);
2460 pmlmepriv->wps_probe_resp_ie = NULL;
2461
2462 if (ie_len > 0) {
2463 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
2464 pmlmepriv->wps_probe_resp_ie_len = ie_len;
2465 if (!pmlmepriv->wps_probe_resp_ie)
2466 return -EINVAL;
2467 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
2468 }
2469
2470 return 0;
2471}
2472
2473static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
2474{
2475 struct adapter *padapter = netdev_priv(dev);
2476 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2477 int ie_len;
2478
2479 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2480 return -EINVAL;
2481
2482 ie_len = len - 12 - 2;
2483
2484 kfree(pmlmepriv->wps_assoc_resp_ie);
2485 pmlmepriv->wps_assoc_resp_ie = NULL;
2486
2487 if (ie_len > 0) {
2488 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
2489 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
2490 if (!pmlmepriv->wps_assoc_resp_ie)
2491 return -EINVAL;
2492
2493 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
2494 }
2495
2496 return 0;
2497}
2498
2499static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
2500{
2501 struct adapter *padapter = netdev_priv(dev);
2502 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2503 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2504 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2505
2506 u8 value;
2507
2508 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2509 return -EINVAL;
2510
2511 value = param->u.wpa_param.value;
2512
2513
2514 if (value != 1 && value != 2)
2515 value = 0;
2516 pmlmeinfo->hidden_ssid_mode = value;
2517 return 0;
2518}
2519
2520static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
2521{
2522 struct adapter *padapter = netdev_priv(dev);
2523 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2524
2525 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2526 return -EINVAL;
2527
2528 if (is_broadcast_ether_addr(param->sta_addr))
2529 return -EINVAL;
2530
2531 return rtw_acl_remove_sta(padapter, param->sta_addr);
2532}
2533
2534static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
2535{
2536 struct adapter *padapter = netdev_priv(dev);
2537 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2538
2539 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2540 return -EINVAL;
2541
2542 if (is_broadcast_ether_addr(param->sta_addr))
2543 return -EINVAL;
2544
2545 return rtw_acl_add_sta(padapter, param->sta_addr);
2546}
2547
2548static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
2549{
2550 struct adapter *padapter = netdev_priv(dev);
2551 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2552
2553 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
2554 return -EINVAL;
2555
2556 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
2557
2558 return 0;
2559}
2560
2561static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
2562{
2563 struct ieee_param *param;
2564 int ret = 0;
2565 struct adapter *padapter = netdev_priv(dev);
2566
2567
2568
2569
2570
2571
2572 if (!padapter->hw_init_completed)
2573 return -EPERM;
2574
2575 if (!p->pointer || p->length != sizeof(struct ieee_param))
2576 return -EINVAL;
2577
2578 param = memdup_user(p->pointer, p->length);
2579 if (IS_ERR(param))
2580 return PTR_ERR(param);
2581
2582 switch (param->cmd) {
2583 case RTL871X_HOSTAPD_FLUSH:
2584 ret = rtw_hostapd_sta_flush(dev);
2585 break;
2586 case RTL871X_HOSTAPD_ADD_STA:
2587 ret = rtw_add_sta(dev, param);
2588 break;
2589 case RTL871X_HOSTAPD_REMOVE_STA:
2590 ret = rtw_del_sta(dev, param);
2591 break;
2592 case RTL871X_HOSTAPD_SET_BEACON:
2593 ret = rtw_set_beacon(dev, param, p->length);
2594 break;
2595 case RTL871X_SET_ENCRYPTION:
2596 ret = rtw_set_encryption(dev, param, p->length);
2597 break;
2598 case RTL871X_HOSTAPD_GET_WPAIE_STA:
2599 ret = rtw_get_sta_wpaie(dev, param);
2600 break;
2601 case RTL871X_HOSTAPD_SET_WPS_BEACON:
2602 ret = rtw_set_wps_beacon(dev, param, p->length);
2603 break;
2604 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
2605 ret = rtw_set_wps_probe_resp(dev, param, p->length);
2606 break;
2607 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
2608 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
2609 break;
2610 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
2611 ret = rtw_set_hidden_ssid(dev, param, p->length);
2612 break;
2613 case RTL871X_HOSTAPD_GET_INFO_STA:
2614 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
2615 break;
2616 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
2617 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
2618 break;
2619 case RTL871X_HOSTAPD_ACL_ADD_STA:
2620 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
2621 break;
2622 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
2623 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
2624 break;
2625 default:
2626 ret = -EOPNOTSUPP;
2627 break;
2628 }
2629
2630 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2631 ret = -EFAULT;
2632 kfree(param);
2633 return ret;
2634}
2635#endif
2636
2637#include <rtw_android.h>
2638static int rtw_wx_set_priv(struct net_device *dev,
2639 struct iw_request_info *info,
2640 union iwreq_data *awrq, char *extra)
2641{
2642 int ret = 0;
2643 int len = 0;
2644 char *ext;
2645 struct adapter *padapter = netdev_priv(dev);
2646 struct iw_point *dwrq = (struct iw_point *)awrq;
2647
2648 if (dwrq->length == 0)
2649 return -EFAULT;
2650
2651 len = dwrq->length;
2652 ext = vmalloc(len);
2653 if (!ext)
2654 return -ENOMEM;
2655
2656 if (copy_from_user(ext, dwrq->pointer, len)) {
2657 vfree(ext);
2658 return -EFAULT;
2659 }
2660
2661
2662 if (dwrq->flags == 0x8766 && len > 8) {
2663 u32 cp_sz;
2664 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2665 u8 *probereq_wpsie = ext;
2666 int probereq_wpsie_len = len;
2667 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
2668
2669 if ((probereq_wpsie[0] == WLAN_EID_VENDOR_SPECIFIC) &&
2670 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
2671 cp_sz = min(probereq_wpsie_len, MAX_WPS_IE_LEN);
2672
2673 pmlmepriv->wps_probe_req_ie_len = 0;
2674 kfree(pmlmepriv->wps_probe_req_ie);
2675 pmlmepriv->wps_probe_req_ie = NULL;
2676
2677 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
2678 if (!pmlmepriv->wps_probe_req_ie) {
2679 pr_info("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
2680 ret = -EINVAL;
2681 goto FREE_EXT;
2682 }
2683 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
2684 pmlmepriv->wps_probe_req_ie_len = cp_sz;
2685 }
2686 goto FREE_EXT;
2687 }
2688
2689 if (len >= WEXT_CSCAN_HEADER_SIZE &&
2690 !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
2691 ret = rtw_wx_set_scan(dev, info, awrq, ext);
2692 goto FREE_EXT;
2693 }
2694
2695FREE_EXT:
2696
2697 vfree(ext);
2698
2699 return ret;
2700}
2701
2702static iw_handler rtw_handlers[] = {
2703 IW_HANDLER(SIOCGIWNAME, rtw_wx_get_name),
2704 IW_HANDLER(SIOCGIWFREQ, rtw_wx_get_freq),
2705 IW_HANDLER(SIOCSIWMODE, rtw_wx_set_mode),
2706 IW_HANDLER(SIOCGIWMODE, rtw_wx_get_mode),
2707 IW_HANDLER(SIOCGIWSENS, rtw_wx_get_sens),
2708 IW_HANDLER(SIOCGIWRANGE, rtw_wx_get_range),
2709 IW_HANDLER(SIOCSIWPRIV, rtw_wx_set_priv),
2710 IW_HANDLER(SIOCSIWAP, rtw_wx_set_wap),
2711 IW_HANDLER(SIOCGIWAP, rtw_wx_get_wap),
2712 IW_HANDLER(SIOCSIWMLME, rtw_wx_set_mlme),
2713 IW_HANDLER(SIOCSIWSCAN, rtw_wx_set_scan),
2714 IW_HANDLER(SIOCGIWSCAN, rtw_wx_get_scan),
2715 IW_HANDLER(SIOCSIWESSID, rtw_wx_set_essid),
2716 IW_HANDLER(SIOCGIWESSID, rtw_wx_get_essid),
2717 IW_HANDLER(SIOCGIWNICKN, rtw_wx_get_nick),
2718 IW_HANDLER(SIOCSIWRATE, rtw_wx_set_rate),
2719 IW_HANDLER(SIOCGIWRATE, rtw_wx_get_rate),
2720 IW_HANDLER(SIOCSIWRTS, rtw_wx_set_rts),
2721 IW_HANDLER(SIOCGIWRTS, rtw_wx_get_rts),
2722 IW_HANDLER(SIOCSIWFRAG, rtw_wx_set_frag),
2723 IW_HANDLER(SIOCGIWFRAG, rtw_wx_get_frag),
2724 IW_HANDLER(SIOCGIWRETRY, rtw_wx_get_retry),
2725 IW_HANDLER(SIOCSIWENCODE, rtw_wx_set_enc),
2726 IW_HANDLER(SIOCGIWENCODE, rtw_wx_get_enc),
2727 IW_HANDLER(SIOCGIWPOWER, rtw_wx_get_power),
2728 IW_HANDLER(SIOCSIWGENIE, rtw_wx_set_gen_ie),
2729 IW_HANDLER(SIOCSIWAUTH, rtw_wx_set_auth),
2730 IW_HANDLER(SIOCSIWENCODEEXT, rtw_wx_set_enc_ext),
2731 IW_HANDLER(SIOCSIWPMKSA, rtw_wx_set_pmkid),
2732};
2733
2734static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
2735{
2736 struct adapter *padapter = netdev_priv(dev);
2737 struct iw_statistics *piwstats = &padapter->iwstats;
2738
2739 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2740 piwstats->qual.qual = 0;
2741 piwstats->qual.level = 0;
2742 piwstats->qual.noise = 0;
2743 } else {
2744 piwstats->qual.level = padapter->recvpriv.signal_strength;
2745 piwstats->qual.qual = padapter->recvpriv.signal_qual;
2746 piwstats->qual.noise = padapter->recvpriv.noise;
2747 }
2748 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2749 return piwstats;
2750}
2751
2752struct iw_handler_def rtw_handlers_def = {
2753 .standard = rtw_handlers,
2754 .num_standard = ARRAY_SIZE(rtw_handlers),
2755 .get_wireless_stats = rtw_get_wireless_stats,
2756};
2757
2758int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2759{
2760 struct iwreq *wrq = (struct iwreq *)rq;
2761 int ret = 0;
2762
2763 switch (cmd) {
2764 case RTL_IOCTL_WPA_SUPPLICANT:
2765 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
2766 break;
2767#ifdef CONFIG_88EU_AP_MODE
2768 case RTL_IOCTL_HOSTAPD:
2769 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
2770 break;
2771#endif
2772 case (SIOCDEVPRIVATE + 1):
2773 ret = rtw_android_priv_cmd(dev, rq, cmd);
2774 break;
2775 default:
2776 ret = -EOPNOTSUPP;
2777 break;
2778 }
2779 return ret;
2780}
2781