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