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