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