1
2
3
4
5
6
7#define _IOCTL_LINUX_C_
8
9#include <linux/etherdevice.h>
10#include <drv_types.h>
11#include <rtw_debug.h>
12#include <rtw_mp.h>
13#include <hal_btcoex.h>
14#include <linux/jiffies.h>
15#include <linux/kernel.h>
16
17#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)
18
19#define SCAN_ITEM_SIZE 768
20#define MAX_CUSTOM_LEN 64
21#define RATE_COUNT 4
22
23
24#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
25#define WEXT_CSCAN_HEADER_SIZE 12
26#define WEXT_CSCAN_SSID_SECTION 'S'
27#define WEXT_CSCAN_CHANNEL_SECTION 'C'
28#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
29#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
30#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
31#define WEXT_CSCAN_TYPE_SECTION 'T'
32
33static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
34 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
35
36void indicate_wx_scan_complete_event(struct adapter *padapter)
37{
38 union iwreq_data wrqu;
39
40 memset(&wrqu, 0, sizeof(union iwreq_data));
41}
42
43
44void rtw_indicate_wx_assoc_event(struct adapter *padapter)
45{
46 union iwreq_data wrqu;
47 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
48 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
49 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
50 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
51
52 memset(&wrqu, 0, sizeof(union iwreq_data));
53
54 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
55
56 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
57 memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
58 else
59 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
60
61 netdev_dbg(padapter->pnetdev, "assoc success\n");
62}
63
64void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
65{
66 union iwreq_data wrqu;
67
68 memset(&wrqu, 0, sizeof(union iwreq_data));
69
70 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
71 eth_zero_addr(wrqu.ap_addr.sa_data);
72}
73
74static char *translate_scan(struct adapter *padapter,
75 struct iw_request_info *info, struct wlan_network *pnetwork,
76 char *start, char *stop)
77{
78 struct iw_event iwe;
79 u16 cap;
80 u32 ht_ielen = 0;
81 char *custom = NULL;
82 char *p;
83 u16 max_rate = 0, rate, ht_cap = false, vht_cap = false;
84 u32 i = 0;
85 u8 bw_40MHz = 0, short_GI = 0;
86 u16 mcs_rate = 0, vht_data_rate = 0;
87 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0 : 12);
88 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
89 u8 ss, sq;
90
91
92 iwe.cmd = SIOCGIWAP;
93 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
94
95 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
96 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
97
98
99 iwe.cmd = SIOCGIWESSID;
100 iwe.u.data.flags = 1;
101 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
102 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
103
104
105 if (pnetwork->network.Reserved[0] == 2) {
106 p = rtw_get_ie(&pnetwork->network.IEs[0], WLAN_EID_HT_CAPABILITY, &ht_ielen, pnetwork->network.IELength);
107 } else {
108 p = rtw_get_ie(&pnetwork->network.IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, pnetwork->network.IELength-12);
109 }
110 if (p && ht_ielen > 0) {
111 struct ieee80211_ht_cap *pht_capie;
112 ht_cap = true;
113 pht_capie = (struct ieee80211_ht_cap *)(p+2);
114 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
115 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
116 short_GI = (le16_to_cpu(pht_capie->cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
117 }
118
119
120 iwe.cmd = SIOCGIWNAME;
121 if (rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) {
122 if (ht_cap)
123 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
124 else
125 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
126 } else if (rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) {
127 if (ht_cap)
128 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
129 else
130 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
131 } else {
132 if (pnetwork->network.Configuration.DSConfig > 14) {
133 if (vht_cap)
134 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
135 else if (ht_cap)
136 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
137 else
138 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
139 } else {
140 if (ht_cap)
141 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
142 else
143 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
144 }
145 }
146
147 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
148
149
150 if (pnetwork->network.Reserved[0] == 2) {
151 cap = 0;
152 } else {
153 __le16 le_tmp;
154
155 iwe.cmd = SIOCGIWMODE;
156 memcpy((u8 *)&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
157 cap = le16_to_cpu(le_tmp);
158 }
159
160 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_ESS)) {
161 if (cap & WLAN_CAPABILITY_ESS)
162 iwe.u.mode = IW_MODE_MASTER;
163 else
164 iwe.u.mode = IW_MODE_ADHOC;
165
166 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
167 }
168
169 if (pnetwork->network.Configuration.DSConfig < 1 )
170 pnetwork->network.Configuration.DSConfig = 1;
171
172
173 iwe.cmd = SIOCGIWFREQ;
174 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
175 iwe.u.freq.e = 1;
176 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
177 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
178
179
180 iwe.cmd = SIOCGIWENCODE;
181 if (cap & WLAN_CAPABILITY_PRIVACY)
182 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
183 else
184 iwe.u.data.flags = IW_ENCODE_DISABLED;
185 iwe.u.data.length = 0;
186 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
187
188
189 max_rate = 0;
190 custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC);
191 if (!custom)
192 return start;
193 p = custom;
194 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
195 while (pnetwork->network.SupportedRates[i] != 0) {
196 rate = pnetwork->network.SupportedRates[i]&0x7F;
197 if (rate > max_rate)
198 max_rate = rate;
199 p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
200 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
201 i++;
202 }
203
204 if (vht_cap) {
205 max_rate = vht_data_rate;
206 } else if (ht_cap) {
207 if (mcs_rate & 0x8000)
208 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
209 else
210 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
211
212 max_rate = max_rate*2;
213 }
214
215 iwe.cmd = SIOCGIWRATE;
216 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
217 iwe.u.bitrate.value = max_rate * 500000;
218 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
219
220
221 if (pnetwork->network.Reserved[0] != 2) {
222 u8 *buf;
223 u8 wpa_ie[255], rsn_ie[255];
224 u16 wpa_len = 0, rsn_len = 0;
225 u8 *p;
226 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
227
228 buf = kzalloc(MAX_WPA_IE_LEN*2, GFP_ATOMIC);
229 if (!buf)
230 return start;
231 if (wpa_len > 0) {
232 p = buf;
233 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf), "wpa_ie =");
234 for (i = 0; i < wpa_len; i++)
235 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf),
236 "%02x", wpa_ie[i]);
237
238 if (wpa_len > 100) {
239 printk("-----------------Len %d----------------\n", wpa_len);
240 for (i = 0; i < wpa_len; i++)
241 printk("%02x ", wpa_ie[i]);
242 printk("\n");
243 printk("-----------------Len %d----------------\n", wpa_len);
244 }
245
246 memset(&iwe, 0, sizeof(iwe));
247 iwe.cmd = IWEVCUSTOM;
248 iwe.u.data.length = strlen(buf);
249 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
250
251 memset(&iwe, 0, sizeof(iwe));
252 iwe.cmd = IWEVGENIE;
253 iwe.u.data.length = wpa_len;
254 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
255 }
256 if (rsn_len > 0) {
257 p = buf;
258 memset(buf, 0, MAX_WPA_IE_LEN*2);
259 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf), "rsn_ie =");
260 for (i = 0; i < rsn_len; i++)
261 p += scnprintf(p, (MAX_WPA_IE_LEN * 2) - (p - buf),
262 "%02x", rsn_ie[i]);
263 memset(&iwe, 0, sizeof(iwe));
264 iwe.cmd = IWEVCUSTOM;
265 iwe.u.data.length = strlen(buf);
266 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
267
268 memset(&iwe, 0, sizeof(iwe));
269 iwe.cmd = IWEVGENIE;
270 iwe.u.data.length = rsn_len;
271 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
272 }
273 kfree(buf);
274 }
275
276 {
277 uint cnt = 0, total_ielen;
278 u8 *wpsie_ptr = NULL;
279 uint wps_ielen = 0;
280
281 u8 *ie_ptr;
282 total_ielen = pnetwork->network.IELength - ie_offset;
283
284 if (pnetwork->network.Reserved[0] == 2) {
285 ie_ptr = pnetwork->network.IEs;
286 total_ielen = pnetwork->network.IELength;
287 } else {
288 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
289 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
290 }
291
292 while (cnt < total_ielen) {
293 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
294 wpsie_ptr = &ie_ptr[cnt];
295 iwe.cmd = IWEVGENIE;
296 iwe.u.data.length = (u16)wps_ielen;
297 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
298 }
299 cnt += ie_ptr[cnt + 1] + 2;
300 }
301 }
302
303
304 iwe.cmd = IWEVQUAL;
305 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
306 | IW_QUAL_NOISE_INVALID;
307
308 if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
309 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
310 ss = padapter->recvpriv.signal_strength;
311 sq = padapter->recvpriv.signal_qual;
312 } else {
313 ss = pnetwork->network.PhyInfo.SignalStrength;
314 sq = pnetwork->network.PhyInfo.SignalQuality;
315 }
316
317
318 iwe.u.qual.level = (u8)ss;
319
320 iwe.u.qual.qual = (u8)sq;
321
322 iwe.u.qual.noise = 0;
323
324 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
325
326 {
327 u8 *buf;
328 u8 *pos;
329
330 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
331 if (!buf)
332 goto exit;
333
334 pos = pnetwork->network.Reserved;
335 memset(&iwe, 0, sizeof(iwe));
336 iwe.cmd = IWEVCUSTOM;
337 iwe.u.data.length = scnprintf(buf, MAX_WPA_IE_LEN, "fm =%02X%02X", pos[1], pos[0]);
338 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
339 kfree(buf);
340 }
341exit:
342 kfree(custom);
343
344 return start;
345}
346
347static int wpa_set_auth_algs(struct net_device *dev, u32 value)
348{
349 struct adapter *padapter = rtw_netdev_priv(dev);
350 int ret = 0;
351
352 if ((value & WLAN_AUTH_SHARED_KEY) && (value & WLAN_AUTH_OPEN)) {
353 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
354 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
355 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
356 } else if (value & WLAN_AUTH_SHARED_KEY) {
357 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
358
359 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
360 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
361 } else if (value & WLAN_AUTH_OPEN) {
362
363 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
364 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
365 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
366 }
367 } else {
368 ret = -EINVAL;
369 }
370
371 return ret;
372
373}
374
375static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
376{
377 int ret = 0;
378 u32 wep_key_idx, wep_key_len, wep_total_len;
379 struct ndis_802_11_wep *pwep = NULL;
380 struct adapter *padapter = rtw_netdev_priv(dev);
381 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
382 struct security_priv *psecuritypriv = &padapter->securitypriv;
383
384 param->u.crypt.err = 0;
385 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
386
387 if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
388 ret = -EINVAL;
389 goto exit;
390 }
391
392 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
393 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
394 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
395 if (param->u.crypt.idx >= WEP_KEYS ||
396 param->u.crypt.idx >= BIP_MAX_KEYID) {
397 ret = -EINVAL;
398 goto exit;
399 }
400 } else {
401 {
402 ret = -EINVAL;
403 goto exit;
404 }
405 }
406
407 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
408
409 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
410 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
411 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
412
413 wep_key_idx = param->u.crypt.idx;
414 wep_key_len = param->u.crypt.key_len;
415
416 if (wep_key_idx > WEP_KEYS)
417 return -EINVAL;
418
419 if (wep_key_len > 0) {
420 wep_key_len = wep_key_len <= 5 ? 5 : 13;
421 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
422 pwep = kzalloc(wep_total_len, GFP_KERNEL);
423 if (!pwep) {
424 ret = -ENOMEM;
425 goto exit;
426 }
427
428 pwep->KeyLength = wep_key_len;
429 pwep->Length = wep_total_len;
430
431 if (wep_key_len == 13) {
432 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
433 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
434 }
435 } else {
436 ret = -EINVAL;
437 goto exit;
438 }
439
440 pwep->KeyIndex = wep_key_idx;
441 pwep->KeyIndex |= 0x80000000;
442
443 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
444
445 if (param->u.crypt.set_tx) {
446 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
447 ret = -EOPNOTSUPP;
448 } else {
449
450
451
452 if (wep_key_idx >= WEP_KEYS) {
453 ret = -EOPNOTSUPP;
454 goto exit;
455 }
456
457 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
458 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
459 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true);
460 }
461
462 goto exit;
463 }
464
465 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
466 struct sta_info *psta, *pbcmc_sta;
467 struct sta_priv *pstapriv = &padapter->stapriv;
468
469 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) {
470 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
471 if (psta == NULL) {
472
473 } else {
474
475 if (strcmp(param->u.crypt.alg, "none") != 0)
476 psta->ieee8021x_blocked = false;
477
478 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
479 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
480 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
481 }
482
483 if (param->u.crypt.set_tx == 1) {
484 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
485
486 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
487
488 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
489 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
490
491 padapter->securitypriv.busetkipkey = false;
492
493 }
494
495 rtw_setstakey_cmd(padapter, psta, true, true);
496 } else {
497 if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
498 memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
499
500 if (param->u.crypt.key_len > 16) {
501 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
502 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
503 }
504 padapter->securitypriv.binstallGrpkey = true;
505
506 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
507
508 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, true);
509 } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
510
511
512 memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
513
514
515
516
517 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
518 padapter->securitypriv.binstallBIPkey = true;
519 }
520 }
521 }
522
523 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
524 if (pbcmc_sta == NULL) {
525
526 } else {
527
528 if (strcmp(param->u.crypt.alg, "none") != 0)
529 pbcmc_sta->ieee8021x_blocked = false;
530
531 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
532 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled)) {
533 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
534 }
535 }
536 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
537
538 }
539 }
540
541exit:
542
543 kfree(pwep);
544 return ret;
545}
546
547static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
548{
549 u8 *buf = NULL;
550 int group_cipher = 0, pairwise_cipher = 0;
551 int ret = 0;
552 u8 null_addr[] = {0, 0, 0, 0, 0, 0};
553
554 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
555 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
556 if (pie == NULL)
557 return ret;
558 else
559 return -EINVAL;
560 }
561
562 if (ielen) {
563 buf = rtw_zmalloc(ielen);
564 if (buf == NULL) {
565 ret = -ENOMEM;
566 goto exit;
567 }
568
569 memcpy(buf, pie, ielen);
570
571 if (ielen < RSN_HEADER_LEN) {
572 ret = -1;
573 goto exit;
574 }
575
576 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
577 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
578 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
579 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
580 }
581
582 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
583 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
584 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
585 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
586 }
587
588 if (group_cipher == 0)
589 group_cipher = WPA_CIPHER_NONE;
590 if (pairwise_cipher == 0)
591 pairwise_cipher = WPA_CIPHER_NONE;
592
593 switch (group_cipher) {
594 case WPA_CIPHER_NONE:
595 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
596 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
597 break;
598 case WPA_CIPHER_WEP40:
599 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
600 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
601 break;
602 case WPA_CIPHER_TKIP:
603 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
604 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
605 break;
606 case WPA_CIPHER_CCMP:
607 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
608 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
609 break;
610 case WPA_CIPHER_WEP104:
611 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
612 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
613 break;
614 }
615
616 switch (pairwise_cipher) {
617 case WPA_CIPHER_NONE:
618 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
619 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
620 break;
621 case WPA_CIPHER_WEP40:
622 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
623 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
624 break;
625 case WPA_CIPHER_TKIP:
626 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
627 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
628 break;
629 case WPA_CIPHER_CCMP:
630 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
631 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
632 break;
633 case WPA_CIPHER_WEP104:
634 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
635 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
636 break;
637 }
638
639 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
640 {
641 u16 cnt = 0;
642 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
643
644 while (cnt < ielen) {
645 eid = buf[cnt];
646
647 if ((eid == WLAN_EID_VENDOR_SPECIFIC) && (!memcmp(&buf[cnt+2], wps_oui, 4))) {
648 padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
649
650 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
651
652 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
653
654 cnt += buf[cnt+1]+2;
655
656 break;
657 } else {
658 cnt += buf[cnt+1]+2;
659 }
660 }
661 }
662 }
663
664
665 if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
666 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
667 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
668
669
670 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
671
672exit:
673
674 kfree(buf);
675
676 return ret;
677}
678
679static int rtw_wx_get_name(struct net_device *dev,
680 struct iw_request_info *info,
681 union iwreq_data *wrqu, char *extra)
682{
683 struct adapter *padapter = rtw_netdev_priv(dev);
684 u32 ht_ielen = 0;
685 char *p;
686 u8 ht_cap = false, vht_cap = false;
687 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
688 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
689 NDIS_802_11_RATES_EX *prates = NULL;
690
691 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
692
693 p = rtw_get_ie(&pcur_bss->IEs[12], WLAN_EID_HT_CAPABILITY, &ht_ielen, pcur_bss->IELength-12);
694 if (p && ht_ielen > 0)
695 ht_cap = true;
696
697 prates = &pcur_bss->SupportedRates;
698
699 if (rtw_is_cckratesonly_included((u8 *)prates)) {
700 if (ht_cap)
701 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
702 else
703 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
704 } else if (rtw_is_cckrates_included((u8 *)prates)) {
705 if (ht_cap)
706 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
707 else
708 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
709 } else {
710 if (pcur_bss->Configuration.DSConfig > 14) {
711 if (vht_cap)
712 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
713 else if (ht_cap)
714 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
715 else
716 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
717 } else {
718 if (ht_cap)
719 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
720 else
721 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
722 }
723 }
724 } else {
725
726
727 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
728 }
729 return 0;
730}
731
732static int rtw_wx_set_freq(struct net_device *dev,
733 struct iw_request_info *info,
734 union iwreq_data *wrqu, char *extra)
735{
736 return 0;
737}
738
739static int rtw_wx_get_freq(struct net_device *dev,
740 struct iw_request_info *info,
741 union iwreq_data *wrqu, char *extra)
742{
743 struct adapter *padapter = rtw_netdev_priv(dev);
744 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
745 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
746
747 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
748
749 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
750 wrqu->freq.e = 1;
751 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
752
753 } else {
754 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
755 wrqu->freq.e = 1;
756 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
757 }
758
759 return 0;
760}
761
762static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
763 union iwreq_data *wrqu, char *b)
764{
765 struct adapter *padapter = rtw_netdev_priv(dev);
766 enum ndis_802_11_network_infrastructure networkType;
767 int ret = 0;
768
769 if (_FAIL == rtw_pwr_wakeup(padapter)) {
770 ret = -EPERM;
771 goto exit;
772 }
773
774 if (!padapter->hw_init_completed) {
775 ret = -EPERM;
776 goto exit;
777 }
778
779 switch (wrqu->mode) {
780 case IW_MODE_AUTO:
781 networkType = Ndis802_11AutoUnknown;
782 break;
783 case IW_MODE_ADHOC:
784 networkType = Ndis802_11IBSS;
785 break;
786 case IW_MODE_MASTER:
787 networkType = Ndis802_11APMode;
788
789 break;
790 case IW_MODE_INFRA:
791 networkType = Ndis802_11Infrastructure;
792 break;
793 default:
794 ret = -EINVAL;
795 goto exit;
796 }
797
798
799
800
801
802
803
804
805
806
807
808
809 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == false) {
810
811 ret = -EPERM;
812 goto exit;
813
814 }
815
816 rtw_setopmode_cmd(padapter, networkType, true);
817
818exit:
819 return ret;
820}
821
822static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
823 union iwreq_data *wrqu, char *b)
824{
825 struct adapter *padapter = rtw_netdev_priv(dev);
826 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
827
828 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
829 wrqu->mode = IW_MODE_INFRA;
830 } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) ||
831 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) {
832 wrqu->mode = IW_MODE_ADHOC;
833 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
834 wrqu->mode = IW_MODE_MASTER;
835 } else {
836 wrqu->mode = IW_MODE_AUTO;
837 }
838 return 0;
839}
840
841
842static int rtw_wx_set_pmkid(struct net_device *dev,
843 struct iw_request_info *a,
844 union iwreq_data *wrqu, char *extra)
845{
846 struct adapter *padapter = rtw_netdev_priv(dev);
847 u8 j, blInserted = false;
848 int intReturn = false;
849 struct security_priv *psecuritypriv = &padapter->securitypriv;
850 struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
851 u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
852 u8 strIssueBssid[ETH_ALEN] = { 0x00 };
853
854
855
856
857
858
859
860
861 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
862 if (pPMK->cmd == IW_PMKSA_ADD) {
863 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
864 return intReturn;
865 else
866 intReturn = true;
867
868 blInserted = false;
869
870
871 for (j = 0; j < NUM_PMKID_CACHE; j++) {
872 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
873
874 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
875 psecuritypriv->PMKIDList[j].bUsed = true;
876 psecuritypriv->PMKIDIndex = j+1;
877 blInserted = true;
878 break;
879 }
880 }
881
882 if (!blInserted) {
883
884 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
885 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
886
887 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
888 psecuritypriv->PMKIDIndex++;
889 if (psecuritypriv->PMKIDIndex == 16)
890 psecuritypriv->PMKIDIndex = 0;
891 }
892 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
893 intReturn = true;
894 for (j = 0; j < NUM_PMKID_CACHE; j++) {
895 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
896
897 eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid);
898 psecuritypriv->PMKIDList[j].bUsed = false;
899 break;
900 }
901 }
902 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
903 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
904 psecuritypriv->PMKIDIndex = 0;
905 intReturn = true;
906 }
907 return intReturn;
908}
909
910static int rtw_wx_get_sens(struct net_device *dev,
911 struct iw_request_info *info,
912 union iwreq_data *wrqu, char *extra)
913{
914 {
915 wrqu->sens.value = 0;
916 wrqu->sens.fixed = 0;
917 wrqu->sens.disabled = 1;
918 }
919 return 0;
920}
921
922static int rtw_wx_get_range(struct net_device *dev,
923 struct iw_request_info *info,
924 union iwreq_data *wrqu, char *extra)
925{
926 struct iw_range *range = (struct iw_range *)extra;
927 struct adapter *padapter = rtw_netdev_priv(dev);
928 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
929
930 u16 val;
931 int i;
932
933 wrqu->data.length = sizeof(*range);
934 memset(range, 0, sizeof(*range));
935
936
937
938
939
940
941
942
943
944
945 range->throughput = 5 * 1000 * 1000;
946
947
948
949
950 range->max_qual.qual = 100;
951 range->max_qual.level = 100;
952 range->max_qual.noise = 100;
953 range->max_qual.updated = 7;
954
955
956 range->avg_qual.qual = 92;
957
958 range->avg_qual.level = 256 - 78;
959 range->avg_qual.noise = 0;
960 range->avg_qual.updated = 7;
961
962 range->num_bitrates = RATE_COUNT;
963
964 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
965 range->bitrate[i] = rtw_rates[i];
966
967 range->min_frag = MIN_FRAG_THRESHOLD;
968 range->max_frag = MAX_FRAG_THRESHOLD;
969
970 range->pm_capa = 0;
971
972 range->we_version_compiled = WIRELESS_EXT;
973 range->we_version_source = 16;
974
975 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
976
977
978 if (pmlmeext->channel_set[i].ChannelNum != 0) {
979 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
980 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
981 range->freq[val].e = 1;
982 val++;
983 }
984
985 if (val == IW_MAX_FREQUENCIES)
986 break;
987 }
988
989 range->num_channels = val;
990 range->num_frequency = val;
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1009 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1010
1011 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID |
1012 IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
1013
1014 return 0;
1015}
1016
1017
1018
1019
1020
1021
1022static int rtw_wx_set_wap(struct net_device *dev,
1023 struct iw_request_info *info,
1024 union iwreq_data *awrq,
1025 char *extra)
1026{
1027 uint ret = 0;
1028 struct adapter *padapter = rtw_netdev_priv(dev);
1029 struct sockaddr *temp = (struct sockaddr *)awrq;
1030 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1031 struct list_head *phead;
1032 u8 *dst_bssid, *src_bssid;
1033 struct __queue *queue = &(pmlmepriv->scanned_queue);
1034 struct wlan_network *pnetwork = NULL;
1035 enum ndis_802_11_authentication_mode authmode;
1036
1037 rtw_ps_deny(padapter, PS_DENY_JOIN);
1038 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1039 ret = -1;
1040 goto exit;
1041 }
1042
1043 if (!padapter->bup) {
1044 ret = -1;
1045 goto exit;
1046 }
1047
1048
1049 if (temp->sa_family != ARPHRD_ETHER) {
1050 ret = -EINVAL;
1051 goto exit;
1052 }
1053
1054 authmode = padapter->securitypriv.ndisauthtype;
1055 spin_lock_bh(&queue->lock);
1056 phead = get_list_head(queue);
1057 list_for_each(pmlmepriv->pscanned, phead) {
1058 pnetwork = list_entry(pmlmepriv->pscanned,
1059 struct wlan_network, list);
1060
1061 dst_bssid = pnetwork->network.MacAddress;
1062
1063 src_bssid = temp->sa_data;
1064
1065 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
1066 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1067 ret = -1;
1068 spin_unlock_bh(&queue->lock);
1069 goto exit;
1070 }
1071 break;
1072 }
1073
1074 }
1075 spin_unlock_bh(&queue->lock);
1076
1077 rtw_set_802_11_authentication_mode(padapter, authmode);
1078
1079 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == false) {
1080 ret = -1;
1081 goto exit;
1082 }
1083
1084exit:
1085
1086 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1087
1088 return ret;
1089}
1090
1091static int rtw_wx_get_wap(struct net_device *dev,
1092 struct iw_request_info *info,
1093 union iwreq_data *wrqu, char *extra)
1094{
1095
1096 struct adapter *padapter = rtw_netdev_priv(dev);
1097 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1098 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1099
1100 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1101
1102 eth_zero_addr(wrqu->ap_addr.sa_data);
1103
1104 if (((check_fwstate(pmlmepriv, _FW_LINKED)) == true) ||
1105 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) ||
1106 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == true)) {
1107 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1108 } else {
1109 eth_zero_addr(wrqu->ap_addr.sa_data);
1110 }
1111
1112 return 0;
1113}
1114
1115static int rtw_wx_set_mlme(struct net_device *dev,
1116 struct iw_request_info *info,
1117 union iwreq_data *wrqu, char *extra)
1118{
1119 int ret = 0;
1120 struct adapter *padapter = rtw_netdev_priv(dev);
1121 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1122
1123
1124 if (mlme == NULL)
1125 return -1;
1126
1127 switch (mlme->cmd) {
1128 case IW_MLME_DEAUTH:
1129 if (!rtw_set_802_11_disassociate(padapter))
1130 ret = -1;
1131 break;
1132 case IW_MLME_DISASSOC:
1133 if (!rtw_set_802_11_disassociate(padapter))
1134 ret = -1;
1135 break;
1136 default:
1137 return -EOPNOTSUPP;
1138 }
1139
1140 return ret;
1141}
1142
1143static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1144 union iwreq_data *wrqu, char *extra)
1145{
1146 u8 _status = false;
1147 int ret = 0;
1148 struct adapter *padapter = rtw_netdev_priv(dev);
1149 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1150 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1151
1152 rtw_ps_deny(padapter, PS_DENY_SCAN);
1153 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1154 ret = -1;
1155 goto exit;
1156 }
1157
1158 if (padapter->bDriverStopped) {
1159 ret = -1;
1160 goto exit;
1161 }
1162
1163 if (!padapter->bup) {
1164 ret = -1;
1165 goto exit;
1166 }
1167
1168 if (!padapter->hw_init_completed) {
1169 ret = -1;
1170 goto exit;
1171 }
1172
1173
1174
1175
1176 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1177 indicate_wx_scan_complete_event(padapter);
1178 goto exit;
1179 }
1180
1181 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) {
1182 indicate_wx_scan_complete_event(padapter);
1183 goto exit;
1184 }
1185
1186 memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
1187
1188 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1189 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1190
1191 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1192 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1193
1194 memcpy(ssid[0].Ssid, req->essid, len);
1195 ssid[0].SsidLength = len;
1196
1197 spin_lock_bh(&pmlmepriv->lock);
1198
1199 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1200
1201 spin_unlock_bh(&pmlmepriv->lock);
1202
1203 }
1204
1205 } else if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
1206 && !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1207 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
1208 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
1209 char section;
1210 char sec_len;
1211 int ssid_index = 0;
1212
1213 while (len >= 1) {
1214 section = *(pos++); len -= 1;
1215
1216 switch (section) {
1217 case WEXT_CSCAN_SSID_SECTION:
1218 if (len < 1) {
1219 len = 0;
1220 break;
1221 }
1222
1223 sec_len = *(pos++); len -= 1;
1224
1225 if (sec_len > 0 && sec_len <= len) {
1226 ssid[ssid_index].SsidLength = sec_len;
1227 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1228 ssid_index++;
1229 }
1230
1231 pos += sec_len; len -= sec_len;
1232 break;
1233
1234
1235 case WEXT_CSCAN_CHANNEL_SECTION:
1236 pos += 1; len -= 1;
1237 break;
1238 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1239 pos += 2; len -= 2;
1240 break;
1241 case WEXT_CSCAN_PASV_DWELL_SECTION:
1242 pos += 2; len -= 2;
1243 break;
1244 case WEXT_CSCAN_HOME_DWELL_SECTION:
1245 pos += 2; len -= 2;
1246 break;
1247 case WEXT_CSCAN_TYPE_SECTION:
1248 pos += 1; len -= 1;
1249 break;
1250 default:
1251 len = 0;
1252 }
1253 }
1254
1255
1256 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1257
1258 } else {
1259 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1260 }
1261
1262 if (_status == false)
1263 ret = -1;
1264
1265exit:
1266
1267 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
1268
1269 return ret;
1270}
1271
1272static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1273 union iwreq_data *wrqu, char *extra)
1274{
1275 struct list_head *plist, *phead;
1276 struct adapter *padapter = rtw_netdev_priv(dev);
1277 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1278 struct __queue *queue = &(pmlmepriv->scanned_queue);
1279 struct wlan_network *pnetwork = NULL;
1280 char *ev = extra;
1281 char *stop = ev + wrqu->data.length;
1282 u32 ret = 0;
1283 signed int wait_status;
1284
1285 if (adapter_to_pwrctl(padapter)->brfoffbyhw && padapter->bDriverStopped) {
1286 ret = -EINVAL;
1287 goto exit;
1288 }
1289
1290 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1291
1292 if (check_fwstate(pmlmepriv, wait_status))
1293 return -EAGAIN;
1294
1295 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1296
1297 phead = get_list_head(queue);
1298 list_for_each(plist, phead) {
1299 if ((stop - ev) < SCAN_ITEM_SIZE) {
1300 ret = -E2BIG;
1301 break;
1302 }
1303
1304 pnetwork = list_entry(plist, struct wlan_network, list);
1305
1306
1307 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1308 && true == rtw_validate_ssid(&(pnetwork->network.Ssid))) {
1309
1310 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1311 }
1312
1313 }
1314
1315 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1316
1317 wrqu->data.length = ev-extra;
1318 wrqu->data.flags = 0;
1319
1320exit:
1321
1322 return ret;
1323
1324}
1325
1326
1327
1328
1329
1330
1331static int rtw_wx_set_essid(struct net_device *dev,
1332 struct iw_request_info *a,
1333 union iwreq_data *wrqu, char *extra)
1334{
1335 struct adapter *padapter = rtw_netdev_priv(dev);
1336 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1337 struct __queue *queue = &pmlmepriv->scanned_queue;
1338 struct list_head *phead;
1339 struct wlan_network *pnetwork = NULL;
1340 enum ndis_802_11_authentication_mode authmode;
1341 struct ndis_802_11_ssid ndis_ssid;
1342 u8 *dst_ssid, *src_ssid;
1343
1344 uint ret = 0, len;
1345
1346 rtw_ps_deny(padapter, PS_DENY_JOIN);
1347 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1348 ret = -1;
1349 goto exit;
1350 }
1351
1352 if (!padapter->bup) {
1353 ret = -1;
1354 goto exit;
1355 }
1356
1357 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1358 ret = -E2BIG;
1359 goto exit;
1360 }
1361
1362 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1363 ret = -1;
1364 goto exit;
1365 }
1366
1367 authmode = padapter->securitypriv.ndisauthtype;
1368 if (wrqu->essid.flags && wrqu->essid.length) {
1369 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
1370
1371 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1372 ndis_ssid.SsidLength = len;
1373 memcpy(ndis_ssid.Ssid, extra, len);
1374 src_ssid = ndis_ssid.Ssid;
1375
1376 spin_lock_bh(&queue->lock);
1377 phead = get_list_head(queue);
1378 list_for_each(pmlmepriv->pscanned, phead) {
1379 pnetwork = list_entry(pmlmepriv->pscanned,
1380 struct wlan_network, list);
1381
1382 dst_ssid = pnetwork->network.Ssid.Ssid;
1383
1384 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
1385 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
1386 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
1387 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1388 continue;
1389 }
1390
1391 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == false) {
1392 ret = -1;
1393 spin_unlock_bh(&queue->lock);
1394 goto exit;
1395 }
1396
1397 break;
1398 }
1399 }
1400 spin_unlock_bh(&queue->lock);
1401 rtw_set_802_11_authentication_mode(padapter, authmode);
1402
1403 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false) {
1404 ret = -1;
1405 goto exit;
1406 }
1407 }
1408
1409exit:
1410
1411 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1412
1413 return ret;
1414}
1415
1416static int rtw_wx_get_essid(struct net_device *dev,
1417 struct iw_request_info *a,
1418 union iwreq_data *wrqu, char *extra)
1419{
1420 u32 len, ret = 0;
1421 struct adapter *padapter = rtw_netdev_priv(dev);
1422 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1423 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1424
1425 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
1426 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
1427 len = pcur_bss->Ssid.SsidLength;
1428
1429 wrqu->essid.length = len;
1430
1431 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1432
1433 wrqu->essid.flags = 1;
1434 } else {
1435 ret = -1;
1436 goto exit;
1437 }
1438
1439exit:
1440 return ret;
1441}
1442
1443static int rtw_wx_set_rate(struct net_device *dev,
1444 struct iw_request_info *a,
1445 union iwreq_data *wrqu, char *extra)
1446{
1447 int i, ret = 0;
1448 struct adapter *padapter = rtw_netdev_priv(dev);
1449 u8 datarates[NumRates];
1450 u32 target_rate = wrqu->bitrate.value;
1451 u32 fixed = wrqu->bitrate.fixed;
1452 u32 ratevalue = 0;
1453 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1454
1455 if (target_rate == -1) {
1456 ratevalue = 11;
1457 goto set_rate;
1458 }
1459 target_rate = target_rate/100000;
1460
1461 switch (target_rate) {
1462 case 10:
1463 ratevalue = 0;
1464 break;
1465 case 20:
1466 ratevalue = 1;
1467 break;
1468 case 55:
1469 ratevalue = 2;
1470 break;
1471 case 60:
1472 ratevalue = 3;
1473 break;
1474 case 90:
1475 ratevalue = 4;
1476 break;
1477 case 110:
1478 ratevalue = 5;
1479 break;
1480 case 120:
1481 ratevalue = 6;
1482 break;
1483 case 180:
1484 ratevalue = 7;
1485 break;
1486 case 240:
1487 ratevalue = 8;
1488 break;
1489 case 360:
1490 ratevalue = 9;
1491 break;
1492 case 480:
1493 ratevalue = 10;
1494 break;
1495 case 540:
1496 ratevalue = 11;
1497 break;
1498 default:
1499 ratevalue = 11;
1500 break;
1501 }
1502
1503set_rate:
1504
1505 for (i = 0; i < NumRates; i++) {
1506 if (ratevalue == mpdatarate[i]) {
1507 datarates[i] = mpdatarate[i];
1508 if (fixed == 0)
1509 break;
1510 } else {
1511 datarates[i] = 0xff;
1512 }
1513 }
1514
1515 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1516 ret = -1;
1517
1518 return ret;
1519}
1520
1521static int rtw_wx_get_rate(struct net_device *dev,
1522 struct iw_request_info *info,
1523 union iwreq_data *wrqu, char *extra)
1524{
1525 u16 max_rate = 0;
1526
1527 max_rate = rtw_get_cur_max_rate(rtw_netdev_priv(dev));
1528
1529 if (max_rate == 0)
1530 return -EPERM;
1531
1532 wrqu->bitrate.fixed = 0;
1533 wrqu->bitrate.value = max_rate * 100000;
1534
1535 return 0;
1536}
1537
1538static int rtw_wx_set_rts(struct net_device *dev,
1539 struct iw_request_info *info,
1540 union iwreq_data *wrqu, char *extra)
1541{
1542 struct adapter *padapter = rtw_netdev_priv(dev);
1543
1544 if (wrqu->rts.disabled)
1545 padapter->registrypriv.rts_thresh = 2347;
1546 else {
1547 if (wrqu->rts.value < 0 ||
1548 wrqu->rts.value > 2347)
1549 return -EINVAL;
1550
1551 padapter->registrypriv.rts_thresh = wrqu->rts.value;
1552 }
1553
1554 return 0;
1555}
1556
1557static int rtw_wx_get_rts(struct net_device *dev,
1558 struct iw_request_info *info,
1559 union iwreq_data *wrqu, char *extra)
1560{
1561 struct adapter *padapter = rtw_netdev_priv(dev);
1562
1563 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1564 wrqu->rts.fixed = 0;
1565
1566
1567 return 0;
1568}
1569
1570static int rtw_wx_set_frag(struct net_device *dev,
1571 struct iw_request_info *info,
1572 union iwreq_data *wrqu, char *extra)
1573{
1574 struct adapter *padapter = rtw_netdev_priv(dev);
1575
1576 if (wrqu->frag.disabled)
1577 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1578 else {
1579 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1580 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1581 return -EINVAL;
1582
1583 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1584 }
1585
1586 return 0;
1587
1588}
1589
1590static int rtw_wx_get_frag(struct net_device *dev,
1591 struct iw_request_info *info,
1592 union iwreq_data *wrqu, char *extra)
1593{
1594 struct adapter *padapter = rtw_netdev_priv(dev);
1595
1596 wrqu->frag.value = padapter->xmitpriv.frag_len;
1597 wrqu->frag.fixed = 0;
1598
1599
1600 return 0;
1601}
1602
1603static int rtw_wx_get_retry(struct net_device *dev,
1604 struct iw_request_info *info,
1605 union iwreq_data *wrqu, char *extra)
1606{
1607
1608
1609
1610 wrqu->retry.value = 7;
1611 wrqu->retry.fixed = 0;
1612 wrqu->retry.disabled = 1;
1613
1614 return 0;
1615
1616}
1617
1618static int rtw_wx_set_enc(struct net_device *dev,
1619 struct iw_request_info *info,
1620 union iwreq_data *wrqu, char *keybuf)
1621{
1622 u32 key, ret = 0;
1623 u32 keyindex_provided;
1624 struct ndis_802_11_wep wep;
1625 enum ndis_802_11_authentication_mode authmode;
1626
1627 struct iw_point *erq = &(wrqu->encoding);
1628 struct adapter *padapter = rtw_netdev_priv(dev);
1629 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1630
1631 memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1632
1633 key = erq->flags & IW_ENCODE_INDEX;
1634
1635 if (erq->flags & IW_ENCODE_DISABLED) {
1636 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1637 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1638 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1639 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1640 authmode = Ndis802_11AuthModeOpen;
1641 padapter->securitypriv.ndisauthtype = authmode;
1642
1643 goto exit;
1644 }
1645
1646 if (key) {
1647 if (key > WEP_KEYS)
1648 return -EINVAL;
1649 key--;
1650 keyindex_provided = 1;
1651 } else {
1652 keyindex_provided = 0;
1653 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1654 }
1655
1656
1657 if (erq->flags & IW_ENCODE_OPEN) {
1658 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1659
1660 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1661
1662 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1663 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1664 authmode = Ndis802_11AuthModeOpen;
1665 padapter->securitypriv.ndisauthtype = authmode;
1666 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1667 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1668
1669 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1670
1671 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1672 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1673 authmode = Ndis802_11AuthModeShared;
1674 padapter->securitypriv.ndisauthtype = authmode;
1675 } else {
1676 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1677 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1678 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1679 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1680 authmode = Ndis802_11AuthModeOpen;
1681 padapter->securitypriv.ndisauthtype = authmode;
1682 }
1683
1684 wep.KeyIndex = key;
1685 if (erq->length > 0) {
1686 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1687
1688 wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
1689 } else {
1690 wep.KeyLength = 0;
1691
1692 if (keyindex_provided == 1) {
1693 padapter->securitypriv.dot11PrivacyKeyIndex = key;
1694
1695 switch (padapter->securitypriv.dot11DefKeylen[key]) {
1696 case 5:
1697 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1698 break;
1699 case 13:
1700 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1701 break;
1702 default:
1703 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1704 break;
1705 }
1706
1707 goto exit;
1708
1709 }
1710
1711 }
1712
1713 wep.KeyIndex |= 0x80000000;
1714
1715 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1716
1717 if (rtw_set_802_11_add_wep(padapter, &wep) == false) {
1718 if (rf_on == pwrpriv->rf_pwrstate)
1719 ret = -EOPNOTSUPP;
1720 goto exit;
1721 }
1722
1723exit:
1724 return ret;
1725}
1726
1727static int rtw_wx_get_enc(struct net_device *dev,
1728 struct iw_request_info *info,
1729 union iwreq_data *wrqu, char *keybuf)
1730{
1731 uint key, ret = 0;
1732 struct adapter *padapter = rtw_netdev_priv(dev);
1733 struct iw_point *erq = &(wrqu->encoding);
1734 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1735
1736 if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
1737 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true) {
1738 erq->length = 0;
1739 erq->flags |= IW_ENCODE_DISABLED;
1740 return 0;
1741 }
1742 }
1743
1744
1745 key = erq->flags & IW_ENCODE_INDEX;
1746
1747 if (key) {
1748 if (key > WEP_KEYS)
1749 return -EINVAL;
1750 key--;
1751 } else {
1752 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1753 }
1754
1755 erq->flags = key + 1;
1756
1757
1758
1759
1760
1761
1762 switch (padapter->securitypriv.ndisencryptstatus) {
1763 case Ndis802_11EncryptionNotSupported:
1764 case Ndis802_11EncryptionDisabled:
1765 erq->length = 0;
1766 erq->flags |= IW_ENCODE_DISABLED;
1767 break;
1768 case Ndis802_11Encryption1Enabled:
1769 erq->length = padapter->securitypriv.dot11DefKeylen[key];
1770
1771 if (erq->length) {
1772 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1773
1774 erq->flags |= IW_ENCODE_ENABLED;
1775
1776 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
1777 erq->flags |= IW_ENCODE_OPEN;
1778 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
1779 erq->flags |= IW_ENCODE_RESTRICTED;
1780 } else {
1781 erq->length = 0;
1782 erq->flags |= IW_ENCODE_DISABLED;
1783 }
1784 break;
1785 case Ndis802_11Encryption2Enabled:
1786 case Ndis802_11Encryption3Enabled:
1787 erq->length = 16;
1788 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
1789 break;
1790 default:
1791 erq->length = 0;
1792 erq->flags |= IW_ENCODE_DISABLED;
1793 break;
1794 }
1795 return ret;
1796}
1797
1798static int rtw_wx_get_power(struct net_device *dev,
1799 struct iw_request_info *info,
1800 union iwreq_data *wrqu, char *extra)
1801{
1802
1803
1804 wrqu->power.value = 0;
1805 wrqu->power.fixed = 0;
1806 wrqu->power.disabled = 1;
1807
1808 return 0;
1809}
1810
1811static int rtw_wx_set_gen_ie(struct net_device *dev,
1812 struct iw_request_info *info,
1813 union iwreq_data *wrqu, char *extra)
1814{
1815 struct adapter *padapter = rtw_netdev_priv(dev);
1816
1817 return rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
1818}
1819
1820static int rtw_wx_set_auth(struct net_device *dev,
1821 struct iw_request_info *info,
1822 union iwreq_data *wrqu, char *extra)
1823{
1824 struct adapter *padapter = rtw_netdev_priv(dev);
1825 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1826 int ret = 0;
1827
1828 switch (param->flags & IW_AUTH_INDEX) {
1829 case IW_AUTH_WPA_VERSION:
1830 break;
1831 case IW_AUTH_CIPHER_PAIRWISE:
1832 break;
1833 case IW_AUTH_CIPHER_GROUP:
1834 break;
1835 case IW_AUTH_KEY_MGMT:
1836
1837
1838
1839 break;
1840 case IW_AUTH_TKIP_COUNTERMEASURES:
1841
1842 if (param->value)
1843 padapter->securitypriv.btkip_countermeasure = true;
1844 else
1845 padapter->securitypriv.btkip_countermeasure = false;
1846 break;
1847 case IW_AUTH_DROP_UNENCRYPTED:
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1865 break;
1866
1867 if (param->value) {
1868 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1869 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1870 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1871 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1872 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1873 }
1874
1875 break;
1876 case IW_AUTH_80211_AUTH_ALG:
1877
1878
1879
1880 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
1881 LeaveAllPowerSaveMode(padapter);
1882 rtw_disassoc_cmd(padapter, 500, false);
1883 rtw_indicate_disconnect(padapter);
1884 rtw_free_assoc_resources(padapter, 1);
1885 }
1886
1887 ret = wpa_set_auth_algs(dev, (u32)param->value);
1888 break;
1889 case IW_AUTH_WPA_ENABLED:
1890 break;
1891 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1892 break;
1893 case IW_AUTH_PRIVACY_INVOKED:
1894 break;
1895 default:
1896 return -EOPNOTSUPP;
1897 }
1898
1899 return ret;
1900}
1901
1902static int rtw_wx_set_enc_ext(struct net_device *dev,
1903 struct iw_request_info *info,
1904 union iwreq_data *wrqu, char *extra)
1905{
1906 char *alg_name;
1907 u32 param_len;
1908 struct ieee_param *param = NULL;
1909 struct iw_point *pencoding = &wrqu->encoding;
1910 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1911 int ret = 0;
1912
1913 param_len = sizeof(struct ieee_param) + pext->key_len;
1914 param = kzalloc(param_len, GFP_KERNEL);
1915 if (param == NULL)
1916 return -1;
1917
1918 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1919 eth_broadcast_addr(param->sta_addr);
1920
1921
1922 switch (pext->alg) {
1923 case IW_ENCODE_ALG_NONE:
1924
1925
1926 alg_name = "none";
1927 break;
1928 case IW_ENCODE_ALG_WEP:
1929 alg_name = "WEP";
1930 break;
1931 case IW_ENCODE_ALG_TKIP:
1932 alg_name = "TKIP";
1933 break;
1934 case IW_ENCODE_ALG_CCMP:
1935 alg_name = "CCMP";
1936 break;
1937 case IW_ENCODE_ALG_AES_CMAC:
1938 alg_name = "BIP";
1939 break;
1940 default:
1941 ret = -1;
1942 goto exit;
1943 }
1944
1945 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1946
1947 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1948 param->u.crypt.set_tx = 1;
1949
1950
1951
1952
1953 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
1954 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1955 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC))) {
1956 param->u.crypt.set_tx = 0;
1957 }
1958
1959 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1960
1961 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1962 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1963
1964 if (pext->key_len) {
1965 param->u.crypt.key_len = pext->key_len;
1966
1967 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
1968 }
1969
1970 if (pencoding->flags & IW_ENCODE_DISABLED) {
1971
1972
1973 }
1974
1975 ret = wpa_set_encryption(dev, param, param_len);
1976
1977exit:
1978 kfree(param);
1979
1980 return ret;
1981}
1982
1983
1984static int rtw_wx_get_nick(struct net_device *dev,
1985 struct iw_request_info *info,
1986 union iwreq_data *wrqu, char *extra)
1987{
1988
1989
1990
1991
1992 if (extra) {
1993 wrqu->data.length = 14;
1994 wrqu->data.flags = 1;
1995 memcpy(extra, "<WIFI@REALTEK>", 14);
1996 }
1997 return 0;
1998}
1999
2000static int rtw_wx_read32(struct net_device *dev,
2001 struct iw_request_info *info,
2002 union iwreq_data *wrqu, char *extra)
2003{
2004 struct adapter *padapter;
2005 struct iw_point *p;
2006 u16 len;
2007 u32 addr;
2008 u32 data32;
2009 u32 bytes;
2010 u8 *ptmp;
2011 int ret;
2012
2013
2014 ret = 0;
2015 padapter = rtw_netdev_priv(dev);
2016 p = &wrqu->data;
2017 len = p->length;
2018 if (0 == len)
2019 return -EINVAL;
2020
2021 ptmp = rtw_malloc(len);
2022 if (NULL == ptmp)
2023 return -ENOMEM;
2024
2025 if (copy_from_user(ptmp, p->pointer, len)) {
2026 ret = -EFAULT;
2027 goto exit;
2028 }
2029
2030 bytes = 0;
2031 addr = 0;
2032 sscanf(ptmp, "%d,%x", &bytes, &addr);
2033
2034 switch (bytes) {
2035 case 1:
2036 data32 = rtw_read8(padapter, addr);
2037 sprintf(extra, "0x%02X", data32);
2038 break;
2039 case 2:
2040 data32 = rtw_read16(padapter, addr);
2041 sprintf(extra, "0x%04X", data32);
2042 break;
2043 case 4:
2044 data32 = rtw_read32(padapter, addr);
2045 sprintf(extra, "0x%08X", data32);
2046 break;
2047 default:
2048 ret = -EINVAL;
2049 goto exit;
2050 }
2051
2052exit:
2053 kfree(ptmp);
2054
2055 return ret;
2056}
2057
2058static int rtw_wx_write32(struct net_device *dev,
2059 struct iw_request_info *info,
2060 union iwreq_data *wrqu, char *extra)
2061{
2062 struct adapter *padapter = rtw_netdev_priv(dev);
2063
2064 u32 addr;
2065 u32 data32;
2066 u32 bytes;
2067
2068
2069 bytes = 0;
2070 addr = 0;
2071 data32 = 0;
2072 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
2073
2074 switch (bytes) {
2075 case 1:
2076 rtw_write8(padapter, addr, (u8)data32);
2077 break;
2078 case 2:
2079 rtw_write16(padapter, addr, (u16)data32);
2080 break;
2081 case 4:
2082 rtw_write32(padapter, addr, data32);
2083 break;
2084 default:
2085 return -EINVAL;
2086 }
2087
2088 return 0;
2089}
2090
2091static int rtw_wx_read_rf(struct net_device *dev,
2092 struct iw_request_info *info,
2093 union iwreq_data *wrqu, char *extra)
2094{
2095 struct adapter *padapter = rtw_netdev_priv(dev);
2096 u32 path, addr, data32;
2097
2098
2099 path = *(u32 *)extra;
2100 addr = *((u32 *)extra + 1);
2101 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
2102
2103
2104
2105
2106
2107 sprintf(extra, "0x%05x", data32);
2108
2109 return 0;
2110}
2111
2112static int rtw_wx_write_rf(struct net_device *dev,
2113 struct iw_request_info *info,
2114 union iwreq_data *wrqu, char *extra)
2115{
2116 struct adapter *padapter = rtw_netdev_priv(dev);
2117 u32 path, addr, data32;
2118
2119
2120 path = *(u32 *)extra;
2121 addr = *((u32 *)extra + 1);
2122 data32 = *((u32 *)extra + 2);
2123 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
2124
2125 return 0;
2126}
2127
2128static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
2129 union iwreq_data *wrqu, char *b)
2130{
2131 return -1;
2132}
2133
2134static int dummy(struct net_device *dev, struct iw_request_info *a,
2135 union iwreq_data *wrqu, char *b)
2136{
2137
2138
2139
2140 return -1;
2141
2142}
2143
2144static int rtw_wx_set_channel_plan(struct net_device *dev,
2145 struct iw_request_info *info,
2146 union iwreq_data *wrqu, char *extra)
2147{
2148 struct adapter *padapter = rtw_netdev_priv(dev);
2149 u8 channel_plan_req = (u8)(*((int *)wrqu));
2150
2151 if (rtw_set_chplan_cmd(padapter, channel_plan_req, 1, 1) != _SUCCESS)
2152 return -EPERM;
2153
2154 return 0;
2155}
2156
2157static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
2158 struct iw_request_info *a,
2159 union iwreq_data *wrqu, char *b)
2160{
2161 return 0;
2162}
2163
2164static int rtw_wx_get_sensitivity(struct net_device *dev,
2165 struct iw_request_info *info,
2166 union iwreq_data *wrqu, char *buf)
2167{
2168 return 0;
2169}
2170
2171static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
2172 struct iw_request_info *info,
2173 union iwreq_data *wrqu, char *extra)
2174{
2175 return 0;
2176}
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
2187 union iwreq_data *wrqu, char *extra)
2188{
2189 return 0;
2190}
2191
2192static int rtw_get_ap_info(struct net_device *dev,
2193 struct iw_request_info *info,
2194 union iwreq_data *wrqu, char *extra)
2195{
2196 int ret = 0;
2197 int wpa_ielen;
2198 u32 cnt = 0;
2199 struct list_head *plist, *phead;
2200 unsigned char *pbuf;
2201 u8 bssid[ETH_ALEN];
2202 char data[32];
2203 struct wlan_network *pnetwork = NULL;
2204 struct adapter *padapter = rtw_netdev_priv(dev);
2205 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2206 struct __queue *queue = &(pmlmepriv->scanned_queue);
2207 struct iw_point *pdata = &wrqu->data;
2208
2209 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2210 ret = -EINVAL;
2211 goto exit;
2212 }
2213
2214 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == true) {
2215 msleep(30);
2216 cnt++;
2217 if (cnt > 100)
2218 break;
2219 }
2220
2221
2222
2223 pdata->flags = 0;
2224 if (pdata->length >= 32) {
2225 if (copy_from_user(data, pdata->pointer, 32)) {
2226 ret = -EINVAL;
2227 goto exit;
2228 }
2229 } else {
2230 ret = -EINVAL;
2231 goto exit;
2232 }
2233
2234 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
2235
2236 phead = get_list_head(queue);
2237 list_for_each(plist, phead) {
2238 pnetwork = list_entry(plist, struct wlan_network, list);
2239
2240 if (!mac_pton(data, bssid)) {
2241 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2242 return -EINVAL;
2243 }
2244
2245
2246 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2247
2248 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
2249 if (pbuf && (wpa_ielen > 0)) {
2250 pdata->flags = 1;
2251 break;
2252 }
2253
2254 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
2255 if (pbuf && (wpa_ielen > 0)) {
2256 pdata->flags = 2;
2257 break;
2258 }
2259 }
2260
2261 }
2262
2263 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
2264
2265 if (pdata->length >= 34) {
2266 if (copy_to_user((u8 __force __user *)pdata->pointer+32, (u8 *)&pdata->flags, 1)) {
2267 ret = -EINVAL;
2268 goto exit;
2269 }
2270 }
2271
2272exit:
2273
2274 return ret;
2275
2276}
2277
2278static int rtw_set_pid(struct net_device *dev,
2279 struct iw_request_info *info,
2280 union iwreq_data *wrqu, char *extra)
2281{
2282
2283 int ret = 0;
2284 struct adapter *padapter = rtw_netdev_priv(dev);
2285 int *pdata = (int *)wrqu;
2286 int selector;
2287
2288 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2289 ret = -EINVAL;
2290 goto exit;
2291 }
2292
2293 selector = *pdata;
2294 if (selector < 3 && selector >= 0)
2295 padapter->pid[selector] = *(pdata+1);
2296
2297exit:
2298
2299 return ret;
2300
2301}
2302
2303static int rtw_wps_start(struct net_device *dev,
2304 struct iw_request_info *info,
2305 union iwreq_data *wrqu, char *extra)
2306{
2307
2308 int ret = 0;
2309 struct adapter *padapter = rtw_netdev_priv(dev);
2310 struct iw_point *pdata = &wrqu->data;
2311 u32 u32wps_start = 0;
2312
2313 if ((true == padapter->bDriverStopped) || (true == padapter->bSurpriseRemoved) || (NULL == pdata)) {
2314 ret = -EINVAL;
2315 goto exit;
2316 }
2317
2318 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) {
2319 ret = -EFAULT;
2320 goto exit;
2321 }
2322 if (u32wps_start == 0)
2323 u32wps_start = *extra;
2324
2325exit:
2326
2327 return ret;
2328
2329}
2330
2331static int rtw_p2p_set(struct net_device *dev,
2332 struct iw_request_info *info,
2333 union iwreq_data *wrqu, char *extra)
2334{
2335
2336 return 0;
2337
2338}
2339
2340static int rtw_p2p_get(struct net_device *dev,
2341 struct iw_request_info *info,
2342 union iwreq_data *wrqu, char *extra)
2343{
2344
2345 return 0;
2346
2347}
2348
2349static int rtw_p2p_get2(struct net_device *dev,
2350 struct iw_request_info *info,
2351 union iwreq_data *wrqu, char *extra)
2352{
2353
2354 return 0;
2355
2356}
2357
2358static int rtw_rereg_nd_name(struct net_device *dev,
2359 struct iw_request_info *info,
2360 union iwreq_data *wrqu, char *extra)
2361{
2362 int ret = 0;
2363 struct adapter *padapter = rtw_netdev_priv(dev);
2364 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
2365 char new_ifname[IFNAMSIZ];
2366
2367 if (rereg_priv->old_ifname[0] == 0) {
2368 char *reg_ifname;
2369 reg_ifname = padapter->registrypriv.ifname;
2370
2371 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
2372 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
2373 }
2374
2375 if (wrqu->data.length > IFNAMSIZ)
2376 return -EFAULT;
2377
2378 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
2379 return -EFAULT;
2380
2381 if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
2382 return ret;
2383
2384 ret = rtw_change_ifname(padapter, new_ifname);
2385 if (ret != 0)
2386 goto exit;
2387
2388 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
2389 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
2390
2391 if (!memcmp(new_ifname, "disable%d", 9)) {
2392
2393 rtw_free_network_queue(padapter, true);
2394
2395
2396
2397 }
2398exit:
2399 return ret;
2400
2401}
2402
2403static int rtw_dbg_port(struct net_device *dev,
2404 struct iw_request_info *info,
2405 union iwreq_data *wrqu, char *extra)
2406{
2407 u8 major_cmd, minor_cmd;
2408 u16 arg;
2409 u32 extra_arg, *pdata, val32;
2410 struct adapter *padapter = rtw_netdev_priv(dev);
2411 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2412 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2413
2414 pdata = (u32 *)&wrqu->data;
2415
2416 val32 = *pdata;
2417 arg = (u16)(val32&0x0000ffff);
2418 major_cmd = (u8)(val32>>24);
2419 minor_cmd = (u8)((val32>>16)&0x00ff);
2420
2421 extra_arg = *(pdata+1);
2422
2423 switch (major_cmd) {
2424 case 0x70:
2425 switch (minor_cmd) {
2426 case 1:
2427 break;
2428 case 2:
2429 break;
2430 case 4:
2431 break;
2432 }
2433 break;
2434 case 0x71:
2435 switch (minor_cmd) {
2436 case 1:
2437 rtw_write8(padapter, arg, extra_arg);
2438 break;
2439 case 2:
2440 rtw_write16(padapter, arg, extra_arg);
2441 break;
2442 case 4:
2443 rtw_write32(padapter, arg, extra_arg);
2444 break;
2445 }
2446 break;
2447 case 0x72:
2448 break;
2449 case 0x73:
2450 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
2451 break;
2452 case 0x74:
2453 break;
2454 case 0x75:
2455 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
2456 break;
2457
2458 case 0x76:
2459 switch (minor_cmd) {
2460 case 0x00:
2461 padapter->recvpriv.is_signal_dbg = 0;
2462 break;
2463 case 0x01:
2464 padapter->recvpriv.is_signal_dbg = 1;
2465 extra_arg = extra_arg > 100 ? 100 : extra_arg;
2466 padapter->recvpriv.signal_strength_dbg = extra_arg;
2467 break;
2468 }
2469 break;
2470 case 0x78:
2471 break;
2472 case 0x79:
2473 {
2474
2475
2476
2477
2478 u8 value = extra_arg & 0x0f;
2479 u8 sign = minor_cmd;
2480 u16 write_value = 0;
2481
2482 if (sign)
2483 value = value | 0x10;
2484
2485 write_value = value | (value << 5);
2486 rtw_write16(padapter, 0x6d9, write_value);
2487 }
2488 break;
2489 case 0x7a:
2490 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
2491 , WLAN_REASON_EXPIRATION_CHK);
2492 break;
2493 case 0x7F:
2494 switch (minor_cmd) {
2495 case 0x0:
2496 break;
2497 case 0x01:
2498 break;
2499 case 0x02:
2500 break;
2501 case 0x03:
2502 break;
2503 case 0x04:
2504
2505 break;
2506 case 0x05:
2507 break;
2508 case 0x06:
2509 {
2510 u32 ODMFlag;
2511 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
2512 ODMFlag = (u32)(0x0f&arg);
2513 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
2514 }
2515 break;
2516 case 0x07:
2517 break;
2518 case 0x08:
2519 {
2520 }
2521 break;
2522 case 0x09:
2523 break;
2524 case 0x0a:
2525 {
2526 int max_mac_id = 0;
2527 max_mac_id = rtw_search_max_mac_id(padapter);
2528 printk("%s ==> max_mac_id = %d\n", __func__, max_mac_id);
2529 }
2530 break;
2531 case 0x0b:
2532 if (arg == 0) {
2533 padapter->driver_vcs_en = 0;
2534 } else if (arg == 1) {
2535 padapter->driver_vcs_en = 1;
2536
2537 if (extra_arg > 2)
2538 padapter->driver_vcs_type = 1;
2539 else
2540 padapter->driver_vcs_type = extra_arg;
2541 }
2542 break;
2543 case 0x0c:
2544 {
2545 if (arg == 0)
2546
2547 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
2548 else if (arg == 1)
2549 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
2550 }
2551 break;
2552 case 0x0e:
2553 {
2554 if (arg == 0) {
2555 padapter->driver_rx_ampdu_factor = 0xFF;
2556 } else if (arg == 1) {
2557
2558 if ((extra_arg & 0x03) > 0x03)
2559 padapter->driver_rx_ampdu_factor = 0xFF;
2560 else
2561 padapter->driver_rx_ampdu_factor = extra_arg;
2562 }
2563 }
2564 break;
2565
2566 case 0x10:
2567 netdev_dbg(dev, "%s %s\n", "rtl8723bs", DRIVERVERSION);
2568 break;
2569 case 0x11:
2570 {
2571 linked_info_dump(padapter, extra_arg);
2572 }
2573 break;
2574 case 0x12:
2575 {
2576 struct registry_priv *pregpriv = &padapter->registrypriv;
2577
2578
2579 if (extra_arg == 0 || extra_arg == 1)
2580 pregpriv->rx_stbc = extra_arg;
2581 }
2582 break;
2583 case 0x13:
2584 {
2585 struct registry_priv *pregpriv = &padapter->registrypriv;
2586
2587 if (extra_arg < 3)
2588 pregpriv->ampdu_enable = extra_arg;
2589 }
2590 break;
2591 case 0x14:
2592 {
2593 }
2594 break;
2595 case 0x16:
2596 {
2597 if (arg == 0xff) {
2598 rtw_odm_dbg_comp_msg(padapter);
2599 } else {
2600 u64 dbg_comp = (u64)extra_arg;
2601 rtw_odm_dbg_comp_set(padapter, dbg_comp);
2602 }
2603 }
2604 break;
2605#ifdef DBG_FIXED_CHAN
2606 case 0x17:
2607 {
2608 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2609 printk("===> Fixed channel to %d\n", extra_arg);
2610 pmlmeext->fixed_chan = extra_arg;
2611
2612 }
2613 break;
2614#endif
2615 case 0x18:
2616 {
2617 printk("===> Switch USB Mode %d\n", extra_arg);
2618 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
2619 }
2620 break;
2621 case 0x19:
2622 {
2623 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2624
2625
2626
2627 if (arg == 0)
2628 pregistrypriv->ldpc_cap = 0x00;
2629 else if (arg == 1)
2630 pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33);
2631 }
2632 break;
2633 case 0x1a:
2634 {
2635 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2636
2637
2638
2639 if (arg == 0)
2640 pregistrypriv->stbc_cap = 0x00;
2641 else if (arg == 1)
2642 pregistrypriv->stbc_cap = (u8)(extra_arg&0x33);
2643 }
2644 break;
2645 case 0x1b:
2646 {
2647 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2648
2649 if (arg == 0) {
2650 init_mlme_default_rate_set(padapter);
2651 pregistrypriv->ht_enable = (u8)rtw_ht_enable;
2652 } else if (arg == 1) {
2653
2654 int i;
2655 u8 max_rx_rate;
2656
2657 max_rx_rate = (u8)extra_arg;
2658
2659 if (max_rx_rate < 0xc) {
2660 pregistrypriv->ht_enable = 0;
2661 for (i = 0; i < NumRates; i++) {
2662 if (pmlmeext->datarate[i] > max_rx_rate)
2663 pmlmeext->datarate[i] = 0xff;
2664 }
2665
2666 }
2667 else if (max_rx_rate < 0x1c) {
2668 u32 mcs_bitmap = 0x0;
2669
2670 for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++)
2671 mcs_bitmap |= BIT(i);
2672
2673 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
2674 }
2675 }
2676 }
2677 break;
2678 case 0x1c:
2679 {
2680 if (arg == 0) {
2681 padapter->driver_ampdu_spacing = 0xFF;
2682 } else if (arg == 1) {
2683
2684 if (extra_arg > 0x07)
2685 padapter->driver_ampdu_spacing = 0xFF;
2686 else
2687 padapter->driver_ampdu_spacing = extra_arg;
2688 }
2689 }
2690 break;
2691 case 0x23:
2692 {
2693 padapter->bNotifyChannelChange = extra_arg;
2694 break;
2695 }
2696 case 0x24:
2697 {
2698 break;
2699 }
2700 case 0xaa:
2701 {
2702 if ((extra_arg & 0x7F) > 0x3F)
2703 extra_arg = 0xFF;
2704 padapter->fix_rate = extra_arg;
2705 }
2706 break;
2707 case 0xdd:
2708 {
2709 if (extra_arg == 0)
2710 mac_reg_dump(padapter);
2711 else if (extra_arg == 1)
2712 bb_reg_dump(padapter);
2713 else if (extra_arg == 2)
2714 rf_reg_dump(padapter);
2715 }
2716 break;
2717
2718 case 0xee:
2719 {
2720 u32 odm_flag;
2721
2722 if (0xf == extra_arg) {
2723 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
2724 } else {
2725
2726
2727
2728
2729
2730 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
2731 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
2732 }
2733 }
2734 break;
2735
2736 case 0xfd:
2737 rtw_write8(padapter, 0xc50, arg);
2738 rtw_write8(padapter, 0xc58, arg);
2739 break;
2740 case 0xfe:
2741 break;
2742 case 0xff:
2743 {
2744 }
2745 break;
2746 }
2747 break;
2748 default:
2749 break;
2750 }
2751
2752
2753 return 0;
2754
2755}
2756
2757static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2758{
2759 uint ret = 0;
2760 struct adapter *padapter = rtw_netdev_priv(dev);
2761
2762 switch (name) {
2763 case IEEE_PARAM_WPA_ENABLED:
2764
2765 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2766
2767
2768
2769 switch ((value)&0xff) {
2770 case 1:
2771 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
2772 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2773 break;
2774 case 2:
2775 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2776 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2777 break;
2778 }
2779
2780 break;
2781
2782 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2783
2784 break;
2785
2786 case IEEE_PARAM_DROP_UNENCRYPTED:
2787 {
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799 break;
2800
2801 }
2802 case IEEE_PARAM_PRIVACY_INVOKED:
2803
2804
2805
2806 break;
2807
2808 case IEEE_PARAM_AUTH_ALGS:
2809
2810 ret = wpa_set_auth_algs(dev, value);
2811
2812 break;
2813
2814 case IEEE_PARAM_IEEE_802_1X:
2815
2816
2817
2818 break;
2819
2820 case IEEE_PARAM_WPAX_SELECT:
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830 break;
2831
2832 default:
2833
2834
2835
2836 ret = -EOPNOTSUPP;
2837
2838
2839 break;
2840
2841 }
2842
2843 return ret;
2844
2845}
2846
2847static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2848{
2849 int ret = 0;
2850 struct adapter *padapter = rtw_netdev_priv(dev);
2851
2852 switch (command) {
2853 case IEEE_MLME_STA_DEAUTH:
2854
2855 if (!rtw_set_802_11_disassociate(padapter))
2856 ret = -1;
2857
2858 break;
2859
2860 case IEEE_MLME_STA_DISASSOC:
2861
2862 if (!rtw_set_802_11_disassociate(padapter))
2863 ret = -1;
2864
2865 break;
2866
2867 default:
2868 ret = -EOPNOTSUPP;
2869 break;
2870 }
2871
2872 return ret;
2873
2874}
2875
2876static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2877{
2878 struct ieee_param *param;
2879 uint ret = 0;
2880
2881
2882
2883 if (!p->pointer || p->length != sizeof(struct ieee_param))
2884 return -EINVAL;
2885
2886 param = rtw_malloc(p->length);
2887 if (param == NULL)
2888 return -ENOMEM;
2889
2890 if (copy_from_user(param, p->pointer, p->length)) {
2891 kfree(param);
2892 return -EFAULT;
2893 }
2894
2895 switch (param->cmd) {
2896
2897 case IEEE_CMD_SET_WPA_PARAM:
2898 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
2899 break;
2900
2901 case IEEE_CMD_SET_WPA_IE:
2902
2903 ret = rtw_set_wpa_ie(rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
2904 break;
2905
2906 case IEEE_CMD_SET_ENCRYPTION:
2907 ret = wpa_set_encryption(dev, param, p->length);
2908 break;
2909
2910 case IEEE_CMD_MLME:
2911 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
2912 break;
2913
2914 default:
2915 ret = -EOPNOTSUPP;
2916 break;
2917
2918 }
2919
2920 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2921 ret = -EFAULT;
2922
2923 kfree(param);
2924
2925
2926 return ret;
2927}
2928
2929static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
2930{
2931 int ret = 0;
2932 u32 wep_key_idx, wep_key_len, wep_total_len;
2933 struct ndis_802_11_wep *pwep = NULL;
2934 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
2935 struct adapter *padapter = rtw_netdev_priv(dev);
2936 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2937 struct security_priv *psecuritypriv = &(padapter->securitypriv);
2938 struct sta_priv *pstapriv = &padapter->stapriv;
2939 char *txkey = padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey;
2940 char *rxkey = padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey;
2941 char *grpkey = psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey;
2942
2943 param->u.crypt.err = 0;
2944 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2945
2946
2947
2948 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
2949 ret = -EINVAL;
2950 goto exit;
2951 }
2952
2953 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2954 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2955 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
2956 if (param->u.crypt.idx >= WEP_KEYS) {
2957 ret = -EINVAL;
2958 goto exit;
2959 }
2960 } else {
2961 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
2962 if (!psta)
2963
2964 goto exit;
2965 }
2966
2967 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
2968
2969
2970 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2971 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2972 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2973 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2974
2975 goto exit;
2976 }
2977
2978
2979 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
2980 wep_key_idx = param->u.crypt.idx;
2981 wep_key_len = param->u.crypt.key_len;
2982
2983 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
2984 ret = -EINVAL;
2985 goto exit;
2986 }
2987
2988
2989 if (wep_key_len > 0) {
2990 wep_key_len = wep_key_len <= 5 ? 5 : 13;
2991 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
2992 pwep = kzalloc(wep_total_len, GFP_KERNEL);
2993 if (!pwep)
2994 goto exit;
2995
2996 pwep->KeyLength = wep_key_len;
2997 pwep->Length = wep_total_len;
2998
2999 }
3000
3001 pwep->KeyIndex = wep_key_idx;
3002
3003 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
3004
3005 if (param->u.crypt.set_tx) {
3006 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3007 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
3008 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
3009 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3010
3011 if (pwep->KeyLength == 13) {
3012 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
3013 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3014 }
3015
3016
3017 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
3018
3019 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
3020
3021 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
3022
3023 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
3024 } else {
3025
3026
3027
3028 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
3029
3030 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
3031
3032 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
3033 }
3034
3035 goto exit;
3036
3037 }
3038
3039
3040 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3041 if (param->u.crypt.set_tx == 1) {
3042 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3043 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3044
3045 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3046 if (param->u.crypt.key_len == 13)
3047 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3048
3049 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3050 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
3051
3052 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3053
3054
3055
3056 memcpy(txkey, &(param->u.crypt.key[16]), 8);
3057 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
3058
3059 psecuritypriv->busetkipkey = true;
3060
3061 }
3062 else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3063 psecuritypriv->dot118021XGrpPrivacy = _AES_;
3064
3065 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3066 } else {
3067 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3068 }
3069
3070 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
3071
3072 psecuritypriv->binstallGrpkey = true;
3073
3074 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
3075
3076 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
3077
3078 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
3079 if (pbcmc_sta) {
3080 pbcmc_sta->ieee8021x_blocked = false;
3081 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
3082 }
3083 }
3084
3085 goto exit;
3086
3087 }
3088
3089 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) {
3090 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3091 if (param->u.crypt.set_tx == 1) {
3092 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3093
3094 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3095 psta->dot118021XPrivacy = _WEP40_;
3096 if (param->u.crypt.key_len == 13)
3097 psta->dot118021XPrivacy = _WEP104_;
3098 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3099 psta->dot118021XPrivacy = _TKIP_;
3100
3101
3102
3103 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
3104 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
3105
3106 psecuritypriv->busetkipkey = true;
3107
3108 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3109
3110 psta->dot118021XPrivacy = _AES_;
3111 } else {
3112 psta->dot118021XPrivacy = _NO_PRIVACY_;
3113 }
3114
3115 rtw_ap_set_pairwise_key(padapter, psta);
3116
3117 psta->ieee8021x_blocked = false;
3118
3119 } else {
3120 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3121 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3122
3123 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
3124 if (param->u.crypt.key_len == 13)
3125 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
3126 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3127 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
3128
3129 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3130
3131
3132
3133 memcpy(txkey, &(param->u.crypt.key[16]), 8);
3134 memcpy(rxkey, &(param->u.crypt.key[24]), 8);
3135
3136 psecuritypriv->busetkipkey = true;
3137
3138 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3139 psecuritypriv->dot118021XGrpPrivacy = _AES_;
3140
3141 memcpy(grpkey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
3142 } else {
3143 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3144 }
3145
3146 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
3147
3148 psecuritypriv->binstallGrpkey = true;
3149
3150 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;
3151
3152 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
3153
3154 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
3155 if (pbcmc_sta) {
3156 pbcmc_sta->ieee8021x_blocked = false;
3157 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
3158 }
3159 }
3160 }
3161 }
3162
3163exit:
3164 kfree(pwep);
3165
3166 return ret;
3167
3168}
3169
3170static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
3171{
3172 int ret = 0;
3173 struct adapter *padapter = rtw_netdev_priv(dev);
3174 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3175 struct sta_priv *pstapriv = &padapter->stapriv;
3176 unsigned char *pbuf = param->u.bcn_ie.buf;
3177
3178 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3179 return -EINVAL;
3180
3181 memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3182
3183 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
3184 pstapriv->max_num_sta = NUM_STA;
3185
3186
3187 if (rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)
3188 ret = 0;
3189 else
3190 ret = -EINVAL;
3191
3192
3193 return ret;
3194
3195}
3196
3197static void rtw_hostapd_sta_flush(struct net_device *dev)
3198{
3199
3200
3201
3202 struct adapter *padapter = rtw_netdev_priv(dev);
3203
3204
3205 flush_all_cam_entry(padapter);
3206
3207 rtw_sta_flush(padapter);
3208}
3209
3210static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
3211{
3212 int ret = 0;
3213 struct sta_info *psta = NULL;
3214 struct adapter *padapter = rtw_netdev_priv(dev);
3215 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3216 struct sta_priv *pstapriv = &padapter->stapriv;
3217
3218 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3219 return -EINVAL;
3220
3221 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3222 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3223 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3224 return -EINVAL;
3225 }
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3240 if (psta) {
3241 int flags = param->u.add_sta.flags;
3242
3243 psta->aid = param->u.add_sta.aid;
3244
3245 memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
3246
3247
3248
3249 if (WLAN_STA_WME&flags)
3250 psta->qos_option = 1;
3251 else
3252 psta->qos_option = 0;
3253
3254 if (pmlmepriv->qospriv.qos_option == 0)
3255 psta->qos_option = 0;
3256
3257
3258 if (WLAN_STA_HT&flags) {
3259 psta->htpriv.ht_option = true;
3260 psta->qos_option = 1;
3261 memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct ieee80211_ht_cap));
3262 } else {
3263 psta->htpriv.ht_option = false;
3264 }
3265
3266 if (pmlmepriv->htpriv.ht_option == false)
3267 psta->htpriv.ht_option = false;
3268
3269 update_sta_info_apmode(padapter, psta);
3270
3271
3272 } else {
3273 ret = -ENOMEM;
3274 }
3275
3276 return ret;
3277
3278}
3279
3280static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
3281{
3282 int ret = 0;
3283 struct sta_info *psta = NULL;
3284 struct adapter *padapter = rtw_netdev_priv(dev);
3285 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3286 struct sta_priv *pstapriv = &padapter->stapriv;
3287
3288 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3289 return -EINVAL;
3290
3291 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3292 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3293 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3294 return -EINVAL;
3295 }
3296
3297 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3298 if (psta) {
3299 u8 updated = false;
3300
3301 spin_lock_bh(&pstapriv->asoc_list_lock);
3302 if (list_empty(&psta->asoc_list) == false) {
3303 list_del_init(&psta->asoc_list);
3304 pstapriv->asoc_list_cnt--;
3305 updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
3306
3307 }
3308 spin_unlock_bh(&pstapriv->asoc_list_lock);
3309
3310 associated_clients_update(padapter, updated);
3311
3312 psta = NULL;
3313
3314 }
3315
3316 return ret;
3317
3318}
3319
3320static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
3321{
3322 int ret = 0;
3323 struct sta_info *psta = NULL;
3324 struct adapter *padapter = rtw_netdev_priv(dev);
3325 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3326 struct sta_priv *pstapriv = &padapter->stapriv;
3327 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
3328 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
3329
3330 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3331 return -EINVAL;
3332
3333 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
3334 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
3335 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff) {
3336 return -EINVAL;
3337 }
3338
3339 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
3340 if (psta) {
3341 psta_data->aid = (u16)psta->aid;
3342 psta_data->capability = psta->capability;
3343 psta_data->flags = psta->flags;
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354 psta_data->sta_set = ((psta->nonerp_set) |
3355 (psta->no_short_slot_time_set << 1) |
3356 (psta->no_short_preamble_set << 2) |
3357 (psta->no_ht_gf_set << 3) |
3358 (psta->no_ht_set << 4) |
3359 (psta->ht_20mhz_set << 5));
3360
3361 psta_data->tx_supp_rates_len = psta->bssratelen;
3362 memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
3363 memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct ieee80211_ht_cap));
3364 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
3365 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
3366 psta_data->rx_drops = psta->sta_stats.rx_drops;
3367
3368 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
3369 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
3370 psta_data->tx_drops = psta->sta_stats.tx_drops;
3371
3372
3373 } else {
3374 ret = -1;
3375 }
3376
3377 return ret;
3378
3379}
3380
3381static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
3382{
3383 int ret = 0;
3384 struct sta_info *psta = NULL;
3385 struct adapter *padapter = rtw_netdev_priv(dev);
3386 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3387 struct sta_priv *pstapriv = &padapter->stapriv;
3388
3389 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
3390 return -EINVAL;
3391
3392 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3393 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3394 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3395 return -EINVAL;
3396 }
3397
3398 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
3399 if (psta) {
3400 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC)) {
3401 int wpa_ie_len;
3402 int copy_len;
3403
3404 wpa_ie_len = psta->wpa_ie[1];
3405
3406 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
3407
3408 param->u.wpa_ie.len = copy_len;
3409
3410 memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
3411 }
3412 } else {
3413 ret = -1;
3414 }
3415
3416 return ret;
3417
3418}
3419
3420static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
3421{
3422 int ret = 0;
3423 unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
3424 struct adapter *padapter = rtw_netdev_priv(dev);
3425 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3426 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3427 int ie_len;
3428
3429 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3430 return -EINVAL;
3431
3432 ie_len = len-12-2;
3433
3434
3435 kfree(pmlmepriv->wps_beacon_ie);
3436 pmlmepriv->wps_beacon_ie = NULL;
3437
3438 if (ie_len > 0) {
3439 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
3440 pmlmepriv->wps_beacon_ie_len = ie_len;
3441 if (!pmlmepriv->wps_beacon_ie)
3442 return -EINVAL;
3443
3444 memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
3445
3446 update_beacon(padapter, WLAN_EID_VENDOR_SPECIFIC, wps_oui, true);
3447
3448 pmlmeext->bstart_bss = true;
3449 }
3450
3451
3452 return ret;
3453
3454}
3455
3456static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
3457{
3458 int ret = 0;
3459 struct adapter *padapter = rtw_netdev_priv(dev);
3460 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3461 int ie_len;
3462
3463 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3464 return -EINVAL;
3465
3466 ie_len = len-12-2;
3467
3468
3469 kfree(pmlmepriv->wps_probe_resp_ie);
3470 pmlmepriv->wps_probe_resp_ie = NULL;
3471
3472 if (ie_len > 0) {
3473 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
3474 pmlmepriv->wps_probe_resp_ie_len = ie_len;
3475 if (!pmlmepriv->wps_probe_resp_ie)
3476 return -EINVAL;
3477
3478 memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
3479 }
3480
3481
3482 return ret;
3483
3484}
3485
3486static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
3487{
3488 int ret = 0;
3489 struct adapter *padapter = rtw_netdev_priv(dev);
3490 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3491 int ie_len;
3492
3493 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3494 return -EINVAL;
3495
3496 ie_len = len-12-2;
3497
3498
3499 kfree(pmlmepriv->wps_assoc_resp_ie);
3500 pmlmepriv->wps_assoc_resp_ie = NULL;
3501
3502 if (ie_len > 0) {
3503 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
3504 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
3505 if (!pmlmepriv->wps_assoc_resp_ie)
3506 return -EINVAL;
3507
3508 memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
3509 }
3510
3511
3512 return ret;
3513
3514}
3515
3516static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
3517{
3518 int ret = 0;
3519 struct adapter *adapter = rtw_netdev_priv(dev);
3520 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
3521 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
3522 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
3523 int ie_len;
3524 u8 *ssid_ie;
3525 char ssid[NDIS_802_11_LENGTH_SSID + 1];
3526 signed int ssid_len;
3527 u8 ignore_broadcast_ssid;
3528
3529 if (check_fwstate(mlmepriv, WIFI_AP_STATE) != true)
3530 return -EPERM;
3531
3532 if (param->u.bcn_ie.reserved[0] != 0xea)
3533 return -EINVAL;
3534
3535 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
3536
3537 ie_len = len-12-2;
3538 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
3539
3540 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
3541 struct wlan_bssid_ex *pbss_network = &mlmepriv->cur_network.network;
3542 struct wlan_bssid_ex *pbss_network_ext = &mlmeinfo->network;
3543
3544 memcpy(ssid, ssid_ie+2, ssid_len);
3545 ssid[ssid_len] = 0x0;
3546
3547 memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
3548 pbss_network->Ssid.SsidLength = ssid_len;
3549 memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
3550 pbss_network_ext->Ssid.SsidLength = ssid_len;
3551 }
3552
3553 return ret;
3554}
3555
3556static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
3557{
3558 struct adapter *padapter = rtw_netdev_priv(dev);
3559 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3560
3561 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3562 return -EINVAL;
3563
3564 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3565 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3566 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3567 return -EINVAL;
3568 }
3569
3570 rtw_acl_remove_sta(padapter, param->sta_addr);
3571 return 0;
3572
3573}
3574
3575static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
3576{
3577 struct adapter *padapter = rtw_netdev_priv(dev);
3578 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3579
3580 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3581 return -EINVAL;
3582
3583 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3584 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3585 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3586 return -EINVAL;
3587 }
3588
3589 return rtw_acl_add_sta(padapter, param->sta_addr);
3590
3591}
3592
3593static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
3594{
3595 int ret = 0;
3596 struct adapter *padapter = rtw_netdev_priv(dev);
3597 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3598
3599 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
3600 return -EINVAL;
3601
3602 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
3603
3604 return ret;
3605}
3606
3607static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
3608{
3609 struct ieee_param *param;
3610 int ret = 0;
3611 struct adapter *padapter = rtw_netdev_priv(dev);
3612
3613
3614
3615
3616
3617
3618 if (!padapter->hw_init_completed)
3619 return -EPERM;
3620
3621 if (!p->pointer || p->length != sizeof(*param))
3622 return -EINVAL;
3623
3624 param = rtw_malloc(p->length);
3625 if (param == NULL)
3626 return -ENOMEM;
3627
3628 if (copy_from_user(param, p->pointer, p->length)) {
3629 kfree(param);
3630 return -EFAULT;
3631 }
3632
3633 switch (param->cmd) {
3634 case RTL871X_HOSTAPD_FLUSH:
3635
3636 rtw_hostapd_sta_flush(dev);
3637
3638 break;
3639
3640 case RTL871X_HOSTAPD_ADD_STA:
3641
3642 ret = rtw_add_sta(dev, param);
3643
3644 break;
3645
3646 case RTL871X_HOSTAPD_REMOVE_STA:
3647
3648 ret = rtw_del_sta(dev, param);
3649
3650 break;
3651
3652 case RTL871X_HOSTAPD_SET_BEACON:
3653
3654 ret = rtw_set_beacon(dev, param, p->length);
3655
3656 break;
3657
3658 case RTL871X_SET_ENCRYPTION:
3659
3660 ret = rtw_set_encryption(dev, param, p->length);
3661
3662 break;
3663
3664 case RTL871X_HOSTAPD_GET_WPAIE_STA:
3665
3666 ret = rtw_get_sta_wpaie(dev, param);
3667
3668 break;
3669
3670 case RTL871X_HOSTAPD_SET_WPS_BEACON:
3671
3672 ret = rtw_set_wps_beacon(dev, param, p->length);
3673
3674 break;
3675
3676 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
3677
3678 ret = rtw_set_wps_probe_resp(dev, param, p->length);
3679
3680 break;
3681
3682 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
3683
3684 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
3685
3686 break;
3687
3688 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
3689
3690 ret = rtw_set_hidden_ssid(dev, param, p->length);
3691
3692 break;
3693
3694 case RTL871X_HOSTAPD_GET_INFO_STA:
3695
3696 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
3697
3698 break;
3699
3700 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
3701
3702 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
3703
3704 break;
3705
3706 case RTL871X_HOSTAPD_ACL_ADD_STA:
3707
3708 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
3709
3710 break;
3711
3712 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
3713
3714 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
3715
3716 break;
3717
3718 default:
3719 ret = -EOPNOTSUPP;
3720 break;
3721
3722 }
3723
3724 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3725 ret = -EFAULT;
3726
3727 kfree(param);
3728 return ret;
3729}
3730
3731static int rtw_wx_set_priv(struct net_device *dev,
3732 struct iw_request_info *info,
3733 union iwreq_data *awrq,
3734 char *extra)
3735{
3736
3737#ifdef DEBUG_RTW_WX_SET_PRIV
3738 char *ext_dbg;
3739#endif
3740
3741 int ret = 0;
3742 int len = 0;
3743 char *ext;
3744
3745 struct adapter *padapter = rtw_netdev_priv(dev);
3746 struct iw_point *dwrq = (struct iw_point *)awrq;
3747
3748 if (dwrq->length == 0)
3749 return -EFAULT;
3750
3751 len = dwrq->length;
3752 ext = vmalloc(len);
3753 if (!ext)
3754 return -ENOMEM;
3755
3756 if (copy_from_user(ext, dwrq->pointer, len)) {
3757 vfree(ext);
3758 return -EFAULT;
3759 }
3760
3761 #ifdef DEBUG_RTW_WX_SET_PRIV
3762 ext_dbg = vmalloc(len);
3763 if (!ext_dbg) {
3764 vfree(ext, len);
3765 return -ENOMEM;
3766 }
3767
3768 memcpy(ext_dbg, ext, len);
3769 #endif
3770
3771
3772 if (dwrq->flags == 0x8766 && len > 8) {
3773 u32 cp_sz;
3774 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3775 u8 *probereq_wpsie = ext;
3776 int probereq_wpsie_len = len;
3777 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
3778
3779 if ((WLAN_EID_VENDOR_SPECIFIC == probereq_wpsie[0]) &&
3780 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
3781 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
3782
3783 if (pmlmepriv->wps_probe_req_ie) {
3784 pmlmepriv->wps_probe_req_ie_len = 0;
3785 kfree(pmlmepriv->wps_probe_req_ie);
3786 pmlmepriv->wps_probe_req_ie = NULL;
3787 }
3788
3789 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
3790 if (pmlmepriv->wps_probe_req_ie == NULL) {
3791 printk("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
3792 ret = -EINVAL;
3793 goto FREE_EXT;
3794
3795 }
3796
3797 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
3798 pmlmepriv->wps_probe_req_ie_len = cp_sz;
3799
3800 }
3801
3802 goto FREE_EXT;
3803
3804 }
3805
3806 if (len >= WEXT_CSCAN_HEADER_SIZE
3807 && !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
3808 ret = rtw_wx_set_scan(dev, info, awrq, ext);
3809 goto FREE_EXT;
3810 }
3811
3812FREE_EXT:
3813
3814 vfree(ext);
3815 #ifdef DEBUG_RTW_WX_SET_PRIV
3816 vfree(ext_dbg);
3817 #endif
3818
3819 return ret;
3820
3821}
3822
3823static int rtw_pm_set(struct net_device *dev,
3824 struct iw_request_info *info,
3825 union iwreq_data *wrqu, char *extra)
3826{
3827 int ret = 0;
3828 unsigned mode = 0;
3829 struct adapter *padapter = rtw_netdev_priv(dev);
3830
3831 if (!memcmp(extra, "lps =", 4)) {
3832 sscanf(extra+4, "%u", &mode);
3833 ret = rtw_pm_set_lps(padapter, mode);
3834 } else if (!memcmp(extra, "ips =", 4)) {
3835 sscanf(extra+4, "%u", &mode);
3836 ret = rtw_pm_set_ips(padapter, mode);
3837 } else {
3838 ret = -EINVAL;
3839 }
3840
3841 return ret;
3842}
3843
3844static int rtw_test(
3845 struct net_device *dev,
3846 struct iw_request_info *info,
3847 union iwreq_data *wrqu, char *extra)
3848{
3849 u32 len;
3850 u8 *pbuf, *pch;
3851 char *ptmp;
3852 u8 *delim = ",";
3853 struct adapter *padapter = rtw_netdev_priv(dev);
3854
3855
3856 len = wrqu->data.length;
3857
3858 pbuf = rtw_zmalloc(len);
3859 if (!pbuf)
3860 return -ENOMEM;
3861
3862 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
3863 kfree(pbuf);
3864 return -EFAULT;
3865 }
3866
3867 ptmp = (char *)pbuf;
3868 pch = strsep(&ptmp, delim);
3869 if ((pch == NULL) || (strlen(pch) == 0)) {
3870 kfree(pbuf);
3871 return -EFAULT;
3872 }
3873
3874 if (strcmp(pch, "bton") == 0)
3875 hal_btcoex_SetManualControl(padapter, false);
3876
3877 if (strcmp(pch, "btoff") == 0)
3878 hal_btcoex_SetManualControl(padapter, true);
3879
3880 if (strcmp(pch, "h2c") == 0) {
3881 u8 param[8];
3882 u8 count = 0;
3883 u32 tmp;
3884 u8 i;
3885 u32 pos;
3886 s32 ret;
3887
3888
3889 do {
3890 pch = strsep(&ptmp, delim);
3891 if ((pch == NULL) || (strlen(pch) == 0))
3892 break;
3893
3894 sscanf(pch, "%x", &tmp);
3895 param[count++] = (u8)tmp;
3896 } while (count < 8);
3897
3898 if (count == 0) {
3899 kfree(pbuf);
3900 return -EFAULT;
3901 }
3902
3903 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]);
3904
3905 pos = sprintf(extra, "H2C ID = 0x%02x content =", param[0]);
3906 for (i = 1; i < count; i++)
3907 pos += sprintf(extra+pos, "%02x,", param[i]);
3908 extra[pos] = 0;
3909 pos--;
3910 pos += sprintf(extra+pos, " %s", ret == _FAIL?"FAIL":"OK");
3911
3912 wrqu->data.length = strlen(extra) + 1;
3913 }
3914
3915 kfree(pbuf);
3916 return 0;
3917}
3918
3919static iw_handler rtw_handlers[] = {
3920 NULL,
3921 rtw_wx_get_name,
3922 dummy,
3923 dummy,
3924 rtw_wx_set_freq,
3925 rtw_wx_get_freq,
3926 rtw_wx_set_mode,
3927 rtw_wx_get_mode,
3928 dummy,
3929 rtw_wx_get_sens,
3930 NULL,
3931 rtw_wx_get_range,
3932 rtw_wx_set_priv,
3933 NULL,
3934 NULL,
3935 NULL,
3936 dummy,
3937 dummy,
3938 NULL,
3939 NULL,
3940 rtw_wx_set_wap,
3941 rtw_wx_get_wap,
3942 rtw_wx_set_mlme,
3943 dummy,
3944 rtw_wx_set_scan,
3945 rtw_wx_get_scan,
3946 rtw_wx_set_essid,
3947 rtw_wx_get_essid,
3948 dummy,
3949 rtw_wx_get_nick,
3950 NULL,
3951 NULL,
3952 rtw_wx_set_rate,
3953 rtw_wx_get_rate,
3954 rtw_wx_set_rts,
3955 rtw_wx_get_rts,
3956 rtw_wx_set_frag,
3957 rtw_wx_get_frag,
3958 dummy,
3959 dummy,
3960 dummy,
3961 rtw_wx_get_retry,
3962 rtw_wx_set_enc,
3963 rtw_wx_get_enc,
3964 dummy,
3965 rtw_wx_get_power,
3966 NULL,
3967 NULL,
3968 rtw_wx_set_gen_ie,
3969 NULL,
3970 rtw_wx_set_auth,
3971 NULL,
3972 rtw_wx_set_enc_ext,
3973 NULL,
3974 rtw_wx_set_pmkid,
3975 NULL,
3976};
3977
3978static const struct iw_priv_args rtw_private_args[] = {
3979 {
3980 SIOCIWFIRSTPRIV + 0x0,
3981 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
3982 },
3983 {
3984 SIOCIWFIRSTPRIV + 0x1,
3985 IW_PRIV_TYPE_CHAR | 0x7FF,
3986 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
3987 },
3988 {
3989 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
3990 },
3991 {
3992 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
3993 },
3994 {
3995 SIOCIWFIRSTPRIV + 0x4,
3996 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
3997 },
3998 {
3999 SIOCIWFIRSTPRIV + 0x5,
4000 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
4001 },
4002 {
4003 SIOCIWFIRSTPRIV + 0x6,
4004 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
4005 },
4006
4007 {
4008 SIOCIWFIRSTPRIV + 0x7,
4009 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
4010 },
4011 {
4012 SIOCIWFIRSTPRIV + 0x8,
4013 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
4014 },
4015 {
4016 SIOCIWFIRSTPRIV + 0x9,
4017 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
4018 },
4019
4020
4021 {
4022 SIOCIWFIRSTPRIV + 0xA,
4023 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
4024 },
4025
4026 {
4027 SIOCIWFIRSTPRIV + 0xB,
4028 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
4029 },
4030 {
4031 SIOCIWFIRSTPRIV + 0xC,
4032 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
4033 },
4034 {
4035 SIOCIWFIRSTPRIV + 0xD,
4036 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
4037 },
4038 {
4039 SIOCIWFIRSTPRIV + 0x10,
4040 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
4041 },
4042 {
4043 SIOCIWFIRSTPRIV + 0x11,
4044 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "p2p_get"
4045 },
4046 {
4047 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
4048 },
4049 {
4050 SIOCIWFIRSTPRIV + 0x13,
4051 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64, "p2p_get2"
4052 },
4053 {
4054 SIOCIWFIRSTPRIV + 0x14,
4055 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
4056 },
4057 {
4058 SIOCIWFIRSTPRIV + 0x15,
4059 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, "tdls_get"
4060 },
4061 {
4062 SIOCIWFIRSTPRIV + 0x16,
4063 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
4064 },
4065
4066 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"},
4067 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
4068 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
4069 {
4070 SIOCIWFIRSTPRIV + 0x1D,
4071 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
4072 },
4073};
4074
4075static iw_handler rtw_private_handler[] = {
4076 rtw_wx_write32,
4077 rtw_wx_read32,
4078 rtw_drvext_hdl,
4079 NULL,
4080
4081
4082 rtw_get_ap_info,
4083
4084 rtw_set_pid,
4085 rtw_wps_start,
4086
4087
4088 rtw_wx_get_sensitivity,
4089 rtw_wx_set_mtk_wps_probe_ie,
4090 rtw_wx_set_mtk_wps_ie,
4091
4092
4093
4094 rtw_wx_set_channel_plan,
4095
4096 rtw_dbg_port,
4097 rtw_wx_write_rf,
4098 rtw_wx_read_rf,
4099 rtw_wx_priv_null,
4100 rtw_wx_priv_null,
4101 rtw_p2p_set,
4102 rtw_p2p_get,
4103 NULL,
4104 rtw_p2p_get2,
4105
4106 NULL,
4107 NULL,
4108
4109 rtw_pm_set,
4110 rtw_wx_priv_null,
4111 rtw_rereg_nd_name,
4112 rtw_wx_priv_null,
4113 NULL,
4114 NULL,
4115 NULL,
4116 rtw_test,
4117};
4118
4119static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
4120{
4121 struct adapter *padapter = rtw_netdev_priv(dev);
4122 struct iw_statistics *piwstats = &padapter->iwstats;
4123 int tmp_level = 0;
4124 int tmp_qual = 0;
4125 int tmp_noise = 0;
4126
4127 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
4128 piwstats->qual.qual = 0;
4129 piwstats->qual.level = 0;
4130 piwstats->qual.noise = 0;
4131 } else {
4132 tmp_level = padapter->recvpriv.signal_strength;
4133 tmp_qual = padapter->recvpriv.signal_qual;
4134 tmp_noise = padapter->recvpriv.noise;
4135
4136 piwstats->qual.level = tmp_level;
4137 piwstats->qual.qual = tmp_qual;
4138 piwstats->qual.noise = tmp_noise;
4139 }
4140 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;
4141
4142 return &padapter->iwstats;
4143}
4144
4145struct iw_handler_def rtw_handlers_def = {
4146 .standard = rtw_handlers,
4147 .num_standard = ARRAY_SIZE(rtw_handlers),
4148#if defined(CONFIG_WEXT_PRIV)
4149 .private = rtw_private_handler,
4150 .private_args = (struct iw_priv_args *)rtw_private_args,
4151 .num_private = ARRAY_SIZE(rtw_private_handler),
4152 .num_private_args = ARRAY_SIZE(rtw_private_args),
4153#endif
4154 .get_wireless_stats = rtw_get_wireless_stats,
4155};
4156
4157
4158
4159
4160
4161
4162static const char iw_priv_type_size[] = {
4163 0,
4164 1,
4165 1,
4166 0,
4167 sizeof(__u32),
4168 sizeof(struct iw_freq),
4169 sizeof(struct sockaddr),
4170 0,
4171};
4172
4173static int get_priv_size(__u16 args)
4174{
4175 int num = args & IW_PRIV_SIZE_MASK;
4176 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
4177
4178 return num * iw_priv_type_size[type];
4179}
4180
4181
4182static int rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
4183{
4184 int err = 0;
4185 u8 *input = NULL;
4186 u32 input_len = 0;
4187 const char delim[] = " ";
4188 u8 *output = NULL;
4189 u32 output_len = 0;
4190 u32 count = 0;
4191 u8 *buffer = NULL;
4192 u32 buffer_len = 0;
4193 char *ptr = NULL;
4194 u8 cmdname[17] = {0};
4195 u32 cmdlen;
4196 s32 len;
4197 u8 *extra = NULL;
4198 u32 extra_size = 0;
4199
4200 s32 k;
4201 const iw_handler *priv;
4202 const struct iw_priv_args *priv_args;
4203 u32 num_priv_args;
4204 iw_handler handler;
4205 int temp;
4206 int subcmd = 0;
4207 int offset = 0;
4208
4209 union iwreq_data wdata;
4210
4211
4212 memcpy(&wdata, wrq_data, sizeof(wdata));
4213
4214 input_len = 2048;
4215 input = rtw_zmalloc(input_len);
4216 if (NULL == input)
4217 return -ENOMEM;
4218 if (copy_from_user(input, wdata.data.pointer, input_len)) {
4219 err = -EFAULT;
4220 goto exit;
4221 }
4222 ptr = input;
4223 len = strlen(input);
4224
4225 sscanf(ptr, "%16s", cmdname);
4226 cmdlen = strlen(cmdname);
4227
4228
4229 if (cmdlen > 0)
4230 cmdlen += 1;
4231 ptr += cmdlen;
4232 len -= cmdlen;
4233
4234 priv = rtw_private_handler;
4235 priv_args = rtw_private_args;
4236 num_priv_args = ARRAY_SIZE(rtw_private_args);
4237
4238 if (num_priv_args == 0) {
4239 err = -EOPNOTSUPP;
4240 goto exit;
4241 }
4242
4243
4244 k = -1;
4245 while ((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
4246
4247
4248 if (k == num_priv_args) {
4249 err = -EOPNOTSUPP;
4250 goto exit;
4251 }
4252
4253
4254 if (priv_args[k].cmd < SIOCDEVPRIVATE) {
4255 int j = -1;
4256
4257
4258 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
4259 (priv_args[j].set_args != priv_args[k].set_args) ||
4260 (priv_args[j].get_args != priv_args[k].get_args)));
4261
4262
4263 if (j == num_priv_args) {
4264 err = -EINVAL;
4265 goto exit;
4266 }
4267
4268
4269 subcmd = priv_args[k].cmd;
4270
4271 offset = sizeof(__u32);
4272
4273 k = j;
4274 }
4275
4276 buffer = rtw_zmalloc(4096);
4277 if (NULL == buffer) {
4278 err = -ENOMEM;
4279 goto exit;
4280 }
4281
4282
4283 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
4284 (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
4285 u8 *str;
4286
4287 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
4288 case IW_PRIV_TYPE_BYTE:
4289
4290 count = 0;
4291 do {
4292 str = strsep(&ptr, delim);
4293 if (NULL == str)
4294 break;
4295 sscanf(str, "%i", &temp);
4296 buffer[count++] = (u8)temp;
4297 } while (1);
4298 buffer_len = count;
4299
4300
4301 wdata.data.length = count;
4302 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
4303 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
4304
4305 break;
4306
4307 case IW_PRIV_TYPE_INT:
4308
4309 count = 0;
4310 do {
4311 str = strsep(&ptr, delim);
4312 if (NULL == str)
4313 break;
4314 sscanf(str, "%i", &temp);
4315 ((s32 *)buffer)[count++] = (s32)temp;
4316 } while (1);
4317 buffer_len = count * sizeof(s32);
4318
4319
4320 wdata.data.length = count;
4321 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
4322 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
4323
4324 break;
4325
4326 case IW_PRIV_TYPE_CHAR:
4327 if (len > 0) {
4328
4329 wdata.data.length = len;
4330 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
4331 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
4332
4333
4334 memcpy(buffer, ptr, wdata.data.length);
4335 } else {
4336 wdata.data.length = 1;
4337 buffer[0] = '\0';
4338 }
4339 buffer_len = wdata.data.length;
4340 break;
4341
4342 default:
4343 err = -1;
4344 goto exit;
4345 }
4346
4347 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
4348 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
4349 err = -EINVAL;
4350 goto exit;
4351 }
4352 } else {
4353 wdata.data.length = 0L;
4354 }
4355
4356
4357
4358 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
4359 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
4360
4361 if (offset)
4362 wdata.mode = subcmd;
4363 memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
4364 } else {
4365 if ((priv_args[k].set_args == 0) &&
4366 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
4367 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
4368
4369 if (offset)
4370 wdata.mode = subcmd;
4371 } else {
4372
4373 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
4374 err = -EFAULT;
4375 goto exit;
4376 }
4377 wdata.data.flags = subcmd;
4378 }
4379 }
4380
4381 kfree(input);
4382 input = NULL;
4383
4384 extra_size = 0;
4385 if (IW_IS_SET(priv_args[k].cmd)) {
4386
4387 extra_size = get_priv_size(priv_args[k].set_args);
4388
4389
4390 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
4391 ((extra_size + offset) <= IFNAMSIZ))
4392 extra_size = 0;
4393 } else {
4394
4395 extra_size = get_priv_size(priv_args[k].get_args);
4396
4397
4398 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
4399 (extra_size <= IFNAMSIZ))
4400 extra_size = 0;
4401 }
4402
4403 if (extra_size == 0) {
4404 extra = (u8 *)&wdata;
4405 kfree(buffer);
4406 buffer = NULL;
4407 } else
4408 extra = buffer;
4409
4410 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
4411 err = handler(dev, NULL, &wdata, extra);
4412
4413
4414 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
4415 (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
4416 int j;
4417 int n = 0;
4418 u8 str[20] = {0};
4419
4420
4421 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
4422 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
4423 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
4424 else
4425 n = wdata.data.length;
4426
4427 output = rtw_zmalloc(4096);
4428 if (NULL == output) {
4429 err = -ENOMEM;
4430 goto exit;
4431 }
4432
4433 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
4434 case IW_PRIV_TYPE_BYTE:
4435
4436 for (j = 0; j < n; j++) {
4437 len = scnprintf(str, sizeof(str), "%d ", extra[j]);
4438 output_len = strlen(output);
4439 if ((output_len + len + 1) > 4096) {
4440 err = -E2BIG;
4441 goto exit;
4442 }
4443 memcpy(output+output_len, str, len);
4444 }
4445 break;
4446
4447 case IW_PRIV_TYPE_INT:
4448
4449 for (j = 0; j < n; j++) {
4450 len = scnprintf(str, sizeof(str), "%d ", ((__s32 *)extra)[j]);
4451 output_len = strlen(output);
4452 if ((output_len + len + 1) > 4096) {
4453 err = -E2BIG;
4454 goto exit;
4455 }
4456 memcpy(output+output_len, str, len);
4457 }
4458 break;
4459
4460 case IW_PRIV_TYPE_CHAR:
4461
4462 memcpy(output, extra, n);
4463 break;
4464
4465 default:
4466 err = -1;
4467 goto exit;
4468 }
4469
4470 output_len = strlen(output) + 1;
4471 wrq_data->data.length = output_len;
4472 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
4473 err = -EFAULT;
4474 goto exit;
4475 }
4476 } else {
4477 wrq_data->data.length = 0;
4478 }
4479
4480exit:
4481 kfree(input);
4482 kfree(buffer);
4483 kfree(output);
4484
4485 return err;
4486}
4487
4488int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4489{
4490 struct iwreq *wrq = (struct iwreq *)rq;
4491 int ret = 0;
4492
4493 switch (cmd) {
4494 case RTL_IOCTL_WPA_SUPPLICANT:
4495 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
4496 break;
4497 case RTL_IOCTL_HOSTAPD:
4498 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
4499 break;
4500 case SIOCDEVPRIVATE:
4501 ret = rtw_ioctl_wext_private(dev, &wrq->u);
4502 break;
4503 default:
4504 ret = -EOPNOTSUPP;
4505 break;
4506 }
4507
4508 return ret;
4509}
4510