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