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