1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2019 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #define _IOCTL_LINUX_C_
16
17 #include <drv_types.h>
18 #include <rtw_mp.h>
19 #include "../../hal/phydm/phydm_precomp.h"
20 #ifdef RTW_HALMAC
21 #include "../../hal/hal_halmac.h"
22 #endif
23
24 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
25 #define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e)
26 #define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e)
27 #endif
28
29 #ifdef CONFIG_80211N_HT
30 extern int rtw_ht_enable;
31 #endif
32
33
34
35 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)
36
37 #define SCAN_ITEM_SIZE 768
38 #define MAX_CUSTOM_LEN 64
39 #define RATE_COUNT 4
40 #define MAX_SCAN_BUFFER_LEN 65535
41
42 #ifdef CONFIG_GLOBAL_UI_PID
43 extern int ui_pid[3];
44 #endif
45
46 /* combo scan */
47 #define WEXT_CSCAN_AMOUNT 9
48 #define WEXT_CSCAN_BUF_LEN 360
49 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
50 #define WEXT_CSCAN_HEADER_SIZE 12
51 #define WEXT_CSCAN_SSID_SECTION 'S'
52 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
53 #define WEXT_CSCAN_NPROBE_SECTION 'N'
54 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
55 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
56 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
57 #define WEXT_CSCAN_TYPE_SECTION 'T'
58
59
60 extern u8 key_2char2num(u8 hch, u8 lch);
61 extern u8 str_2char2num(u8 hch, u8 lch);
62 extern void macstr2num(u8 *dst, u8 *src);
63 extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
64
65 u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
66 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
67
68 #ifdef CONFIG_RTW_ANDROID
indicate_wx_custom_event(_adapter * padapter,char * msg)69 static void indicate_wx_custom_event(_adapter *padapter, char *msg)
70 {
71 u8 *buff;
72 union iwreq_data wrqu;
73
74 if (strlen(msg) > IW_CUSTOM_MAX) {
75 RTW_INFO("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);
76 return;
77 }
78
79 buff = rtw_zmalloc(IW_CUSTOM_MAX + 1);
80 if (!buff)
81 return;
82
83 _rtw_memcpy(buff, msg, strlen(msg));
84
85 _rtw_memset(&wrqu, 0, sizeof(wrqu));
86 wrqu.data.length = strlen(msg);
87
88 RTW_INFO("%s %s\n", __FUNCTION__, buff);
89 #ifndef CONFIG_IOCTL_CFG80211
90 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
91 #endif
92
93 rtw_mfree(buff, IW_CUSTOM_MAX + 1);
94
95 }
96 #endif
97
98 #if 0
99 static void request_wps_pbc_event(_adapter *padapter)
100 {
101 u8 *buff, *p;
102 union iwreq_data wrqu;
103
104
105 buff = rtw_malloc(IW_CUSTOM_MAX);
106 if (!buff)
107 return;
108
109 _rtw_memset(buff, 0, IW_CUSTOM_MAX);
110
111 p = buff;
112
113 p += sprintf(p, "WPS_PBC_START.request=TRUE");
114
115 _rtw_memset(&wrqu, 0, sizeof(wrqu));
116
117 wrqu.data.length = p - buff;
118
119 wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX;
120
121 RTW_INFO("%s\n", __FUNCTION__);
122
123 #ifndef CONFIG_IOCTL_CFG80211
124 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
125 #endif
126
127 if (buff)
128 rtw_mfree(buff, IW_CUSTOM_MAX);
129
130 }
131 #endif
132
133 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
rtw_request_wps_pbc_event(_adapter * padapter)134 void rtw_request_wps_pbc_event(_adapter *padapter)
135 {
136 #ifdef RTK_DMP_PLATFORM
137 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
138 kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
139 #else
140 kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
141 #endif
142 #else
143
144 if (padapter->pid[0] == 0) {
145 /* 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. */
146 return;
147 }
148
149 rtw_signal_process(padapter->pid[0], SIGUSR1);
150
151 #endif
152
153 rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
154 }
155 #endif/* #ifdef CONFIG_SUPPORT_HW_WPS_PBC */
156
indicate_wx_scan_complete_event(_adapter * padapter)157 void indicate_wx_scan_complete_event(_adapter *padapter)
158 {
159 union iwreq_data wrqu;
160
161 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
162
163 /* RTW_INFO("+rtw_indicate_wx_scan_complete_event\n"); */
164 #ifndef CONFIG_IOCTL_CFG80211
165 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
166 #endif
167 }
168
169
rtw_indicate_wx_assoc_event(_adapter * padapter)170 void rtw_indicate_wx_assoc_event(_adapter *padapter)
171 {
172 union iwreq_data wrqu;
173 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
174 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
175 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
176 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
177
178 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
179
180 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
181
182 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
183 _rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
184 else
185 _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
186
187 RTW_PRINT("assoc success\n");
188 #ifndef CONFIG_IOCTL_CFG80211
189 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
190 #endif
191 }
192
rtw_indicate_wx_disassoc_event(_adapter * padapter)193 void rtw_indicate_wx_disassoc_event(_adapter *padapter)
194 {
195 union iwreq_data wrqu;
196
197 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
198
199 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
200 _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
201
202 #ifndef CONFIG_IOCTL_CFG80211
203 RTW_PRINT("indicate disassoc\n");
204 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
205 #endif
206 }
207
208 /*
209 uint rtw_is_cckrates_included(u8 *rate)
210 {
211 u32 i = 0;
212
213 while(rate[i]!=0)
214 {
215 if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
216 (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )
217 return _TRUE;
218 i++;
219 }
220
221 return _FALSE;
222 }
223
224 uint rtw_is_cckratesonly_included(u8 *rate)
225 {
226 u32 i = 0;
227
228 while(rate[i]!=0)
229 {
230 if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
231 (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )
232 return _FALSE;
233 i++;
234 }
235
236 return _TRUE;
237 }
238 */
239
240 #ifdef CONFIG_IOCTL_WEXT
search_p2p_wfd_ie(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)241 static int search_p2p_wfd_ie(_adapter *padapter,
242 struct iw_request_info *info, struct wlan_network *pnetwork,
243 char *start, char *stop)
244 {
245 #ifdef CONFIG_P2P
246 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
247 #ifdef CONFIG_WFD
248 if (SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type) {
249
250 } else if ((SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type) ||
251 (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type))
252 #endif /* CONFIG_WFD */
253 {
254 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
255 u32 blnGotP2PIE = _FALSE;
256
257 /* User is doing the P2P device discovery */
258 /* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
259 /* If not, the driver should ignore this AP and go to the next AP. */
260
261 /* Verifying the SSID */
262 if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
263 u32 p2pielen = 0;
264
265 /* Verifying the P2P IE */
266 if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen))
267 blnGotP2PIE = _TRUE;
268 }
269
270 if (blnGotP2PIE == _FALSE)
271 return _FALSE;
272
273 }
274 }
275
276 #ifdef CONFIG_WFD
277 if (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type) {
278 u32 blnGotWFD = _FALSE;
279 u8 *wfd_ie;
280 uint wfd_ielen = 0;
281
282 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
283 if (wfd_ie) {
284 u8 *wfd_devinfo;
285 uint wfd_devlen;
286
287 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
288 if (wfd_devinfo) {
289 if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK) {
290 /* the first two bits will indicate the WFD device type */
291 if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_SOURCE) {
292 /* If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. */
293 blnGotWFD = _TRUE;
294 }
295 } else if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE) {
296 /* the first two bits will indicate the WFD device type */
297 if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_PSINK) {
298 /* If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. */
299 /* Todo: How about the SSink?! */
300 blnGotWFD = _TRUE;
301 }
302 }
303 }
304 }
305
306 if (blnGotWFD == _FALSE)
307 return _FALSE;
308 }
309 #endif /* CONFIG_WFD */
310
311 #endif /* CONFIG_P2P */
312 return _TRUE;
313 }
iwe_stream_mac_addr_proess(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)314 static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,
315 struct iw_request_info *info, struct wlan_network *pnetwork,
316 char *start, char *stop, struct iw_event *iwe)
317 {
318 /* AP MAC address */
319 iwe->cmd = SIOCGIWAP;
320 iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
321
322 _rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
323 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);
324 return start;
325 }
iwe_stream_essid_proess(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)326 static inline char *iwe_stream_essid_proess(_adapter *padapter,
327 struct iw_request_info *info, struct wlan_network *pnetwork,
328 char *start, char *stop, struct iw_event *iwe)
329 {
330
331 /* Add the ESSID */
332 iwe->cmd = SIOCGIWESSID;
333 iwe->u.data.flags = 1;
334 iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
335 start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
336 return start;
337 }
338
iwe_stream_chan_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)339 static inline char *iwe_stream_chan_process(_adapter *padapter,
340 struct iw_request_info *info, struct wlan_network *pnetwork,
341 char *start, char *stop, struct iw_event *iwe)
342 {
343 if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
344 pnetwork->network.Configuration.DSConfig = 1;
345
346 /* Add frequency/channel */
347 iwe->cmd = SIOCGIWFREQ;
348 iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
349 iwe->u.freq.e = 1;
350 iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;
351 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);
352 return start;
353 }
iwe_stream_mode_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe,u16 cap)354 static inline char *iwe_stream_mode_process(_adapter *padapter,
355 struct iw_request_info *info, struct wlan_network *pnetwork,
356 char *start, char *stop, struct iw_event *iwe, u16 cap)
357 {
358 /* Add mode */
359 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
360 iwe->cmd = SIOCGIWMODE;
361 if (cap & WLAN_CAPABILITY_BSS)
362 iwe->u.mode = IW_MODE_MASTER;
363 else
364 iwe->u.mode = IW_MODE_ADHOC;
365
366 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);
367 }
368 return start;
369 }
iwe_stream_encryption_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe,u16 cap)370 static inline char *iwe_stream_encryption_process(_adapter *padapter,
371 struct iw_request_info *info, struct wlan_network *pnetwork,
372 char *start, char *stop, struct iw_event *iwe, u16 cap)
373 {
374
375 /* Add encryption capability */
376 iwe->cmd = SIOCGIWENCODE;
377 if (cap & WLAN_CAPABILITY_PRIVACY)
378 iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
379 else
380 iwe->u.data.flags = IW_ENCODE_DISABLED;
381 iwe->u.data.length = 0;
382 start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
383 return start;
384
385 }
386
iwe_stream_protocol_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)387 static inline char *iwe_stream_protocol_process(_adapter *padapter,
388 struct iw_request_info *info, struct wlan_network *pnetwork,
389 char *start, char *stop, struct iw_event *iwe)
390 {
391 u16 ht_cap = _FALSE, vht_cap = _FALSE;
392 u32 ht_ielen = 0, vht_ielen = 0;
393 char *p;
394 u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request */
395
396 #ifdef CONFIG_80211N_HT
397 /* parsing HT_CAP_IE */
398 if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
399 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
400 if (p && ht_ielen > 0)
401 ht_cap = _TRUE;
402 }
403 #endif
404
405 #ifdef CONFIG_80211AC_VHT
406 /* parsing VHT_CAP_IE */
407 if(padapter->registrypriv.wireless_mode & WIRELESS_11AC) {
408 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
409 if (p && vht_ielen > 0)
410 vht_cap = _TRUE;
411 }
412 #endif
413 /* Add the protocol name */
414 iwe->cmd = SIOCGIWNAME;
415 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
416 if (ht_cap == _TRUE)
417 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");
418 else
419 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");
420 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
421 if (ht_cap == _TRUE)
422 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");
423 else
424 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");
425 } else {
426 if (pnetwork->network.Configuration.DSConfig > 14) {
427 #ifdef CONFIG_80211AC_VHT
428 if (vht_cap == _TRUE)
429 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");
430 else
431 #endif
432 {
433 if (ht_cap == _TRUE)
434 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");
435 else
436 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");
437 }
438 } else {
439 if (ht_cap == _TRUE)
440 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");
441 else
442 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");
443 }
444 }
445 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);
446 return start;
447 }
448
iwe_stream_rate_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)449 static inline char *iwe_stream_rate_process(_adapter *padapter,
450 struct iw_request_info *info, struct wlan_network *pnetwork,
451 char *start, char *stop, struct iw_event *iwe)
452 {
453 u32 ht_ielen = 0, vht_ielen = 0;
454 char *p;
455 u16 max_rate = 0, rate, ht_cap = _FALSE, vht_cap = _FALSE;
456 u32 i = 0;
457 u8 bw_40MHz = 0, short_GI = 0, bw_160MHz = 0, vht_highest_rate = 0;
458 u16 mcs_rate = 0, vht_data_rate = 0;
459 char custom[MAX_CUSTOM_LEN] = {0};
460 u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request */
461
462 /* parsing HT_CAP_IE */
463 if(is_supported_ht(padapter->registrypriv.wireless_mode)) {
464 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
465 if (p && ht_ielen > 0) {
466 struct rtw_ieee80211_ht_cap *pht_capie;
467 ht_cap = _TRUE;
468 pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
469 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
470 bw_40MHz = (pht_capie->cap_info & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
471 short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
472 }
473 }
474 #ifdef CONFIG_80211AC_VHT
475 /* parsing VHT_CAP_IE */
476 if(padapter->registrypriv.wireless_mode & WIRELESS_11AC){
477 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
478 if (p && vht_ielen > 0) {
479 u8 mcs_map[2];
480
481 vht_cap = _TRUE;
482 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p + 2);
483 if (bw_160MHz)
484 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p + 2);
485 else
486 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p + 2);
487
488 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p + 2), 2);
489
490 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
491 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
492 }
493 }
494 #endif
495
496 /*Add basic and extended rates */
497 p = custom;
498 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
499 while (pnetwork->network.SupportedRates[i] != 0) {
500 rate = pnetwork->network.SupportedRates[i] & 0x7F;
501 if (rate > max_rate)
502 max_rate = rate;
503 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
504 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
505 i++;
506 }
507 #ifdef CONFIG_80211AC_VHT
508 if (vht_cap == _TRUE)
509 max_rate = vht_data_rate;
510 else
511 #endif
512 if (ht_cap == _TRUE) {
513 if (mcs_rate & 0x8000) /* MCS15 */
514 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
515
516 else if (mcs_rate & 0x0080) /* MCS7 */
517 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
518 else { /* default MCS7 */
519 /* RTW_INFO("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); */
520 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
521 }
522
523 max_rate = max_rate * 2; /* Mbps/2; */
524 }
525
526 iwe->cmd = SIOCGIWRATE;
527 iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
528 iwe->u.bitrate.value = max_rate * 500000;
529 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);
530 return start ;
531 }
532
iwe_stream_wpa_wpa2_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)533 static inline char *iwe_stream_wpa_wpa2_process(_adapter *padapter,
534 struct iw_request_info *info, struct wlan_network *pnetwork,
535 char *start, char *stop, struct iw_event *iwe)
536 {
537 int buf_size = MAX_WPA_IE_LEN * 2;
538 /* u8 pbuf[buf_size]={0}; */
539 u8 *pbuf = rtw_zmalloc(buf_size);
540
541 u8 wpa_ie[255] = {0}, rsn_ie[255] = {0};
542 u16 i, wpa_len = 0, rsn_len = 0;
543 u8 *p;
544 sint out_len = 0;
545
546
547 if (pbuf) {
548 p = pbuf;
549
550 /* parsing WPA/WPA2 IE */
551 if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */
552 out_len = rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
553
554 if (wpa_len > 0) {
555
556 _rtw_memset(pbuf, 0, buf_size);
557 p += sprintf(p, "wpa_ie=");
558 for (i = 0; i < wpa_len; i++)
559 p += sprintf(p, "%02x", wpa_ie[i]);
560
561 if (wpa_len > 100) {
562 printk("-----------------Len %d----------------\n", wpa_len);
563 for (i = 0; i < wpa_len; i++)
564 printk("%02x ", wpa_ie[i]);
565 printk("\n");
566 printk("-----------------Len %d----------------\n", wpa_len);
567 }
568
569 _rtw_memset(iwe, 0, sizeof(*iwe));
570 iwe->cmd = IWEVCUSTOM;
571 iwe->u.data.length = strlen(pbuf);
572 start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
573
574 _rtw_memset(iwe, 0, sizeof(*iwe));
575 iwe->cmd = IWEVGENIE;
576 iwe->u.data.length = wpa_len;
577 start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
578 }
579 if (rsn_len > 0) {
580
581 _rtw_memset(pbuf, 0, buf_size);
582 p += sprintf(p, "rsn_ie=");
583 for (i = 0; i < rsn_len; i++)
584 p += sprintf(p, "%02x", rsn_ie[i]);
585 _rtw_memset(iwe, 0, sizeof(*iwe));
586 iwe->cmd = IWEVCUSTOM;
587 iwe->u.data.length = strlen(pbuf);
588 start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
589
590 _rtw_memset(iwe, 0, sizeof(*iwe));
591 iwe->cmd = IWEVGENIE;
592 iwe->u.data.length = rsn_len;
593 start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
594 }
595 }
596
597 rtw_mfree(pbuf, buf_size);
598 }
599 return start;
600 }
601
iwe_stream_wps_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)602 static inline char *iwe_stream_wps_process(_adapter *padapter,
603 struct iw_request_info *info, struct wlan_network *pnetwork,
604 char *start, char *stop, struct iw_event *iwe)
605 {
606 /* parsing WPS IE */
607 uint cnt = 0, total_ielen;
608 u8 *wpsie_ptr = NULL;
609 uint wps_ielen = 0;
610 u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);
611
612 u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
613 total_ielen = pnetwork->network.IELength - ie_offset;
614
615 if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) { /* Probe Request */
616 ie_ptr = pnetwork->network.IEs;
617 total_ielen = pnetwork->network.IELength;
618 } else { /* Beacon or Probe Respones */
619 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
620 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
621 }
622 while (cnt < total_ielen) {
623 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
624 wpsie_ptr = &ie_ptr[cnt];
625 iwe->cmd = IWEVGENIE;
626 iwe->u.data.length = (u16)wps_ielen;
627 start = iwe_stream_add_point(info, start, stop, iwe, wpsie_ptr);
628 }
629 cnt += ie_ptr[cnt + 1] + 2; /* goto next */
630 }
631 return start;
632 }
633
iwe_stream_wapi_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)634 static inline char *iwe_stream_wapi_process(_adapter *padapter,
635 struct iw_request_info *info, struct wlan_network *pnetwork,
636 char *start, char *stop, struct iw_event *iwe)
637 {
638 #ifdef CONFIG_WAPI_SUPPORT
639 char *p;
640
641 if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */
642 sint out_len_wapi = 0;
643 /* here use static for stack size */
644 static u8 buf_wapi[MAX_WAPI_IE_LEN * 2] = {0};
645 static u8 wapi_ie[MAX_WAPI_IE_LEN] = {0};
646 u16 wapi_len = 0;
647 u16 i;
648
649 out_len_wapi = rtw_get_wapi_ie(pnetwork->network.IEs , pnetwork->network.IELength, wapi_ie, &wapi_len);
650
651 RTW_INFO("rtw_wx_get_scan: %s ", pnetwork->network.Ssid.Ssid);
652 RTW_INFO("rtw_wx_get_scan: ssid = %d ", wapi_len);
653
654
655 if (wapi_len > 0) {
656 p = buf_wapi;
657 /* _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2); */
658 p += sprintf(p, "wapi_ie=");
659 for (i = 0; i < wapi_len; i++)
660 p += sprintf(p, "%02x", wapi_ie[i]);
661
662 _rtw_memset(iwe, 0, sizeof(*iwe));
663 iwe->cmd = IWEVCUSTOM;
664 iwe->u.data.length = strlen(buf_wapi);
665 start = iwe_stream_add_point(info, start, stop, iwe, buf_wapi);
666
667 _rtw_memset(iwe, 0, sizeof(*iwe));
668 iwe->cmd = IWEVGENIE;
669 iwe->u.data.length = wapi_len;
670 start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);
671 }
672 }
673 #endif/* #ifdef CONFIG_WAPI_SUPPORT */
674 return start;
675 }
676
iwe_stream_rssi_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)677 static inline char *iwe_stream_rssi_process(_adapter *padapter,
678 struct iw_request_info *info, struct wlan_network *pnetwork,
679 char *start, char *stop, struct iw_event *iwe)
680 {
681 u8 ss, sq;
682 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
683 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
684 s16 noise = 0;
685 #endif
686
687 /* Add quality statistics */
688 iwe->cmd = IWEVQUAL;
689 iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
690 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
691 | IW_QUAL_NOISE_UPDATED
692 #else
693 | IW_QUAL_NOISE_INVALID
694 #endif
695 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
696 | IW_QUAL_DBM
697 #endif
698 ;
699
700 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE &&
701 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
702 ss = padapter->recvpriv.signal_strength;
703 sq = padapter->recvpriv.signal_qual;
704 } else {
705 ss = pnetwork->network.PhyInfo.SignalStrength;
706 sq = pnetwork->network.PhyInfo.SignalQuality;
707 }
708
709
710 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
711 iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
712 #else
713 iwe->u.qual.level = (u8)ss; /* % */
714 #endif
715
716 iwe->u.qual.qual = (u8)sq; /* signal quality */
717
718 #ifdef CONFIG_PLATFORM_ROCKCHIPS
719 iwe->u.qual.noise = -100; /* noise level suggest by zhf@rockchips */
720 #else
721 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
722 if (IS_NM_ENABLE(padapter)) {
723 noise = rtw_noise_query_by_chan_num(padapter, pnetwork->network.Configuration.DSConfig);
724 #ifndef CONFIG_SIGNAL_DISPLAY_DBM
725 noise = translate_dbm_to_percentage(noise);/*percentage*/
726 #endif
727 iwe->u.qual.noise = noise;
728 }
729 #else
730 iwe->u.qual.noise = 0; /* noise level */
731 #endif
732 #endif /* CONFIG_PLATFORM_ROCKCHIPS */
733
734 /* RTW_INFO("iqual=%d, ilevel=%d, inoise=%d, iupdated=%d\n", iwe.u.qual.qual, iwe.u.qual.level , iwe.u.qual.noise, iwe.u.qual.updated); */
735
736 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);
737 return start;
738 }
739
iwe_stream_net_rsv_process(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop,struct iw_event * iwe)740 static inline char *iwe_stream_net_rsv_process(_adapter *padapter,
741 struct iw_request_info *info, struct wlan_network *pnetwork,
742 char *start, char *stop, struct iw_event *iwe)
743 {
744 u8 buf[32] = {0};
745 u8 *p, *pos;
746 p = buf;
747 pos = pnetwork->network.Reserved;
748
749 p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
750 _rtw_memset(iwe, 0, sizeof(*iwe));
751 iwe->cmd = IWEVCUSTOM;
752 iwe->u.data.length = strlen(buf);
753 start = iwe_stream_add_point(info, start, stop, iwe, buf);
754 return start;
755 }
756
translate_scan(_adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)757 static char *translate_scan(_adapter *padapter,
758 struct iw_request_info *info, struct wlan_network *pnetwork,
759 char *start, char *stop)
760 {
761 struct iw_event iwe;
762 u16 cap = 0;
763 _rtw_memset(&iwe, 0, sizeof(iwe));
764
765 if (_FALSE == search_p2p_wfd_ie(padapter, info, pnetwork, start, stop))
766 return start;
767
768 start = iwe_stream_mac_addr_proess(padapter, info, pnetwork, start, stop, &iwe);
769 start = iwe_stream_essid_proess(padapter, info, pnetwork, start, stop, &iwe);
770 start = iwe_stream_protocol_process(padapter, info, pnetwork, start, stop, &iwe);
771 if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) /* Probe Request */
772 cap = 0;
773 else {
774 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
775 cap = le16_to_cpu(cap);
776 }
777
778 start = iwe_stream_mode_process(padapter, info, pnetwork, start, stop, &iwe, cap);
779 start = iwe_stream_chan_process(padapter, info, pnetwork, start, stop, &iwe);
780 start = iwe_stream_encryption_process(padapter, info, pnetwork, start, stop, &iwe, cap);
781 start = iwe_stream_rate_process(padapter, info, pnetwork, start, stop, &iwe);
782 start = iwe_stream_wpa_wpa2_process(padapter, info, pnetwork, start, stop, &iwe);
783 start = iwe_stream_wps_process(padapter, info, pnetwork, start, stop, &iwe);
784 start = iwe_stream_wapi_process(padapter, info, pnetwork, start, stop, &iwe);
785 start = iwe_stream_rssi_process(padapter, info, pnetwork, start, stop, &iwe);
786 start = iwe_stream_net_rsv_process(padapter, info, pnetwork, start, stop, &iwe);
787
788 return start;
789 }
790
wpa_set_auth_algs(struct net_device * dev,u32 value)791 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
792 {
793 _adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
794 int ret = 0;
795
796 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
797 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
798 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
799 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
800 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
801 } else if (value & AUTH_ALG_SHARED_KEY) {
802 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);
803 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
804
805 #ifdef CONFIG_PLATFORM_MT53XX
806 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
807 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
808 #else
809 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
810 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
811 #endif
812 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
813 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
814 /* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
815 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
816 #ifdef CONFIG_PLATFORM_MT53XX
817 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
818 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
819 #else
820 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
821 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
822 #endif
823 }
824
825 } else if (value & AUTH_ALG_LEAP)
826 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
827 else {
828 RTW_INFO("wpa_set_auth_algs, error!\n");
829 ret = -EINVAL;
830 }
831
832 return ret;
833
834 }
835
wpa_set_encryption(struct net_device * dev,struct ieee_param * param,u32 param_len)836 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
837 {
838 int ret = 0;
839 u32 wep_key_idx, wep_key_len;
840 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
841 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
842 struct security_priv *psecuritypriv = &padapter->securitypriv;
843 #ifdef CONFIG_P2P
844 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
845 #endif /* CONFIG_P2P */
846
847
848 param->u.crypt.err = 0;
849 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
850
851 if (param_len < (u32)((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
852 ret = -EINVAL;
853 goto exit;
854 }
855
856 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
857 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
858 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
859
860 if (param->u.crypt.idx >= WEP_KEYS
861 #ifdef CONFIG_IEEE80211W
862 && param->u.crypt.idx > BIP_MAX_KEYID
863 #endif /* CONFIG_IEEE80211W */
864 ) {
865 ret = -EINVAL;
866 goto exit;
867 }
868 } else {
869 #ifdef CONFIG_WAPI_SUPPORT
870 if (strcmp(param->u.crypt.alg, "SMS4"))
871 #endif
872 {
873 ret = -EINVAL;
874 goto exit;
875 }
876 }
877
878 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
879 RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
880
881 wep_key_idx = param->u.crypt.idx;
882 wep_key_len = param->u.crypt.key_len;
883
884 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
885 ret = -EINVAL;
886 goto exit;
887 }
888
889 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
890 /* wep default key has not been set, so use this key index as default key.*/
891
892 wep_key_len = wep_key_len <= 5 ? 5 : 13;
893
894 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
895 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
896 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
897
898 if (wep_key_len == 13) {
899 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
900 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
901 }
902
903 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
904 }
905
906 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
907
908 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
909
910 psecuritypriv->key_mask |= BIT(wep_key_idx);
911
912 padapter->mlmeextpriv.mlmext_info.key_index = wep_key_idx;
913 goto exit;
914 }
915
916 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
917 struct sta_info *psta, *pbcmc_sta;
918 struct sta_priv *pstapriv = &padapter->stapriv;
919
920 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
921 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
922 if (psta == NULL) {
923 /* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
924 } else {
925 /* Jeff: don't disable ieee8021x_blocked while clearing key */
926 if (strcmp(param->u.crypt.alg, "none") != 0)
927 psta->ieee8021x_blocked = _FALSE;
928
929 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
930 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
931 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
932
933 if (param->u.crypt.set_tx == 1) { /* pairwise key */
934 RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n"
935 , FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
936 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
937 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
938 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
939 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
940 padapter->securitypriv.busetkipkey = _FALSE;
941 }
942 psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
943 psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
944 psta->bpairwise_key_installed = _TRUE;
945 rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
946
947 } else { /* group key */
948 if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
949 RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"
950 , FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
951 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,
952 (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
953 /* only TKIP group key need to install this */
954 if (param->u.crypt.key_len > 16) {
955 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
956 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
957 }
958 padapter->securitypriv.binstallGrpkey = _TRUE;
959 if (param->u.crypt.idx < 4)
960 _rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8);
961 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
962 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
963
964 #ifdef CONFIG_IEEE80211W
965 } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
966 RTW_INFO(FUNC_ADPT_FMT" set IGTK idx:%u, len:%u\n"
967 , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
968 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,
969 (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
970 psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
971 psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
972 psecuritypriv->binstallBIPkey = _TRUE;
973 #endif /* CONFIG_IEEE80211W */
974
975 }
976
977 #ifdef CONFIG_P2P
978 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
979 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
980 #endif /* CONFIG_P2P */
981
982 /* WPA/WPA2 key-handshake has completed */
983 clr_fwstate(pmlmepriv, WIFI_UNDER_KEY_HANDSHAKE);
984 }
985 }
986
987 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
988 if (pbcmc_sta == NULL) {
989 /* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
990 } else {
991 /* Jeff: don't disable ieee8021x_blocked while clearing key */
992 if (strcmp(param->u.crypt.alg, "none") != 0)
993 pbcmc_sta->ieee8021x_blocked = _FALSE;
994
995 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
996 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
997 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
998 }
999 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1000 }
1001 }
1002
1003 #ifdef CONFIG_WAPI_SUPPORT
1004 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1005 rtw_wapi_set_set_encryption(padapter, param);
1006 #endif
1007
1008 exit:
1009
1010
1011 return ret;
1012 }
1013
rtw_set_wpa_ie(_adapter * padapter,char * pie,unsigned short ielen)1014 static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1015 {
1016 u8 *buf = NULL, *pos = NULL;
1017 int group_cipher = 0, pairwise_cipher = 0;
1018 u8 mfp_opt = MFP_NO;
1019 int ret = 0;
1020 u8 null_addr[] = {0, 0, 0, 0, 0, 0};
1021 #ifdef CONFIG_P2P
1022 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1023 #endif /* CONFIG_P2P */
1024
1025 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
1026 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1027 if (pie == NULL)
1028 return ret;
1029 else
1030 return -EINVAL;
1031 }
1032
1033 if (ielen) {
1034 buf = rtw_zmalloc(ielen);
1035 if (buf == NULL) {
1036 ret = -ENOMEM;
1037 goto exit;
1038 }
1039
1040 _rtw_memcpy(buf, pie , ielen);
1041
1042 /* dump */
1043 {
1044 int i;
1045 RTW_INFO("\n wpa_ie(length:%d):\n", ielen);
1046 for (i = 0; i < ielen; i = i + 8)
1047 RTW_INFO("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]);
1048 }
1049
1050 pos = buf;
1051 if (ielen < RSN_HEADER_LEN) {
1052 ret = -1;
1053 goto exit;
1054 }
1055
1056 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1057 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1058 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
1059 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1060 }
1061
1062 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL, NULL, &mfp_opt, NULL) == _SUCCESS) {
1063 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1064 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1065 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1066 }
1067
1068 if (group_cipher == 0)
1069 group_cipher = WPA_CIPHER_NONE;
1070 if (pairwise_cipher == 0)
1071 pairwise_cipher = WPA_CIPHER_NONE;
1072
1073 switch (group_cipher) {
1074 case WPA_CIPHER_NONE:
1075 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1076 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1077 break;
1078 case WPA_CIPHER_WEP40:
1079 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1080 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1081 break;
1082 case WPA_CIPHER_TKIP:
1083 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1084 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1085 break;
1086 case WPA_CIPHER_CCMP:
1087 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1088 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1089 break;
1090 case WPA_CIPHER_WEP104:
1091 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1092 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1093 break;
1094 }
1095
1096 switch (pairwise_cipher) {
1097 case WPA_CIPHER_NONE:
1098 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1099 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1100 break;
1101 case WPA_CIPHER_WEP40:
1102 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1103 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1104 break;
1105 case WPA_CIPHER_TKIP:
1106 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1107 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1108 break;
1109 case WPA_CIPHER_CCMP:
1110 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
1111 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1112 break;
1113 case WPA_CIPHER_WEP104:
1114 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1115 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1116 break;
1117 }
1118
1119 if (mfp_opt == MFP_INVALID) {
1120 RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));
1121 ret = -EINVAL;
1122 goto exit;
1123 }
1124 padapter->securitypriv.mfp_opt = mfp_opt;
1125
1126 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1127 {/* set wps_ie */
1128 u16 cnt = 0;
1129 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
1130
1131 while (cnt < ielen) {
1132 eid = buf[cnt];
1133
1134 if ((eid == _VENDOR_SPECIFIC_IE_) && (_rtw_memcmp(&buf[cnt + 2], wps_oui, 4) == _TRUE)) {
1135 RTW_INFO("SET WPS_IE\n");
1136
1137 padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < MAX_WPS_IE_LEN) ? (buf[cnt + 1] + 2) : MAX_WPS_IE_LEN;
1138
1139 _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1140
1141 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1142
1143 #ifdef CONFIG_P2P
1144 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1145 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1146 #endif /* CONFIG_P2P */
1147 cnt += buf[cnt + 1] + 2;
1148
1149 break;
1150 } else {
1151 cnt += buf[cnt + 1] + 2; /* goto next */
1152 }
1153 }
1154 }
1155
1156 #ifdef CONFIG_RTW_MULTI_AP
1157 padapter->multi_ap = rtw_get_multi_ap_ie_ext(buf, ielen) & MULTI_AP_BACKHAUL_STA;
1158 if (padapter->multi_ap)
1159 adapter_set_use_wds(padapter, 1);
1160 #endif
1161 }
1162
1163 /* TKIP and AES disallow multicast packets until installing group key */
1164 if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1165 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1166 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1167 /* WPS open need to enable multicast
1168 * || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
1169 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1170
1171
1172 exit:
1173
1174 if (buf)
1175 rtw_mfree(buf, ielen);
1176
1177 return ret;
1178 }
1179
rtw_wx_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1180 static int rtw_wx_get_name(struct net_device *dev,
1181 struct iw_request_info *info,
1182 union iwreq_data *wrqu, char *extra)
1183 {
1184 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1185 u32 ht_ielen = 0;
1186 char *p;
1187 u8 ht_cap = _FALSE, vht_cap = _FALSE;
1188 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1189 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1190 NDIS_802_11_RATES_EX *prates = NULL;
1191
1192
1193
1194 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
1195 /* parsing HT_CAP_IE */
1196 if( is_supported_ht(padapter->registrypriv.wireless_mode)&&(padapter->registrypriv.ht_enable)) {
1197 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
1198 if (p && ht_ielen > 0 )
1199 ht_cap = _TRUE;
1200 }
1201 #ifdef CONFIG_80211AC_VHT
1202 if ((padapter->registrypriv.wireless_mode & WIRELESS_11AC) &&
1203 (pmlmepriv->vhtpriv.vht_option == _TRUE))
1204 vht_cap = _TRUE;
1205 #endif
1206
1207 prates = &pcur_bss->SupportedRates;
1208 if (rtw_is_cckratesonly_included((u8 *)prates) == _TRUE) {
1209 if (ht_cap == _TRUE)
1210 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1211 else
1212 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1213 } else if ((rtw_is_cckrates_included((u8 *)prates)) == _TRUE) {
1214 if (ht_cap == _TRUE)
1215 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1216 else {
1217 if(padapter->registrypriv.wireless_mode & WIRELESS_11G)
1218 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1219 else
1220 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1221 }
1222 } else {
1223 if (pcur_bss->Configuration.DSConfig > 14) {
1224 #ifdef CONFIG_80211AC_VHT
1225 if (vht_cap == _TRUE)
1226 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1227 else
1228 #endif
1229 {
1230 if (ht_cap == _TRUE)
1231 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1232 else
1233 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1234 }
1235 } else {
1236 if (ht_cap == _TRUE)
1237 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1238 else
1239 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1240 }
1241 }
1242 } else {
1243 /* prates = &padapter->registrypriv.dev_network.SupportedRates; */
1244 /* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */
1245 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1246 }
1247
1248
1249 return 0;
1250 }
1251
rtw_wx_set_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1252 static int rtw_wx_set_freq(struct net_device *dev,
1253 struct iw_request_info *info,
1254 union iwreq_data *wrqu, char *extra)
1255 {
1256
1257 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1258 int exp = 1, freq = 0, div = 0;
1259
1260 rtw_ps_deny(padapter, PS_DENY_IOCTL);
1261 if (rtw_pwr_wakeup(padapter) == _FALSE)
1262 goto exit;
1263 if (wrqu->freq.m <= 1000) {
1264 if (wrqu->freq.flags == IW_FREQ_AUTO) {
1265 if (rtw_chset_search_ch(adapter_to_chset(padapter), wrqu->freq.m) > 0) {
1266 padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1267 RTW_INFO("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m);
1268 } else {
1269 padapter->mlmeextpriv.cur_channel = 1;
1270 RTW_INFO("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__);
1271 }
1272 } else {
1273 padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1274 RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1275 }
1276 } else {
1277 while (wrqu->freq.e) {
1278 exp *= 10;
1279 wrqu->freq.e--;
1280 }
1281
1282 freq = wrqu->freq.m;
1283
1284 while (!(freq % 10)) {
1285 freq /= 10;
1286 exp *= 10;
1287 }
1288
1289 /* freq unit is MHz here */
1290 div = 1000000 / exp;
1291
1292 if (div)
1293 freq /= div;
1294 else {
1295 div = exp / 1000000;
1296 freq *= div;
1297 }
1298
1299 /* If freq is invalid, rtw_freq2ch() will return channel 1 */
1300 padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);
1301 RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1302 }
1303 set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
1304 exit:
1305 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
1306
1307 return 0;
1308 }
1309
rtw_wx_get_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1310 static int rtw_wx_get_freq(struct net_device *dev,
1311 struct iw_request_info *info,
1312 union iwreq_data *wrqu, char *extra)
1313 {
1314 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1315 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1316 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1317
1318 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1319
1320 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1321 wrqu->freq.e = 1;
1322 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1323
1324 } else {
1325 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1326 wrqu->freq.e = 1;
1327 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1328 }
1329
1330 return 0;
1331 }
1332
rtw_wx_set_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)1333 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1334 union iwreq_data *wrqu, char *b)
1335 {
1336 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1337 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1338 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1339 int ret = 0;
1340
1341
1342 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1343 ret = -EPERM;
1344 goto exit;
1345 }
1346
1347 if (!rtw_is_hw_init_completed(padapter)) {
1348 ret = -EPERM;
1349 goto exit;
1350 }
1351
1352 /* initial default type */
1353 dev->type = ARPHRD_ETHER;
1354
1355 if (wrqu->mode != IW_MODE_MONITOR) {
1356 rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE);
1357 }
1358
1359 switch (wrqu->mode) {
1360 #ifdef CONFIG_WIFI_MONITOR
1361 case IW_MODE_MONITOR:
1362 networkType = Ndis802_11Monitor;
1363
1364 rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE);
1365 LeaveAllPowerSaveMode(padapter);
1366
1367 #if 0
1368 dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
1369 #endif
1370
1371 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
1372 dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
1373 RTW_INFO("set_mode = IW_MODE_MONITOR\n");
1374 #else
1375 RTW_INFO("kernel version < 2.6.24 not support IW_MODE_MONITOR\n");
1376 #endif
1377 break;
1378 #endif /* CONFIG_WIFI_MONITOR */
1379 case IW_MODE_AUTO:
1380 networkType = Ndis802_11AutoUnknown;
1381 RTW_INFO("set_mode = IW_MODE_AUTO\n");
1382 break;
1383 case IW_MODE_ADHOC:
1384 networkType = Ndis802_11IBSS;
1385 RTW_INFO("set_mode = IW_MODE_ADHOC\n");
1386 break;
1387 case IW_MODE_MASTER:
1388 networkType = Ndis802_11APMode;
1389 RTW_INFO("set_mode = IW_MODE_MASTER\n");
1390 break;
1391 case IW_MODE_INFRA:
1392 networkType = Ndis802_11Infrastructure;
1393 RTW_INFO("set_mode = IW_MODE_INFRA\n");
1394 break;
1395
1396 default:
1397 ret = -EINVAL;;
1398 goto exit;
1399 }
1400
1401 #ifdef CONFIG_AP_MODE
1402 if (MLME_IS_AP(padapter) && networkType == Ndis802_11Infrastructure)
1403 rtw_stop_ap_cmd(padapter, RTW_CMDF_WAIT_ACK);
1404 else
1405 #endif
1406 {
1407 if (rtw_set_802_11_infrastructure_mode(padapter, networkType, 0) == _FALSE) {
1408 ret = -EPERM;
1409 goto exit;
1410 }
1411 rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
1412 }
1413
1414 if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1415 rtw_indicate_connect(padapter);
1416
1417 exit:
1418
1419
1420 return ret;
1421
1422 }
1423
rtw_wx_get_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)1424 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1425 union iwreq_data *wrqu, char *b)
1426 {
1427 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1428 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1429
1430
1431
1432 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1433 wrqu->mode = IW_MODE_INFRA;
1434 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1435 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1436
1437 wrqu->mode = IW_MODE_ADHOC;
1438 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1439 wrqu->mode = IW_MODE_MASTER;
1440 else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1441 wrqu->mode = IW_MODE_MONITOR;
1442 else
1443 wrqu->mode = IW_MODE_AUTO;
1444
1445
1446 return 0;
1447
1448 }
1449
1450
rtw_wx_set_pmkid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1451 static int rtw_wx_set_pmkid(struct net_device *dev,
1452 struct iw_request_info *a,
1453 union iwreq_data *wrqu, char *extra)
1454 {
1455 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1456 u8 j, blInserted = _FALSE;
1457 int intReturn = _FALSE;
1458 struct security_priv *psecuritypriv = &padapter->securitypriv;
1459 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
1460 u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
1461 u8 strIssueBssid[ETH_ALEN] = { 0x00 };
1462
1463 #if 0
1464 struct iw_pmksa {
1465 __u32 cmd;
1466 struct sockaddr bssid;
1467 __u8 pmkid[IW_PMKID_LEN]; /* IW_PMKID_LEN=16 */
1468 }
1469 There are the BSSID information in the bssid.sa_data array.
1470 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1471 If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID / BSSID to driver.
1472 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID / BSSID from driver.
1473 #endif
1474
1475 _rtw_memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1476 if (pPMK->cmd == IW_PMKSA_ADD) {
1477 RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
1478 if (_rtw_memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
1479 return intReturn ;
1480 else
1481 intReturn = _TRUE;
1482 blInserted = _FALSE;
1483
1484 /* overwrite PMKID */
1485 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1486 if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1487 /* BSSID is matched, the same AP => rewrite with new PMKID. */
1488
1489 RTW_INFO("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
1490
1491 _rtw_memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1492 psecuritypriv->PMKIDList[j].bUsed = _TRUE;
1493 blInserted = _TRUE;
1494 break;
1495 }
1496 }
1497
1498 if (!blInserted) {
1499 /* Find a new entry */
1500 RTW_INFO("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1501 psecuritypriv->PMKIDIndex);
1502
1503 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1504 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1505
1506 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
1507 psecuritypriv->PMKIDIndex++ ;
1508 if (psecuritypriv->PMKIDIndex == 16)
1509 psecuritypriv->PMKIDIndex = 0;
1510 }
1511 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
1512 RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
1513 intReturn = _TRUE;
1514 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1515 if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1516 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
1517 _rtw_memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
1518 psecuritypriv->PMKIDList[j].bUsed = _FALSE;
1519 break;
1520 }
1521 }
1522 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
1523 RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
1524 _rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
1525 psecuritypriv->PMKIDIndex = 0;
1526 intReturn = _TRUE;
1527 }
1528 return intReturn ;
1529 }
1530
rtw_wx_get_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1531 static int rtw_wx_get_sens(struct net_device *dev,
1532 struct iw_request_info *info,
1533 union iwreq_data *wrqu, char *extra)
1534 {
1535 #ifdef CONFIG_PLATFORM_ROCKCHIPS
1536 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1537 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1538
1539 /*
1540 * 20110311 Commented by Jeff
1541 * For rockchip platform's wpa_driver_wext_get_rssi
1542 */
1543 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
1544 /* wrqu->sens.value=-padapter->recvpriv.signal_strength; */
1545 wrqu->sens.value = -padapter->recvpriv.rssi;
1546 /* RTW_INFO("%s: %d\n", __FUNCTION__, wrqu->sens.value); */
1547 wrqu->sens.fixed = 0; /* no auto select */
1548 } else
1549 #endif
1550 {
1551 wrqu->sens.value = 0;
1552 wrqu->sens.fixed = 0; /* no auto select */
1553 wrqu->sens.disabled = 1;
1554 }
1555 return 0;
1556 }
1557
rtw_wx_get_range(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1558 static int rtw_wx_get_range(struct net_device *dev,
1559 struct iw_request_info *info,
1560 union iwreq_data *wrqu, char *extra)
1561 {
1562 struct iw_range *range = (struct iw_range *)extra;
1563 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1564 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1565 u16 val;
1566 int i;
1567
1568
1569
1570 wrqu->data.length = sizeof(*range);
1571 _rtw_memset(range, 0, sizeof(*range));
1572
1573 /* Let's try to keep this struct in the same order as in
1574 * linux/include/wireless.h
1575 */
1576
1577 /* TODO: See what values we can set, and remove the ones we can't
1578 * set, or fill them with some default data.
1579 */
1580
1581 /* ~5 Mb/s real (802.11b) */
1582 range->throughput = 5 * 1000 * 1000;
1583
1584 /* TODO: Not used in 802.11b?
1585 * range->min_nwid; Minimal NWID we are able to set */
1586 /* TODO: Not used in 802.11b?
1587 * range->max_nwid; Maximal NWID we are able to set */
1588
1589 /* Old Frequency (backward compat - moved lower ) */
1590 /* range->old_num_channels;
1591 * range->old_num_frequency;
1592 * range->old_freq[6]; Filler to keep "version" at the same offset */
1593
1594 /* signal level threshold range */
1595
1596 /* Quality of link & SNR stuff */
1597 /* Quality range (link, level, noise)
1598 * If the quality is absolute, it will be in the range [0 ; max_qual],
1599 * if the quality is dBm, it will be in the range [max_qual ; 0].
1600 * Don't forget that we use 8 bit arithmetics...
1601 *
1602 * If percentage range is 0~100
1603 * Signal strength dbm range logical is -100 ~ 0
1604 * but usually value is -90 ~ -20
1605 */
1606 range->max_qual.qual = 100;
1607 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1608 range->max_qual.level = (u8)-100;
1609 range->max_qual.noise = (u8)-100;
1610 range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1611 range->max_qual.updated |= IW_QUAL_DBM;
1612 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
1613 /* percent values between 0 and 100. */
1614 range->max_qual.level = 100;
1615 range->max_qual.noise = 100;
1616 range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1617 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
1618
1619 /* This should contain the average/typical values of the quality
1620 * indicator. This should be the threshold between a "good" and
1621 * a "bad" link (example : monitor going from green to orange).
1622 * Currently, user space apps like quality monitors don't have any
1623 * way to calibrate the measurement. With this, they can split
1624 * the range between 0 and max_qual in different quality level
1625 * (using a geometric subdivision centered on the average).
1626 * I expect that people doing the user space apps will feedback
1627 * us on which value we need to put in each driver... */
1628 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1629 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1630 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
1631 range->avg_qual.level = (u8)-70;
1632 range->avg_qual.noise = 0;
1633 range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1634 range->avg_qual.updated |= IW_QUAL_DBM;
1635 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
1636 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1637 range->avg_qual.level = 30;
1638 range->avg_qual.noise = 100;
1639 range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1640 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
1641
1642 range->num_bitrates = RATE_COUNT;
1643
1644 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
1645 range->bitrate[i] = rtw_rates[i];
1646
1647 range->min_frag = MIN_FRAG_THRESHOLD;
1648 range->max_frag = MAX_FRAG_THRESHOLD;
1649
1650 range->pm_capa = 0;
1651
1652 range->we_version_compiled = WIRELESS_EXT;
1653 range->we_version_source = 16;
1654
1655 /* range->retry_capa; What retry options are supported
1656 * range->retry_flags; How to decode max/min retry limit
1657 * range->r_time_flags; How to decode max/min retry life
1658 * range->min_retry; Minimal number of retries
1659 * range->max_retry; Maximal number of retries
1660 * range->min_r_time; Minimal retry lifetime
1661 * range->max_r_time; Maximal retry lifetime */
1662
1663 for (i = 0, val = 0; i < rfctl->max_chan_nums; i++) {
1664
1665 /* Include only legal frequencies for some countries */
1666 if (rfctl->channel_set[i].ChannelNum != 0) {
1667 range->freq[val].i = rfctl->channel_set[i].ChannelNum;
1668 range->freq[val].m = rtw_ch2freq(rfctl->channel_set[i].ChannelNum) * 100000;
1669 range->freq[val].e = 1;
1670 val++;
1671 }
1672
1673 if (val == IW_MAX_FREQUENCIES)
1674 break;
1675 }
1676
1677 range->num_channels = val;
1678 range->num_frequency = val;
1679
1680 /* Commented by Albert 2009/10/13
1681 * The following code will proivde the security capability to network manager.
1682 * If the driver doesn't provide this capability to network manager,
1683 * the WPA/WPA2 routers can't be choosen in the network manager. */
1684
1685 /*
1686 #define IW_SCAN_CAPA_NONE 0x00
1687 #define IW_SCAN_CAPA_ESSID 0x01
1688 #define IW_SCAN_CAPA_BSSID 0x02
1689 #define IW_SCAN_CAPA_CHANNEL 0x04
1690 #define IW_SCAN_CAPA_MODE 0x08
1691 #define IW_SCAN_CAPA_RATE 0x10
1692 #define IW_SCAN_CAPA_TYPE 0x20
1693 #define IW_SCAN_CAPA_TIME 0x40
1694 */
1695
1696 #if WIRELESS_EXT > 17
1697 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1698 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1699 #endif
1700
1701 #ifdef IW_SCAN_CAPA_ESSID /* WIRELESS_EXT > 21 */
1702 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID |
1703 IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
1704 #endif
1705
1706
1707
1708 return 0;
1709
1710 }
1711
1712 /* set bssid flow
1713 * s1. rtw_set_802_11_infrastructure_mode()
1714 * s2. rtw_set_802_11_authentication_mode()
1715 * s3. set_802_11_encryption_mode()
1716 * s4. rtw_set_802_11_bssid() */
rtw_wx_set_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)1717 static int rtw_wx_set_wap(struct net_device *dev,
1718 struct iw_request_info *info,
1719 union iwreq_data *awrq,
1720 char *extra)
1721 {
1722 _irqL irqL;
1723 uint ret = 0;
1724 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1725 struct sockaddr *temp = (struct sockaddr *)awrq;
1726 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1727 _list *phead;
1728 u8 *dst_bssid, *src_bssid;
1729 _queue *queue = &(pmlmepriv->scanned_queue);
1730 struct wlan_network *pnetwork = NULL;
1731 NDIS_802_11_AUTHENTICATION_MODE authmode;
1732
1733 /*
1734 #ifdef CONFIG_CONCURRENT_MODE
1735 if(padapter->adapter_type > PRIMARY_IFACE)
1736 {
1737 ret = -EINVAL;
1738 goto exit;
1739 }
1740 #endif
1741 */
1742
1743 #ifdef CONFIG_CONCURRENT_MODE
1744 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) {
1745 RTW_INFO("set bssid, but buddy_intf is under scanning or linking\n");
1746
1747 ret = -EINVAL;
1748
1749 goto exit;
1750 }
1751 #endif
1752
1753 rtw_ps_deny(padapter, PS_DENY_JOIN);
1754 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1755 ret = -1;
1756 goto cancel_ps_deny;
1757 }
1758
1759 if (!padapter->bup) {
1760 ret = -1;
1761 goto cancel_ps_deny;
1762 }
1763
1764
1765 if (temp->sa_family != ARPHRD_ETHER) {
1766 ret = -EINVAL;
1767 goto cancel_ps_deny;
1768 }
1769
1770 authmode = padapter->securitypriv.ndisauthtype;
1771 _enter_critical_bh(&queue->lock, &irqL);
1772 phead = get_list_head(queue);
1773 pmlmepriv->pscanned = get_next(phead);
1774
1775 while (1) {
1776
1777 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) {
1778 #if 0
1779 ret = -EINVAL;
1780 goto cancel_ps_deny;
1781
1782 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
1783 rtw_set_802_11_bssid(padapter, temp->sa_data);
1784 goto cancel_ps_deny;
1785 } else {
1786 ret = -EINVAL;
1787 goto cancel_ps_deny;
1788 }
1789 #endif
1790
1791 break;
1792 }
1793
1794 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1795
1796 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1797
1798 dst_bssid = pnetwork->network.MacAddress;
1799
1800 src_bssid = temp->sa_data;
1801
1802 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) {
1803 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0)) {
1804 ret = -1;
1805 _exit_critical_bh(&queue->lock, &irqL);
1806 goto cancel_ps_deny;
1807 }
1808
1809 break;
1810 }
1811
1812 }
1813 _exit_critical_bh(&queue->lock, &irqL);
1814
1815 rtw_set_802_11_authentication_mode(padapter, authmode);
1816 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1817 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
1818 ret = -1;
1819 goto cancel_ps_deny;
1820 }
1821
1822 cancel_ps_deny:
1823 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1824
1825 #ifdef CONFIG_CONCURRENT_MODE
1826 exit:
1827 #endif
1828 return ret;
1829 }
1830
rtw_wx_get_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1831 static int rtw_wx_get_wap(struct net_device *dev,
1832 struct iw_request_info *info,
1833 union iwreq_data *wrqu, char *extra)
1834 {
1835
1836 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1837 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1838 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1839
1840 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1841
1842 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1843
1844
1845
1846 if (((check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) == _TRUE) ||
1847 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
1848 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE))
1849
1850 _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1851 else
1852 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1853
1854
1855 return 0;
1856
1857 }
1858
rtw_wx_set_mlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1859 static int rtw_wx_set_mlme(struct net_device *dev,
1860 struct iw_request_info *info,
1861 union iwreq_data *wrqu, char *extra)
1862 {
1863 #if 0
1864 /* SIOCSIWMLME data */
1865 struct iw_mlme {
1866 __u16 cmd; /* IW_MLME_* */
1867 __u16 reason_code;
1868 struct sockaddr addr;
1869 };
1870 #endif
1871
1872 int ret = 0;
1873 u16 reason;
1874 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1875 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1876
1877
1878 if (mlme == NULL)
1879 return -1;
1880
1881 RTW_INFO("%s\n", __FUNCTION__);
1882
1883 reason = cpu_to_le16(mlme->reason_code);
1884
1885
1886 RTW_INFO("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
1887
1888
1889 switch (mlme->cmd) {
1890 case IW_MLME_DEAUTH:
1891 if (!rtw_set_802_11_disassociate(padapter))
1892 ret = -1;
1893 break;
1894
1895 case IW_MLME_DISASSOC:
1896 if (!rtw_set_802_11_disassociate(padapter))
1897 ret = -1;
1898
1899 break;
1900
1901 default:
1902 return -EOPNOTSUPP;
1903 }
1904 #ifdef CONFIG_RTW_REPEATER_SON
1905 rtw_rson_do_disconnect(padapter);
1906 #endif
1907 return ret;
1908 }
1909
rtw_wx_set_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1910 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1911 union iwreq_data *wrqu, char *extra)
1912 {
1913 u8 _status = _FALSE;
1914 int ret = 0;
1915 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1916 /*struct mlme_priv *pmlmepriv = &padapter->mlmepriv;*/
1917 struct sitesurvey_parm parm;
1918 u8 ssc_chk;
1919 #ifdef CONFIG_P2P
1920 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1921 #endif /* CONFIG_P2P */
1922
1923 #ifdef DBG_IOCTL
1924 RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
1925 #endif
1926
1927 #if 1
1928 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
1929
1930 #ifdef CONFIG_DOSCAN_IN_BUSYTRAFFIC
1931 if ((ssc_chk != SS_ALLOW) && (ssc_chk != SS_DENY_BUSY_TRAFFIC))
1932 #else
1933 /* When Busy Traffic, driver do not site survey. So driver return success. */
1934 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1935 /* modify by thomas 2011-02-22. */
1936 if (ssc_chk != SS_ALLOW)
1937 #endif
1938 {
1939 if (ssc_chk == SS_DENY_MP_MODE)
1940 ret = -EPERM;
1941 #ifdef DBG_LA_MODE
1942 else if (ssc_chk == SS_DENY_LA_MODE)
1943 ret = -EPERM;
1944 #endif
1945 else
1946 indicate_wx_scan_complete_event(padapter);
1947
1948 goto exit;
1949 } else
1950 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1951
1952 rtw_ps_deny(padapter, PS_DENY_SCAN);
1953 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1954 ret = -1;
1955 goto cancel_ps_deny;
1956 }
1957 if (!rtw_is_adapter_up(padapter)) {
1958 ret = -1;
1959 goto cancel_ps_deny;
1960 }
1961 #else
1962
1963 #ifdef CONFIG_MP_INCLUDED
1964 if (rtw_mp_mode_check(padapter)) {
1965 RTW_INFO("MP mode block Scan request\n");
1966 ret = -EPERM;
1967 goto exit;
1968 }
1969 #endif
1970 if (rtw_is_scan_deny(padapter)) {
1971 indicate_wx_scan_complete_event(padapter);
1972 goto exit;
1973 }
1974
1975 rtw_ps_deny(padapter, PS_DENY_SCAN);
1976 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1977 ret = -1;
1978 goto cancel_ps_deny;
1979 }
1980
1981 if (!rtw_is_adapter_up(padapter)) {
1982 ret = -1;
1983 goto cancel_ps_deny;
1984 }
1985
1986 #ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC
1987 /* When Busy Traffic, driver do not site survey. So driver return success. */
1988 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1989 /* modify by thomas 2011-02-22. */
1990 if (rtw_mi_busy_traffic_check(padapter)) {
1991 indicate_wx_scan_complete_event(padapter);
1992 goto cancel_ps_deny;
1993 }
1994 #endif
1995 #ifdef CONFIG_RTW_REPEATER_SON
1996 if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {
1997 RTW_INFO(FUNC_ADPT_FMT" blocking scan for under rson scanning process\n", FUNC_ADPT_ARG(padapter));
1998 indicate_wx_scan_complete_event(padapter);
1999 goto cancel_ps_deny;
2000 }
2001 #endif
2002 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2003 RTW_INFO("AP mode process WPS\n");
2004 indicate_wx_scan_complete_event(padapter);
2005 goto cancel_ps_deny;
2006 }
2007
2008 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING) == _TRUE) {
2009 indicate_wx_scan_complete_event(padapter);
2010 goto cancel_ps_deny;
2011 }
2012
2013 #ifdef CONFIG_CONCURRENT_MODE
2014 if (rtw_mi_buddy_check_fwstate(padapter,
2015 WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) {
2016
2017 indicate_wx_scan_complete_event(padapter);
2018 goto cancel_ps_deny;
2019 }
2020 #endif
2021 #endif
2022
2023 #ifdef CONFIG_P2P
2024 if (pwdinfo->p2p_state != P2P_STATE_NONE) {
2025 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2026 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2027 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2028 rtw_free_network_queue(padapter, _TRUE);
2029 }
2030 #endif /* CONFIG_P2P */
2031
2032 #if WIRELESS_EXT >= 17
2033 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
2034 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2035
2036 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2037 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2038
2039 rtw_init_sitesurvey_parm(padapter, &parm);
2040 _rtw_memcpy(&parm.ssid[0].Ssid, &req->essid, len);
2041 parm.ssid[0].SsidLength = len;
2042 parm.ssid_num = 1;
2043
2044 RTW_INFO("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2045
2046 _status = rtw_set_802_11_bssid_list_scan(padapter, &parm);
2047
2048 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2049 RTW_INFO("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2050
2051 } else
2052 #endif
2053
2054 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2055 && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2056 ) {
2057 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
2058 char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
2059 char section;
2060 char sec_len;
2061 int ssid_index = 0;
2062
2063 /* RTW_INFO("%s COMBO_SCAN header is recognized\n", __FUNCTION__); */
2064 rtw_init_sitesurvey_parm(padapter, &parm);
2065
2066 while (len >= 1) {
2067 section = *(pos++);
2068 len -= 1;
2069
2070 switch (section) {
2071 case WEXT_CSCAN_SSID_SECTION:
2072 /* RTW_INFO("WEXT_CSCAN_SSID_SECTION\n"); */
2073 if (len < 1) {
2074 len = 0;
2075 break;
2076 }
2077
2078 sec_len = *(pos++);
2079 len -= 1;
2080
2081 if (sec_len > 0 && sec_len <= len) {
2082
2083 parm.ssid[ssid_index].SsidLength = sec_len;
2084 _rtw_memcpy(&parm.ssid[ssid_index].Ssid, pos, sec_len);
2085
2086 /* RTW_INFO("%s COMBO_SCAN with specific parm.ssid:%s, %d\n", __FUNCTION__ */
2087 /* , parm.ssid[ssid_index].Ssid, parm.ssid[ssid_index].SsidLength); */
2088 ssid_index++;
2089 }
2090
2091 pos += sec_len;
2092 len -= sec_len;
2093 break;
2094
2095
2096 case WEXT_CSCAN_CHANNEL_SECTION:
2097 /* RTW_INFO("WEXT_CSCAN_CHANNEL_SECTION\n"); */
2098 pos += 1;
2099 len -= 1;
2100 break;
2101 case WEXT_CSCAN_ACTV_DWELL_SECTION:
2102 /* RTW_INFO("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); */
2103 pos += 2;
2104 len -= 2;
2105 break;
2106 case WEXT_CSCAN_PASV_DWELL_SECTION:
2107 /* RTW_INFO("WEXT_CSCAN_PASV_DWELL_SECTION\n"); */
2108 pos += 2;
2109 len -= 2;
2110 break;
2111 case WEXT_CSCAN_HOME_DWELL_SECTION:
2112 /* RTW_INFO("WEXT_CSCAN_HOME_DWELL_SECTION\n"); */
2113 pos += 2;
2114 len -= 2;
2115 break;
2116 case WEXT_CSCAN_TYPE_SECTION:
2117 /* RTW_INFO("WEXT_CSCAN_TYPE_SECTION\n"); */
2118 pos += 1;
2119 len -= 1;
2120 break;
2121 #if 0
2122 case WEXT_CSCAN_NPROBE_SECTION:
2123 RTW_INFO("WEXT_CSCAN_NPROBE_SECTION\n");
2124 break;
2125 #endif
2126
2127 default:
2128 /* RTW_INFO("Unknown CSCAN section %c\n", section); */
2129 len = 0; /* stop parsing */
2130 }
2131 /* RTW_INFO("len:%d\n", len); */
2132
2133 }
2134 parm.ssid_num = ssid_index;
2135
2136 /* jeff: it has still some scan paramater to parse, we only do this now... */
2137 _status = rtw_set_802_11_bssid_list_scan(padapter, &parm);
2138
2139 } else
2140
2141 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL);
2142
2143 if (_status == _FALSE)
2144 ret = -1;
2145
2146 cancel_ps_deny:
2147 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2148
2149 exit:
2150 #ifdef DBG_IOCTL
2151 RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2152 #endif
2153
2154 return ret;
2155 }
2156
rtw_wx_get_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)2157 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2158 union iwreq_data *wrqu, char *extra)
2159 {
2160 _irqL irqL;
2161 _list *plist, *phead;
2162 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2163 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2164 RT_CHANNEL_INFO *chset = rfctl->channel_set;
2165 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2166 _queue *queue = &(pmlmepriv->scanned_queue);
2167 struct wlan_network *pnetwork = NULL;
2168 char *ev = extra;
2169 char *stop = ev + wrqu->data.length;
2170 u32 ret = 0;
2171 u32 wait_for_surveydone;
2172 sint wait_status;
2173 u8 ch;
2174
2175 #ifdef CONFIG_P2P
2176 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2177 #endif /* CONFIG_P2P */
2178
2179
2180 #ifdef DBG_IOCTL
2181 RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2182 #endif
2183
2184 if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) {
2185 ret = -EINVAL;
2186 goto exit;
2187 }
2188
2189 #ifdef CONFIG_P2P
2190 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2191 wait_for_surveydone = 200;
2192 else {
2193 /* P2P is disabled */
2194 wait_for_surveydone = 100;
2195 }
2196 #else
2197 {
2198 wait_for_surveydone = 100;
2199 }
2200 #endif /* CONFIG_P2P */
2201
2202 #if 1 /* Wireless Extension use EAGAIN to try */
2203 wait_status = WIFI_UNDER_SURVEY
2204 #ifndef CONFIG_RTW_ANDROID
2205 | WIFI_UNDER_LINKING
2206 #endif
2207 ;
2208
2209 while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2210 return -EAGAIN;
2211 #else
2212 wait_status = WIFI_UNDER_SURVEY
2213 #ifndef CONFIG_RTW_ANDROID
2214 | WIFI_UNDER_LINKING
2215 #endif
2216 ;
2217
2218 while (check_fwstate(pmlmepriv, wait_status) == _TRUE) {
2219 rtw_msleep_os(30);
2220 cnt++;
2221 if (cnt > wait_for_surveydone)
2222 break;
2223 }
2224 #endif
2225 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2226
2227 phead = get_list_head(queue);
2228 plist = get_next(phead);
2229
2230 while (1) {
2231 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
2232 break;
2233
2234 if ((stop - ev) < SCAN_ITEM_SIZE) {
2235 if(wrqu->data.length == MAX_SCAN_BUFFER_LEN){ /*max buffer len defined by iwlist*/
2236 ret = 0;
2237 RTW_INFO("%s: Scan results incomplete\n", __FUNCTION__);
2238 break;
2239 }
2240 ret = -E2BIG;
2241 break;
2242 }
2243
2244 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2245 ch = pnetwork->network.Configuration.DSConfig;
2246
2247 /* report network only if the current channel set contains the channel to which this network belongs */
2248 if (rtw_chset_search_ch(chset, ch) >= 0
2249 && rtw_mlme_band_check(padapter, ch) == _TRUE
2250 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2251 && (!IS_DFS_SLAVE_WITH_RD(rfctl)
2252 || rtw_rfctl_dfs_domain_unknown(rfctl)
2253 || !rtw_chset_is_ch_non_ocp(chset, ch))
2254 )
2255 ev = translate_scan(padapter, a, pnetwork, ev, stop);
2256
2257 plist = get_next(plist);
2258
2259 }
2260
2261 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2262
2263 wrqu->data.length = ev - extra;
2264 wrqu->data.flags = 0;
2265
2266 exit:
2267
2268
2269 #ifdef DBG_IOCTL
2270 RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2271 #endif
2272
2273 return ret ;
2274
2275 }
2276
2277 /* set ssid flow
2278 * s1. rtw_set_802_11_infrastructure_mode()
2279 * s2. set_802_11_authenticaion_mode()
2280 * s3. set_802_11_encryption_mode()
2281 * s4. rtw_set_802_11_ssid() */
rtw_wx_set_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)2282 static int rtw_wx_set_essid(struct net_device *dev,
2283 struct iw_request_info *a,
2284 union iwreq_data *wrqu, char *extra)
2285 {
2286 _irqL irqL;
2287 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2288 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2289 _queue *queue = &pmlmepriv->scanned_queue;
2290 _list *phead;
2291 struct wlan_network *pnetwork = NULL;
2292 NDIS_802_11_AUTHENTICATION_MODE authmode;
2293 NDIS_802_11_SSID ndis_ssid;
2294 u8 *dst_ssid, *src_ssid;
2295
2296 uint ret = 0, len;
2297
2298
2299 #ifdef DBG_IOCTL
2300 RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2301 #endif
2302 #ifdef CONFIG_WEXT_DONT_JOIN_BYSSID
2303 RTW_INFO("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);
2304 return -EPERM;
2305 #endif
2306
2307 #if WIRELESS_EXT <= 20
2308 if ((wrqu->essid.length - 1) > IW_ESSID_MAX_SIZE) {
2309 #else
2310 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
2311 #endif
2312 ret = -E2BIG;
2313 goto exit;
2314 }
2315
2316
2317
2318 rtw_ps_deny(padapter, PS_DENY_JOIN);
2319 if (_FAIL == rtw_pwr_wakeup(padapter)) {
2320 ret = -1;
2321 goto cancel_ps_deny;
2322 }
2323
2324 if (!padapter->bup) {
2325 ret = -1;
2326 goto cancel_ps_deny;
2327 }
2328
2329 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2330 ret = -1;
2331 goto cancel_ps_deny;
2332 }
2333
2334 #ifdef CONFIG_CONCURRENT_MODE
2335 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING)) {
2336 RTW_INFO("set ssid, but buddy_intf is under scanning or linking\n");
2337 ret = -EINVAL;
2338 goto cancel_ps_deny;
2339 }
2340 #endif
2341 authmode = padapter->securitypriv.ndisauthtype;
2342 RTW_INFO("=>%s\n", __FUNCTION__);
2343 if (wrqu->essid.flags && wrqu->essid.length) {
2344 /* Commented by Albert 20100519 */
2345 /* We got the codes in "set_info" function of iwconfig source code. */
2346 /* ========================================= */
2347 /* wrq.u.essid.length = strlen(essid) + 1; */
2348 /* if(we_kernel_version > 20) */
2349 /* wrq.u.essid.length--; */
2350 /* ========================================= */
2351 /* That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. */
2352 #if WIRELESS_EXT <= 20
2353 len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE;
2354 #else
2355 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2356 #endif
2357
2358 if (wrqu->essid.length != 33)
2359 RTW_INFO("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2360
2361 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2362 ndis_ssid.SsidLength = len;
2363 _rtw_memcpy(ndis_ssid.Ssid, extra, len);
2364 src_ssid = ndis_ssid.Ssid;
2365
2366 _enter_critical_bh(&queue->lock, &irqL);
2367 phead = get_list_head(queue);
2368 pmlmepriv->pscanned = get_next(phead);
2369
2370 while (1) {
2371 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) {
2372 #if 0
2373 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2374 rtw_set_802_11_ssid(padapter, &ndis_ssid);
2375
2376 goto cancel_ps_deny;
2377 } else {
2378 ret = -EINVAL;
2379 goto cancel_ps_deny;
2380 }
2381 #endif
2382
2383 break;
2384 }
2385
2386 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2387
2388 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2389
2390 dst_ssid = pnetwork->network.Ssid.Ssid;
2391
2392
2393 if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2394 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
2395
2396 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2397 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2398 continue;
2399 }
2400
2401 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0) == _FALSE) {
2402 ret = -1;
2403 _exit_critical_bh(&queue->lock, &irqL);
2404 goto cancel_ps_deny;
2405 }
2406
2407 break;
2408 }
2409 }
2410 _exit_critical_bh(&queue->lock, &irqL);
2411 rtw_set_802_11_authentication_mode(padapter, authmode);
2412 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
2413 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2414 ret = -1;
2415 goto cancel_ps_deny;
2416 }
2417 }
2418
2419 cancel_ps_deny:
2420 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2421
2422 exit:
2423 RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
2424
2425 #ifdef DBG_IOCTL
2426 RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2427 #endif
2428
2429
2430 return ret;
2431 }
2432
2433 static int rtw_wx_get_essid(struct net_device *dev,
2434 struct iw_request_info *a,
2435 union iwreq_data *wrqu, char *extra)
2436 {
2437 u32 len, ret = 0;
2438 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2439 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2440 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2441
2442
2443
2444 if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) ||
2445 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
2446 len = pcur_bss->Ssid.SsidLength;
2447
2448 wrqu->essid.length = len;
2449
2450 _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2451
2452 wrqu->essid.flags = 1;
2453 } else {
2454 ret = -1;
2455 goto exit;
2456 }
2457
2458 exit:
2459
2460
2461 return ret;
2462
2463 }
2464
2465 static int rtw_wx_set_rate(struct net_device *dev,
2466 struct iw_request_info *a,
2467 union iwreq_data *wrqu, char *extra)
2468 {
2469 int ret = 0;
2470 #if 0
2471 int i;
2472 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2473 u8 datarates[NumRates];
2474 u32 target_rate = wrqu->bitrate.value;
2475 u32 fixed = wrqu->bitrate.fixed;
2476 u32 ratevalue = 0;
2477 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2478
2479
2480
2481 if (target_rate == -1) {
2482 ratevalue = 11;
2483 goto set_rate;
2484 }
2485 target_rate = target_rate / 100000;
2486
2487 switch (target_rate) {
2488 case 10:
2489 ratevalue = 0;
2490 break;
2491 case 20:
2492 ratevalue = 1;
2493 break;
2494 case 55:
2495 ratevalue = 2;
2496 break;
2497 case 60:
2498 ratevalue = 3;
2499 break;
2500 case 90:
2501 ratevalue = 4;
2502 break;
2503 case 110:
2504 ratevalue = 5;
2505 break;
2506 case 120:
2507 ratevalue = 6;
2508 break;
2509 case 180:
2510 ratevalue = 7;
2511 break;
2512 case 240:
2513 ratevalue = 8;
2514 break;
2515 case 360:
2516 ratevalue = 9;
2517 break;
2518 case 480:
2519 ratevalue = 10;
2520 break;
2521 case 540:
2522 ratevalue = 11;
2523 break;
2524 default:
2525 ratevalue = 11;
2526 break;
2527 }
2528
2529 set_rate:
2530
2531 for (i = 0; i < NumRates; i++) {
2532 if (ratevalue == mpdatarate[i]) {
2533 datarates[i] = mpdatarate[i];
2534 if (fixed == 0)
2535 break;
2536 } else
2537 datarates[i] = 0xff;
2538
2539 }
2540
2541 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
2542 ret = -1;
2543 }
2544
2545 #endif
2546 return ret;
2547 }
2548
2549 static int rtw_wx_get_rate(struct net_device *dev,
2550 struct iw_request_info *info,
2551 union iwreq_data *wrqu, char *extra)
2552 {
2553 u16 max_rate = 0;
2554
2555 max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
2556
2557 if (max_rate == 0)
2558 return -EPERM;
2559
2560 wrqu->bitrate.fixed = 0; /* no auto select */
2561 wrqu->bitrate.value = max_rate * 100000;
2562
2563 return 0;
2564 }
2565
2566 static int rtw_wx_set_rts(struct net_device *dev,
2567 struct iw_request_info *info,
2568 union iwreq_data *wrqu, char *extra)
2569 {
2570 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2571
2572
2573 if (wrqu->rts.disabled)
2574 padapter->registrypriv.rts_thresh = 2347;
2575 else {
2576 if (wrqu->rts.value < 0 ||
2577 wrqu->rts.value > 2347)
2578 return -EINVAL;
2579
2580 padapter->registrypriv.rts_thresh = wrqu->rts.value;
2581 }
2582
2583 RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2584
2585
2586 return 0;
2587
2588 }
2589
2590 static int rtw_wx_get_rts(struct net_device *dev,
2591 struct iw_request_info *info,
2592 union iwreq_data *wrqu, char *extra)
2593 {
2594 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2595
2596
2597 RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2598
2599 wrqu->rts.value = padapter->registrypriv.rts_thresh;
2600 wrqu->rts.fixed = 0; /* no auto select */
2601 /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
2602
2603
2604 return 0;
2605 }
2606
2607 static int rtw_wx_set_frag(struct net_device *dev,
2608 struct iw_request_info *info,
2609 union iwreq_data *wrqu, char *extra)
2610 {
2611 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2612
2613
2614 if (wrqu->frag.disabled)
2615 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
2616 else {
2617 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
2618 wrqu->frag.value > MAX_FRAG_THRESHOLD)
2619 return -EINVAL;
2620
2621 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
2622 }
2623
2624 RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2625
2626
2627 return 0;
2628
2629 }
2630
2631 static int rtw_wx_get_frag(struct net_device *dev,
2632 struct iw_request_info *info,
2633 union iwreq_data *wrqu, char *extra)
2634 {
2635 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2636
2637
2638 RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2639
2640 wrqu->frag.value = padapter->xmitpriv.frag_len;
2641 wrqu->frag.fixed = 0; /* no auto select */
2642 /* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */
2643
2644
2645 return 0;
2646 }
2647
2648 static int rtw_wx_get_retry(struct net_device *dev,
2649 struct iw_request_info *info,
2650 union iwreq_data *wrqu, char *extra)
2651 {
2652 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
2653
2654
2655 wrqu->retry.value = 7;
2656 wrqu->retry.fixed = 0; /* no auto select */
2657 wrqu->retry.disabled = 1;
2658
2659 return 0;
2660
2661 }
2662
2663 #if 0
2664 #define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
2665 #define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
2666 #define IW_ENCODE_MODE 0xF000 /* Modes defined below */
2667 #define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
2668 #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
2669 #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
2670 #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
2671 #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
2672 #define IW_ENCODE_TEMP 0x0400 /* Temporary key */
2673 /*
2674 iwconfig wlan0 key on->flags = 0x6001->maybe it means auto
2675 iwconfig wlan0 key off->flags = 0x8800
2676 iwconfig wlan0 key open->flags = 0x2800
2677 iwconfig wlan0 key open 1234567890->flags = 0x2000
2678 iwconfig wlan0 key restricted->flags = 0x4800
2679 iwconfig wlan0 key open [3] 1234567890->flags = 0x2003
2680 iwconfig wlan0 key restricted [2] 1234567890->flags = 0x4002
2681 iwconfig wlan0 key open [3] -> flags = 0x2803
2682 iwconfig wlan0 key restricted [2] -> flags = 0x4802
2683 */
2684 #endif
2685
2686 static int rtw_wx_set_enc(struct net_device *dev,
2687 struct iw_request_info *info,
2688 union iwreq_data *wrqu, char *keybuf)
2689 {
2690 u32 key, ret = 0;
2691 u32 keyindex_provided;
2692 NDIS_802_11_WEP wep;
2693 NDIS_802_11_AUTHENTICATION_MODE authmode;
2694
2695 struct iw_point *erq = &(wrqu->encoding);
2696 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2697 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2698 RTW_INFO("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
2699
2700 _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
2701
2702 key = erq->flags & IW_ENCODE_INDEX;
2703
2704
2705 if (erq->flags & IW_ENCODE_DISABLED) {
2706 RTW_INFO("EncryptionDisabled\n");
2707 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2708 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2709 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2710 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2711 authmode = Ndis802_11AuthModeOpen;
2712 padapter->securitypriv.ndisauthtype = authmode;
2713
2714 goto exit;
2715 }
2716
2717 if (key) {
2718 if (key > WEP_KEYS)
2719 return -EINVAL;
2720 key--;
2721 keyindex_provided = 1;
2722 } else {
2723 keyindex_provided = 0;
2724 key = padapter->securitypriv.dot11PrivacyKeyIndex;
2725 RTW_INFO("rtw_wx_set_enc, key=%d\n", key);
2726 }
2727
2728 /* set authentication mode */
2729 if (erq->flags & IW_ENCODE_OPEN) {
2730 RTW_INFO("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
2731 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
2732
2733 #ifdef CONFIG_PLATFORM_MT53XX
2734 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2735 #else
2736 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2737 #endif
2738
2739 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2740 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2741 authmode = Ndis802_11AuthModeOpen;
2742 padapter->securitypriv.ndisauthtype = authmode;
2743 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
2744 RTW_INFO("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
2745 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2746
2747 #ifdef CONFIG_PLATFORM_MT53XX
2748 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2749 #else
2750 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2751 #endif
2752
2753 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2754 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
2755 authmode = Ndis802_11AuthModeShared;
2756 padapter->securitypriv.ndisauthtype = authmode;
2757 } else {
2758 RTW_INFO("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
2759
2760 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
2761 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2762 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2763 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2764 authmode = Ndis802_11AuthModeOpen;
2765 padapter->securitypriv.ndisauthtype = authmode;
2766 }
2767
2768 wep.KeyIndex = key;
2769 if (erq->length > 0) {
2770 wep.KeyLength = erq->length <= 5 ? 5 : 13;
2771
2772 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2773 } else {
2774 wep.KeyLength = 0 ;
2775
2776 if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length==0). */
2777 padapter->securitypriv.dot11PrivacyKeyIndex = key;
2778
2779 RTW_INFO("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
2780
2781 switch (padapter->securitypriv.dot11DefKeylen[key]) {
2782 case 5:
2783 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2784 break;
2785 case 13:
2786 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2787 break;
2788 default:
2789 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2790 break;
2791 }
2792
2793 goto exit;
2794
2795 }
2796
2797 }
2798
2799 wep.KeyIndex |= 0x80000000;
2800
2801 _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
2802
2803 if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
2804 if (rf_on == pwrpriv->rf_pwrstate)
2805 ret = -EOPNOTSUPP;
2806 goto exit;
2807 }
2808
2809 exit:
2810
2811
2812 return ret;
2813
2814 }
2815
2816 static int rtw_wx_get_enc(struct net_device *dev,
2817 struct iw_request_info *info,
2818 union iwreq_data *wrqu, char *keybuf)
2819 {
2820 uint key, ret = 0;
2821 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2822 struct iw_point *erq = &(wrqu->encoding);
2823 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2824
2825
2826 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) != _TRUE) {
2827 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) {
2828 erq->length = 0;
2829 erq->flags |= IW_ENCODE_DISABLED;
2830 return 0;
2831 }
2832 }
2833
2834
2835 key = erq->flags & IW_ENCODE_INDEX;
2836
2837 if (key) {
2838 if (key > WEP_KEYS)
2839 return -EINVAL;
2840 key--;
2841 } else
2842 key = padapter->securitypriv.dot11PrivacyKeyIndex;
2843
2844 erq->flags = key + 1;
2845
2846 /* if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */
2847 /* { */
2848 /* erq->flags |= IW_ENCODE_OPEN; */
2849 /* } */
2850
2851 switch (padapter->securitypriv.ndisencryptstatus) {
2852 case Ndis802_11EncryptionNotSupported:
2853 case Ndis802_11EncryptionDisabled:
2854
2855 erq->length = 0;
2856 erq->flags |= IW_ENCODE_DISABLED;
2857
2858 break;
2859
2860 case Ndis802_11Encryption1Enabled:
2861
2862 erq->length = padapter->securitypriv.dot11DefKeylen[key];
2863
2864 if (erq->length) {
2865 _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
2866
2867 erq->flags |= IW_ENCODE_ENABLED;
2868
2869 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2870 erq->flags |= IW_ENCODE_OPEN;
2871 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
2872 erq->flags |= IW_ENCODE_RESTRICTED;
2873 } else {
2874 erq->length = 0;
2875 erq->flags |= IW_ENCODE_DISABLED;
2876 }
2877
2878 break;
2879
2880 case Ndis802_11Encryption2Enabled:
2881 case Ndis802_11Encryption3Enabled:
2882
2883 erq->length = 16;
2884 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
2885
2886 break;
2887
2888 default:
2889 erq->length = 0;
2890 erq->flags |= IW_ENCODE_DISABLED;
2891
2892 break;
2893
2894 }
2895
2896
2897 return ret;
2898
2899 }
2900
2901 static int rtw_wx_get_power(struct net_device *dev,
2902 struct iw_request_info *info,
2903 union iwreq_data *wrqu, char *extra)
2904 {
2905 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
2906
2907 wrqu->power.value = 0;
2908 wrqu->power.fixed = 0; /* no auto select */
2909 wrqu->power.disabled = 1;
2910
2911 return 0;
2912
2913 }
2914
2915 static int rtw_wx_set_gen_ie(struct net_device *dev,
2916 struct iw_request_info *info,
2917 union iwreq_data *wrqu, char *extra)
2918 {
2919 int ret;
2920 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2921
2922 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
2923
2924 return ret;
2925 }
2926
2927 static int rtw_wx_set_auth(struct net_device *dev,
2928 struct iw_request_info *info,
2929 union iwreq_data *wrqu, char *extra)
2930 {
2931 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2932 struct iw_param *param = (struct iw_param *)&(wrqu->param);
2933 #ifdef CONFIG_WAPI_SUPPORT
2934 #ifndef CONFIG_IOCTL_CFG80211
2935 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2936 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2937 struct security_priv *psecuritypriv = &padapter->securitypriv;
2938 u32 value = param->value;
2939 #endif
2940 #endif
2941 int ret = 0;
2942
2943 switch (param->flags & IW_AUTH_INDEX) {
2944
2945 case IW_AUTH_WPA_VERSION:
2946 #ifdef CONFIG_WAPI_SUPPORT
2947 #ifndef CONFIG_IOCTL_CFG80211
2948 padapter->wapiInfo.bWapiEnable = false;
2949 if (value == IW_AUTH_WAPI_VERSION_1) {
2950 padapter->wapiInfo.bWapiEnable = true;
2951 psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
2952 psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
2953 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2954 pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
2955 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
2956 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
2957 }
2958 #endif
2959 #endif
2960 break;
2961 case IW_AUTH_CIPHER_PAIRWISE:
2962
2963 break;
2964 case IW_AUTH_CIPHER_GROUP:
2965
2966 break;
2967 case IW_AUTH_KEY_MGMT:
2968 #ifdef CONFIG_WAPI_SUPPORT
2969 #ifndef CONFIG_IOCTL_CFG80211
2970 RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case\n");
2971 if (value == IW_AUTH_KEY_MGMT_WAPI_PSK)
2972 padapter->wapiInfo.bWapiPSK = true;
2973 else
2974 padapter->wapiInfo.bWapiPSK = false;
2975 RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d\n", padapter->wapiInfo.bWapiPSK);
2976 #endif
2977 #endif
2978 /*
2979 * ??? does not use these parameters
2980 */
2981 break;
2982
2983 case IW_AUTH_TKIP_COUNTERMEASURES: {
2984 if (param->value) {
2985 /* wpa_supplicant is enabling the tkip countermeasure. */
2986 padapter->securitypriv.btkip_countermeasure = _TRUE;
2987 } else {
2988 /* wpa_supplicant is disabling the tkip countermeasure. */
2989 padapter->securitypriv.btkip_countermeasure = _FALSE;
2990 }
2991 break;
2992 }
2993 case IW_AUTH_DROP_UNENCRYPTED: {
2994 /* HACK:
2995 *
2996 * wpa_supplicant calls set_wpa_enabled when the driver
2997 * is loaded and unloaded, regardless of if WPA is being
2998 * used. No other calls are made which can be used to
2999 * determine if encryption will be used or not prior to
3000 * association being expected. If encryption is not being
3001 * used, drop_unencrypted is set to false, else true -- we
3002 * can use this to determine if the CAP_PRIVACY_ON bit should
3003 * be set.
3004 */
3005
3006 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) {
3007 break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
3008 /* then it needn't reset it; */
3009 }
3010
3011 if (param->value) {
3012 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3013 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3014 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3015 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3016 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
3017 }
3018
3019 break;
3020 }
3021
3022 case IW_AUTH_80211_AUTH_ALG:
3023
3024 #if defined(CONFIG_RTW_ANDROID) || 1
3025 /*
3026 * It's the starting point of a link layer connection using wpa_supplicant
3027 */
3028 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
3029 LeaveAllPowerSaveMode(padapter);
3030 rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK);
3031 RTW_INFO("%s...call rtw_indicate_disconnect\n ", __FUNCTION__);
3032 rtw_indicate_disconnect(padapter, 0, _FALSE);
3033 rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK);
3034 }
3035 #endif
3036
3037
3038 ret = wpa_set_auth_algs(dev, (u32)param->value);
3039
3040 break;
3041
3042 case IW_AUTH_WPA_ENABLED:
3043
3044 /* if(param->value) */
3045 /* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; */ /* 802.1x */
3046 /* else */
3047 /* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; */ /* open system */
3048
3049 /* _disassociate(priv); */
3050
3051 break;
3052
3053 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3054 /* ieee->ieee802_1x = param->value; */
3055 break;
3056
3057 case IW_AUTH_PRIVACY_INVOKED:
3058 /* ieee->privacy_invoked = param->value; */
3059 break;
3060
3061 #ifdef CONFIG_WAPI_SUPPORT
3062 #ifndef CONFIG_IOCTL_CFG80211
3063 case IW_AUTH_WAPI_ENABLED:
3064 break;
3065 #endif
3066 #endif
3067
3068 default:
3069 return -EOPNOTSUPP;
3070
3071 }
3072
3073 return ret;
3074
3075 }
3076
3077 static int rtw_wx_set_enc_ext(struct net_device *dev,
3078 struct iw_request_info *info,
3079 union iwreq_data *wrqu, char *extra)
3080 {
3081 char *alg_name;
3082 u32 param_len;
3083 struct ieee_param *param = NULL;
3084 struct iw_point *pencoding = &wrqu->encoding;
3085 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3086 int ret = 0;
3087
3088 param_len = sizeof(struct ieee_param) + pext->key_len;
3089 param = (struct ieee_param *)rtw_malloc(param_len);
3090 if (param == NULL)
3091 return -1;
3092
3093 _rtw_memset(param, 0, param_len);
3094
3095 param->cmd = IEEE_CMD_SET_ENCRYPTION;
3096 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3097
3098
3099 switch (pext->alg) {
3100 case IW_ENCODE_ALG_NONE:
3101 /* todo: remove key */
3102 /* remove = 1; */
3103 alg_name = "none";
3104 break;
3105 case IW_ENCODE_ALG_WEP:
3106 alg_name = "WEP";
3107 break;
3108 case IW_ENCODE_ALG_TKIP:
3109 alg_name = "TKIP";
3110 break;
3111 case IW_ENCODE_ALG_CCMP:
3112 alg_name = "CCMP";
3113 break;
3114 #ifdef CONFIG_IEEE80211W
3115 case IW_ENCODE_ALG_AES_CMAC:
3116 alg_name = "BIP";
3117 break;
3118 #endif /* CONFIG_IEEE80211W */
3119 #ifdef CONFIG_WAPI_SUPPORT
3120 #ifndef CONFIG_IOCTL_CFG80211
3121 case IW_ENCODE_ALG_SM4:
3122 alg_name = "SMS4";
3123 _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3124 RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
3125 break;
3126 #endif
3127 #endif
3128 default:
3129 ret = -1;
3130 goto exit;
3131 }
3132
3133 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3134
3135 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3136 param->u.crypt.set_tx = 1;
3137
3138 /* cliW: WEP does not have group key
3139 * just not checking GROUP key setting
3140 */
3141 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3142 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3143 #ifdef CONFIG_IEEE80211W
3144 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3145 #endif /* CONFIG_IEEE80211W */
3146 ))
3147 param->u.crypt.set_tx = 0;
3148
3149 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1 ;
3150
3151 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3152 #ifdef CONFIG_WAPI_SUPPORT
3153 #ifndef CONFIG_IOCTL_CFG80211
3154 if (pext->alg == IW_ENCODE_ALG_SM4)
3155 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3156 else
3157 #endif /* CONFIG_IOCTL_CFG80211 */
3158 #endif /* CONFIG_WAPI_SUPPORT */
3159 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3160 }
3161
3162 if (pext->key_len) {
3163 param->u.crypt.key_len = pext->key_len;
3164 /* _rtw_memcpy(param + 1, pext + 1, pext->key_len); */
3165 _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3166 }
3167
3168 if (pencoding->flags & IW_ENCODE_DISABLED) {
3169 /* todo: remove key */
3170 /* remove = 1; */
3171 }
3172
3173 ret = wpa_set_encryption(dev, param, param_len);
3174
3175 exit:
3176 if (param)
3177 rtw_mfree((u8 *)param, param_len);
3178
3179 return ret;
3180 }
3181
3182
3183 static int rtw_wx_get_nick(struct net_device *dev,
3184 struct iw_request_info *info,
3185 union iwreq_data *wrqu, char *extra)
3186 {
3187 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3188 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3189 /* struct security_priv *psecuritypriv = &padapter->securitypriv; */
3190
3191 if (extra) {
3192 wrqu->data.length = 14;
3193 wrqu->data.flags = 1;
3194 _rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
3195 }
3196
3197 /* rtw_signal_process(pid, SIGUSR1); */ /* for test */
3198
3199 /* dump debug info here */
3200 #if 0
3201 u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, shared, and 8021x */
3202 u32 dot11PrivacyAlgrthm; /* This specify the privacy for shared auth. algorithm. */
3203 u32 dot118021XGrpPrivacy; /* This specify the privacy algthm. used for Grp key */
3204 u32 ndisauthtype;
3205 u32 ndisencryptstatus;
3206 #endif
3207
3208 /* RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", */
3209 /* psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, */
3210 /* psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); */
3211
3212 /* RTW_INFO("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); */
3213 /* RTW_INFO("auth_type=0x%x\n", psecuritypriv->ndisauthtype); */
3214 /* RTW_INFO("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); */
3215
3216 #if 0
3217 RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3218 RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3219 RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3220 RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3221 RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3222
3223 RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3224
3225
3226 RTW_INFO("\n");
3227
3228 RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3229 RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3230
3231 RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3232
3233 RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3234
3235 RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3236 RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3237
3238 RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3239 RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3240 RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3241 RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3242 #endif
3243
3244 return 0;
3245
3246 }
3247 #endif
3248
3249 static int rtw_wx_read32(struct net_device *dev,
3250 struct iw_request_info *info,
3251 union iwreq_data *wrqu, char *extra)
3252 {
3253 PADAPTER padapter;
3254 struct iw_point *p;
3255 u16 len;
3256 u32 addr;
3257 u32 data32;
3258 u32 bytes;
3259 u8 *ptmp;
3260 int ret;
3261
3262
3263 ret = 0;
3264 padapter = (PADAPTER)rtw_netdev_priv(dev);
3265 p = &wrqu->data;
3266 len = p->length;
3267 if (0 == len)
3268 return -EINVAL;
3269
3270 ptmp = (u8 *)rtw_malloc(len);
3271 if (NULL == ptmp)
3272 return -ENOMEM;
3273
3274 if (copy_from_user(ptmp, p->pointer, len)) {
3275 ret = -EFAULT;
3276 goto exit;
3277 }
3278
3279 bytes = 0;
3280 addr = 0;
3281 sscanf(ptmp, "%d,%x", &bytes, &addr);
3282
3283 switch (bytes) {
3284 case 1:
3285 data32 = rtw_read8(padapter, addr);
3286 sprintf(extra, "0x%02X", data32);
3287 break;
3288 case 2:
3289 data32 = rtw_read16(padapter, addr);
3290 sprintf(extra, "0x%04X", data32);
3291 break;
3292 case 4:
3293 data32 = rtw_read32(padapter, addr);
3294 sprintf(extra, "0x%08X", data32);
3295 break;
3296
3297 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)
3298 case 11:
3299 data32 = rtw_sd_iread8(padapter, addr);
3300 sprintf(extra, "0x%02X", data32);
3301 break;
3302 case 12:
3303 data32 = rtw_sd_iread16(padapter, addr);
3304 sprintf(extra, "0x%04X", data32);
3305 break;
3306 case 14:
3307 data32 = rtw_sd_iread32(padapter, addr);
3308 sprintf(extra, "0x%08X", data32);
3309 break;
3310 #endif
3311 default:
3312 RTW_INFO("%s: usage> read [bytes],[address(hex)]\n", __func__);
3313 ret = -EINVAL;
3314 goto exit;
3315 }
3316 RTW_INFO("%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3317
3318 exit:
3319 rtw_mfree(ptmp, len);
3320
3321 return 0;
3322 }
3323
3324 static int rtw_wx_write32(struct net_device *dev,
3325 struct iw_request_info *info,
3326 union iwreq_data *wrqu, char *extra)
3327 {
3328 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3329
3330 u32 addr;
3331 u32 data32;
3332 u32 bytes;
3333
3334
3335 bytes = 0;
3336 addr = 0;
3337 data32 = 0;
3338 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3339
3340 switch (bytes) {
3341 case 1:
3342 rtw_write8(padapter, addr, (u8)data32);
3343 RTW_INFO("%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3344 break;
3345 case 2:
3346 rtw_write16(padapter, addr, (u16)data32);
3347 RTW_INFO("%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3348 break;
3349 case 4:
3350 rtw_write32(padapter, addr, data32);
3351 RTW_INFO("%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3352 break;
3353 default:
3354 RTW_INFO("%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3355 return -EINVAL;
3356 }
3357
3358 return 0;
3359 }
3360
3361 static int rtw_wx_read_rf(struct net_device *dev,
3362 struct iw_request_info *info,
3363 union iwreq_data *wrqu, char *extra)
3364 {
3365 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3366 u32 path, addr, data32;
3367
3368
3369 path = *(u32 *)extra;
3370 addr = *((u32 *)extra + 1);
3371 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3372 /* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3373 /*
3374 * IMPORTANT!!
3375 * Only when wireless private ioctl is at odd order,
3376 * "extra" would be copied to user space.
3377 */
3378 sprintf(extra, "0x%05x", data32);
3379
3380 return 0;
3381 }
3382
3383 static int rtw_wx_write_rf(struct net_device *dev,
3384 struct iw_request_info *info,
3385 union iwreq_data *wrqu, char *extra)
3386 {
3387 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3388 u32 path, addr, data32;
3389
3390
3391 path = *(u32 *)extra;
3392 addr = *((u32 *)extra + 1);
3393 data32 = *((u32 *)extra + 2);
3394 /* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3395 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3396
3397 return 0;
3398 }
3399
3400 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3401 union iwreq_data *wrqu, char *b)
3402 {
3403 return -1;
3404 }
3405
3406 #ifdef CONFIG_RTW_80211K
3407 extern void rm_dbg_cmd(_adapter *padapter, char *s);
3408 static int rtw_wx_priv_rrm(struct net_device *dev, struct iw_request_info *a,
3409 union iwreq_data *wrqu, char *b)
3410 {
3411 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3412 u32 path, addr, data32;
3413
3414
3415 rm_dbg_cmd(padapter, b);
3416 wrqu->data.length = strlen(b);
3417
3418 return 0;
3419 }
3420 #endif
3421
3422 #ifdef CONFIG_IOCTL_WEXT
3423 static int dummy(struct net_device *dev, struct iw_request_info *a,
3424 union iwreq_data *wrqu, char *b)
3425 {
3426 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3427 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3428
3429 /* RTW_INFO("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); */
3430
3431 return -1;
3432
3433 }
3434 #endif
3435
3436 static int rtw_wx_set_channel_plan(struct net_device *dev,
3437 struct iw_request_info *info,
3438 union iwreq_data *wrqu, char *extra)
3439 {
3440 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3441 u16 channel_plan_req = (u16)(*((int *)wrqu));
3442
3443 rtw_chplan_ioctl_input_mapping(&channel_plan_req, NULL);
3444
3445 if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req, RTW_CHPLAN_6G_UNSPECIFIED, RTW_REGD_SET_BY_USER))
3446 return -EPERM;
3447
3448 return 0;
3449 }
3450
3451 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3452 struct iw_request_info *a,
3453 union iwreq_data *wrqu, char *b)
3454 {
3455 #ifdef CONFIG_PLATFORM_MT53XX
3456 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3457 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3458
3459 #endif
3460 return 0;
3461 }
3462
3463 static int rtw_wx_get_sensitivity(struct net_device *dev,
3464 struct iw_request_info *info,
3465 union iwreq_data *wrqu, char *buf)
3466 {
3467 #ifdef CONFIG_PLATFORM_MT53XX
3468 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3469
3470 /* Modified by Albert 20110914 */
3471 /* This is in dbm format for MTK platform. */
3472 wrqu->qual.level = padapter->recvpriv.rssi;
3473 RTW_INFO(" level = %u\n", wrqu->qual.level);
3474 #endif
3475 return 0;
3476 }
3477
3478 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3479 struct iw_request_info *info,
3480 union iwreq_data *wrqu, char *extra)
3481 {
3482 #ifdef CONFIG_PLATFORM_MT53XX
3483 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3484
3485 return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3486 #else
3487 return 0;
3488 #endif
3489 }
3490
3491 #ifdef MP_IOCTL_HDL
3492 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
3493 {
3494 pRW_Reg RegRWStruct;
3495 struct rf_reg_param *prfreg;
3496 u8 path;
3497 u8 offset;
3498 u32 value;
3499
3500 RTW_INFO("%s\n", __FUNCTION__);
3501
3502 switch (id) {
3503 case GEN_MP_IOCTL_SUBCODE(MP_START):
3504 RTW_INFO("871x_driver is only for normal mode, can't enter mp mode\n");
3505 break;
3506 case GEN_MP_IOCTL_SUBCODE(READ_REG):
3507 RegRWStruct = (pRW_Reg)pdata;
3508 switch (RegRWStruct->width) {
3509 case 1:
3510 RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
3511 break;
3512 case 2:
3513 RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
3514 break;
3515 case 4:
3516 RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
3517 break;
3518 default:
3519 break;
3520 }
3521
3522 break;
3523 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
3524 RegRWStruct = (pRW_Reg)pdata;
3525 switch (RegRWStruct->width) {
3526 case 1:
3527 rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
3528 break;
3529 case 2:
3530 rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
3531 break;
3532 case 4:
3533 rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
3534 break;
3535 default:
3536 break;
3537 }
3538
3539 break;
3540 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
3541
3542 prfreg = (struct rf_reg_param *)pdata;
3543
3544 path = (u8)prfreg->path;
3545 offset = (u8)prfreg->offset;
3546
3547 value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
3548
3549 prfreg->value = value;
3550
3551 break;
3552 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
3553
3554 prfreg = (struct rf_reg_param *)pdata;
3555
3556 path = (u8)prfreg->path;
3557 offset = (u8)prfreg->offset;
3558 value = prfreg->value;
3559
3560 rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
3561
3562 break;
3563 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
3564 RTW_INFO("==> trigger gpio 0\n");
3565 rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
3566 break;
3567 #ifdef CONFIG_BT_COEXIST
3568 case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):
3569 RTW_INFO("==> set dm_bt_coexist:%x\n", *(u8 *)pdata);
3570 rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
3571 break;
3572 case GEN_MP_IOCTL_SUBCODE(DEL_BA):
3573 RTW_INFO("==> delete ba:%x\n", *(u8 *)pdata);
3574 rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
3575 break;
3576 #endif
3577 #ifdef DBG_CONFIG_ERROR_DETECT
3578 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
3579 *pdata = rtw_hal_sreset_get_wifi_status(padapter);
3580 break;
3581 #endif
3582
3583 default:
3584 break;
3585 }
3586
3587 }
3588 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
3589 union iwreq_data *wrqu, char *extra)
3590 {
3591 int ret = 0;
3592 u32 BytesRead, BytesWritten, BytesNeeded;
3593 struct oid_par_priv oid_par;
3594 struct mp_ioctl_handler *phandler;
3595 struct mp_ioctl_param *poidparam;
3596 uint status = 0;
3597 u16 len;
3598 u8 *pparmbuf = NULL, bset;
3599 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3600 struct iw_point *p = &wrqu->data;
3601
3602 /* RTW_INFO("+rtw_mp_ioctl_hdl\n"); */
3603
3604 /* mutex_lock(&ioctl_mutex); */
3605
3606 if ((!p->length) || (!p->pointer)) {
3607 ret = -EINVAL;
3608 goto _rtw_mp_ioctl_hdl_exit;
3609 }
3610
3611 pparmbuf = NULL;
3612 bset = (u8)(p->flags & 0xFFFF);
3613 len = p->length;
3614 pparmbuf = (u8 *)rtw_malloc(len);
3615 if (pparmbuf == NULL) {
3616 ret = -ENOMEM;
3617 goto _rtw_mp_ioctl_hdl_exit;
3618 }
3619
3620 if (copy_from_user(pparmbuf, p->pointer, len)) {
3621 ret = -EFAULT;
3622 goto _rtw_mp_ioctl_hdl_exit;
3623 }
3624
3625 poidparam = (struct mp_ioctl_param *)pparmbuf;
3626
3627 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
3628 ret = -EINVAL;
3629 goto _rtw_mp_ioctl_hdl_exit;
3630 }
3631
3632 /* RTW_INFO("%s: %d\n", __func__, poidparam->subcode); */
3633 #ifdef CONFIG_MP_INCLUDED
3634 if (padapter->registrypriv.mp_mode == 1) {
3635 phandler = mp_ioctl_hdl + poidparam->subcode;
3636
3637 if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {
3638 ret = -EINVAL;
3639 goto _rtw_mp_ioctl_hdl_exit;
3640 }
3641
3642 if (phandler->handler) {
3643 oid_par.adapter_context = padapter;
3644 oid_par.oid = phandler->oid;
3645 oid_par.information_buf = poidparam->data;
3646 oid_par.information_buf_len = poidparam->len;
3647 oid_par.dbg = 0;
3648
3649 BytesWritten = 0;
3650 BytesNeeded = 0;
3651
3652 if (bset) {
3653 oid_par.bytes_rw = &BytesRead;
3654 oid_par.bytes_needed = &BytesNeeded;
3655 oid_par.type_of_oid = SET_OID;
3656 } else {
3657 oid_par.bytes_rw = &BytesWritten;
3658 oid_par.bytes_needed = &BytesNeeded;
3659 oid_par.type_of_oid = QUERY_OID;
3660 }
3661
3662 status = phandler->handler(&oid_par);
3663
3664 /* todo:check status, BytesNeeded, etc. */
3665 } else {
3666 RTW_INFO("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",
3667 poidparam->subcode, phandler->oid, phandler->handler);
3668 ret = -EFAULT;
3669 goto _rtw_mp_ioctl_hdl_exit;
3670 }
3671 } else
3672 #endif
3673 {
3674 rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
3675 }
3676
3677 if (bset == 0x00) {/* query info */
3678 if (copy_to_user(p->pointer, pparmbuf, len))
3679 ret = -EFAULT;
3680 }
3681
3682 if (status) {
3683 ret = -EFAULT;
3684 goto _rtw_mp_ioctl_hdl_exit;
3685 }
3686
3687 _rtw_mp_ioctl_hdl_exit:
3688
3689 if (pparmbuf)
3690 rtw_mfree(pparmbuf, len);
3691
3692 /* mutex_unlock(&ioctl_mutex); */
3693
3694 return ret;
3695 }
3696 #endif /*MP_IOCTL_HDL*/
3697 static int rtw_get_ap_info(struct net_device *dev,
3698 struct iw_request_info *info,
3699 union iwreq_data *wrqu, char *extra)
3700 {
3701 int ret = 0;
3702 u32 cnt = 0, wpa_ielen;
3703 _irqL irqL;
3704 _list *plist, *phead;
3705 unsigned char *pbuf;
3706 u8 bssid[ETH_ALEN];
3707 char data[32];
3708 struct wlan_network *pnetwork = NULL;
3709 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3710 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3711 _queue *queue = &(pmlmepriv->scanned_queue);
3712 struct iw_point *pdata = &wrqu->data;
3713
3714 RTW_INFO("+rtw_get_aplist_info\n");
3715
3716 if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
3717 ret = -EINVAL;
3718 goto exit;
3719 }
3720
3721 while ((check_fwstate(pmlmepriv, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING))) == _TRUE) {
3722 rtw_msleep_os(30);
3723 cnt++;
3724 if (cnt > 100)
3725 break;
3726 }
3727
3728
3729 /* pdata->length = 0; */ /* ? */
3730 pdata->flags = 0;
3731 if (pdata->length >= 32) {
3732 if (copy_from_user(data, pdata->pointer, 32)) {
3733 ret = -EINVAL;
3734 goto exit;
3735 }
3736 } else {
3737 ret = -EINVAL;
3738 goto exit;
3739 }
3740
3741 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3742
3743 phead = get_list_head(queue);
3744 plist = get_next(phead);
3745
3746 while (1) {
3747 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
3748 break;
3749
3750
3751 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
3752
3753 if (hwaddr_aton_i(data, bssid)) {
3754 RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data);
3755 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3756 return -EINVAL;
3757 }
3758
3759
3760 if (_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) { /* BSSID match, then check if supporting wpa/wpa2 */
3761 RTW_INFO("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
3762
3763 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
3764 if (pbuf && (wpa_ielen > 0)) {
3765 pdata->flags = 1;
3766 break;
3767 }
3768
3769 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
3770 if (pbuf && (wpa_ielen > 0)) {
3771 pdata->flags = 2;
3772 break;
3773 }
3774
3775 }
3776
3777 plist = get_next(plist);
3778
3779 }
3780
3781 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3782
3783 if (pdata->length >= 34) {
3784 if (copy_to_user((u8 *)pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
3785 ret = -EINVAL;
3786 goto exit;
3787 }
3788 }
3789
3790 exit:
3791
3792 return ret;
3793
3794 }
3795
3796 static int rtw_set_pid(struct net_device *dev,
3797 struct iw_request_info *info,
3798 union iwreq_data *wrqu, char *extra)
3799 {
3800
3801 int ret = 0;
3802 _adapter *padapter = rtw_netdev_priv(dev);
3803 int *pdata = (int *)wrqu;
3804 int selector;
3805
3806 if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
3807 ret = -EINVAL;
3808 goto exit;
3809 }
3810
3811 selector = *pdata;
3812 if (selector < 3 && selector >= 0) {
3813 padapter->pid[selector] = *(pdata + 1);
3814 #ifdef CONFIG_GLOBAL_UI_PID
3815 ui_pid[selector] = *(pdata + 1);
3816 #endif
3817 RTW_INFO("%s set pid[%d]=%d\n", __FUNCTION__, selector , padapter->pid[selector]);
3818 } else
3819 RTW_INFO("%s selector %d error\n", __FUNCTION__, selector);
3820
3821 exit:
3822
3823 return ret;
3824
3825 }
3826
3827 static int rtw_wps_start(struct net_device *dev,
3828 struct iw_request_info *info,
3829 union iwreq_data *wrqu, char *extra)
3830 {
3831
3832 int ret = 0;
3833 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3834 struct iw_point *pdata = &wrqu->data;
3835 u32 u32wps_start = 0;
3836 unsigned int uintRet = 0;
3837
3838 if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) {
3839 ret = -EINVAL;
3840 goto exit;
3841 }
3842
3843 uintRet = copy_from_user((void *) &u32wps_start, pdata->pointer, 4);
3844 if (u32wps_start == 0)
3845 u32wps_start = *extra;
3846
3847 RTW_INFO("[%s] wps_start = %d\n", __FUNCTION__, u32wps_start);
3848
3849 if (u32wps_start == 1) /* WPS Start */
3850 rtw_led_control(padapter, LED_CTL_START_WPS);
3851 else if (u32wps_start == 2) /* WPS Stop because of wps success */
3852 rtw_led_control(padapter, LED_CTL_STOP_WPS);
3853 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
3854 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
3855
3856 exit:
3857
3858 return ret;
3859
3860 }
3861
3862 #ifdef CONFIG_P2P
3863 static int rtw_wext_p2p_enable(struct net_device *dev,
3864 struct iw_request_info *info,
3865 union iwreq_data *wrqu, char *extra)
3866 {
3867
3868 int ret = 0;
3869 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3870 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3871 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3872 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
3873 #ifdef CONFIG_CONCURRENT_MODE
3874 struct roch_info *prochinfo = &padapter->rochinfo;
3875 #endif
3876
3877 if (*extra == '0')
3878 init_role = P2P_ROLE_DISABLE;
3879 else if (*extra == '1')
3880 init_role = P2P_ROLE_DEVICE;
3881 else if (*extra == '2')
3882 init_role = P2P_ROLE_CLIENT;
3883 else if (*extra == '3')
3884 init_role = P2P_ROLE_GO;
3885
3886 if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
3887 ret = -EFAULT;
3888 goto exit;
3889 }
3890
3891 /* set channel/bandwidth */
3892 if (init_role != P2P_ROLE_DISABLE) {
3893 u8 channel, ch_offset;
3894 u16 bwmode;
3895
3896 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
3897 /* Stay at the listen state and wait for discovery. */
3898 channel = pwdinfo->listen_channel;
3899 pwdinfo->operating_channel = pwdinfo->listen_channel;
3900 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3901 bwmode = CHANNEL_WIDTH_20;
3902 }
3903 #ifdef CONFIG_CONCURRENT_MODE
3904 else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
3905
3906 _set_timer(&prochinfo->ap_roch_ch_switch_timer, pwdinfo->ext_listen_interval);
3907
3908 channel = rtw_mi_get_union_chan(padapter);
3909 ch_offset = rtw_mi_get_union_offset(padapter);
3910 bwmode = rtw_mi_get_union_bw(padapter);
3911
3912 pwdinfo->operating_channel = channel;
3913 }
3914 #endif
3915 else {
3916 pwdinfo->operating_channel = pmlmeext->cur_channel;
3917
3918 channel = pwdinfo->operating_channel;
3919 ch_offset = pmlmeext->cur_ch_offset;
3920 bwmode = pmlmeext->cur_bwmode;
3921 }
3922
3923 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
3924 }
3925
3926 exit:
3927 return ret;
3928
3929 }
3930
3931 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
3932 struct iw_request_info *info,
3933 union iwreq_data *wrqu, char *extra)
3934 {
3935
3936 int ret = 0;
3937 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3938 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3939
3940 RTW_INFO("[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen(extra));
3941 if( strlen(extra) > WPS_MAX_DEVICE_NAME_LEN){
3942 RTW_ERR("Invalid strlen(extra): %zu\n", strlen(extra));
3943 rtw_warn_on(1);
3944 return -1;
3945 }
3946 _rtw_memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
3947 pwdinfo->nego_ssidlen = strlen(extra);
3948
3949 return ret;
3950
3951 }
3952
3953
3954 static int rtw_p2p_set_intent(struct net_device *dev,
3955 struct iw_request_info *info,
3956 union iwreq_data *wrqu, char *extra)
3957 {
3958 int ret = 0;
3959 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3960 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3961 u8 intent = pwdinfo->intent;
3962
3963 extra[wrqu->data.length] = 0x00;
3964
3965 intent = rtw_atoi(extra);
3966
3967 if (intent <= 15)
3968 pwdinfo->intent = intent;
3969 else
3970 ret = -1;
3971
3972 RTW_INFO("[%s] intent = %d\n", __FUNCTION__, intent);
3973
3974 return ret;
3975
3976 }
3977
3978 static int rtw_p2p_set_listen_ch(struct net_device *dev,
3979 struct iw_request_info *info,
3980 union iwreq_data *wrqu, char *extra)
3981 {
3982
3983 int ret = 0;
3984 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3985 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3986 u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */
3987
3988 extra[wrqu->data.length] = 0x00;
3989 listen_ch = rtw_atoi(extra);
3990
3991 if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
3992 pwdinfo->listen_channel = listen_ch;
3993 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3994 } else
3995 ret = -1;
3996
3997 RTW_INFO("[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel);
3998
3999 return ret;
4000
4001 }
4002
4003 static int rtw_p2p_set_op_ch(struct net_device *dev,
4004 struct iw_request_info *info,
4005 union iwreq_data *wrqu, char *extra)
4006 {
4007 /* Commented by Albert 20110524
4008 * This function is used to set the operating channel if the driver will become the group owner */
4009
4010 int ret = 0;
4011 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4012 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4013 u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */
4014
4015 extra[wrqu->data.length] = 0x00;
4016
4017 op_ch = (u8) rtw_atoi(extra);
4018 if (op_ch > 0)
4019 pwdinfo->operating_channel = op_ch;
4020 else
4021 ret = -1;
4022
4023 RTW_INFO("[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel);
4024
4025 return ret;
4026
4027 }
4028
4029
4030 static int rtw_p2p_profilefound(struct net_device *dev,
4031 struct iw_request_info *info,
4032 union iwreq_data *wrqu, char *extra)
4033 {
4034
4035 int ret = 0;
4036 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4037 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4038
4039 /* Comment by Albert 2010/10/13 */
4040 /* Input data format: */
4041 /* Ex: 0 */
4042 /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
4043 /* 0 => Reflush the profile record list. */
4044 /* 1 => Add the profile list */
4045 /* XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) */
4046 /* YY => SSID Length */
4047 /* SSID => SSID for persistence group */
4048
4049 RTW_INFO("[%s] In value = %s, len = %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4050
4051
4052 /* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
4053 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4054 if (extra[0] == '0') {
4055 /* Remove all the profile information of wifidirect_info structure. */
4056 _rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
4057 pwdinfo->profileindex = 0;
4058 } else {
4059 if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM)
4060 ret = -1;
4061 else {
4062 int jj, kk;
4063
4064 /* Add this profile information into pwdinfo->profileinfo */
4065 /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
4066 for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
4067 pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4068
4069 /* pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[19] - '0' ); */
4070 /* _rtw_memcpy( pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen ); */
4071 pwdinfo->profileindex++;
4072 }
4073 }
4074 }
4075
4076 return ret;
4077
4078 }
4079
4080 static int rtw_p2p_setDN(struct net_device *dev,
4081 struct iw_request_info *info,
4082 union iwreq_data *wrqu, char *extra)
4083 {
4084
4085 int ret = 0;
4086 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4087 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4088
4089
4090 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4091 _rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
4092 if( wrqu->data.length - 1 > WPS_MAX_DEVICE_NAME_LEN){
4093 RTW_ERR("Invalid wrqu->data.length:%d\n", wrqu->data.length - 1);
4094 rtw_warn_on(1);
4095 return -1;
4096 }
4097 _rtw_memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
4098 pwdinfo->device_name_len = wrqu->data.length - 1;
4099
4100 return ret;
4101
4102 }
4103
4104
4105 static int rtw_p2p_get_status(struct net_device *dev,
4106 struct iw_request_info *info,
4107 union iwreq_data *wrqu, char *extra)
4108 {
4109
4110 int ret = 0;
4111 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4112 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4113
4114 if (padapter->bShowGetP2PState) {
4115 RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4116 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4117 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4118 }
4119
4120 /* Commented by Albert 2010/10/12 */
4121 /* Because of the output size limitation, I had removed the "Role" information. */
4122 /* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
4123 sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
4124 wrqu->data.length = strlen(extra);
4125
4126 return ret;
4127
4128 }
4129
4130 /* Commented by Albert 20110520
4131 * This function will return the config method description
4132 * This config method description will show us which config method the remote P2P device is intented to use
4133 * by sending the provisioning discovery request frame. */
4134
4135 static int rtw_p2p_get_req_cm(struct net_device *dev,
4136 struct iw_request_info *info,
4137 union iwreq_data *wrqu, char *extra)
4138 {
4139
4140 int ret = 0;
4141 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4142 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4143
4144 sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
4145 wrqu->data.length = strlen(extra);
4146 return ret;
4147
4148 }
4149
4150
4151 static int rtw_p2p_get_role(struct net_device *dev,
4152 struct iw_request_info *info,
4153 union iwreq_data *wrqu, char *extra)
4154 {
4155
4156 int ret = 0;
4157 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4158 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4159
4160 RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4161 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4162 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4163
4164 sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
4165 wrqu->data.length = strlen(extra);
4166 return ret;
4167
4168 }
4169
4170
4171 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4172 struct iw_request_info *info,
4173 union iwreq_data *wrqu, char *extra)
4174 {
4175
4176 int ret = 0;
4177 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4178 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4179
4180
4181 RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4182 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4183 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4184
4185 sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4186 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4187 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4188 wrqu->data.length = strlen(extra);
4189 return ret;
4190
4191 }
4192
4193 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4194 struct iw_request_info *info,
4195 union iwreq_data *wrqu, char *extra)
4196
4197 {
4198
4199 int ret = 0;
4200 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4201 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4202
4203 RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4204 pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4205 pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4206 pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4207 sprintf(extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4208 pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4209 pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4210 pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4211 wrqu->data.length = strlen(extra);
4212 return ret;
4213
4214 }
4215
4216 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4217 struct iw_request_info *info,
4218 union iwreq_data *wrqu, char *extra)
4219
4220 {
4221
4222 int ret = 0;
4223 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4224 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4225
4226 RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4227 pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4228 pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4229 pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4230 sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4231 pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4232 pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4233 pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4234 wrqu->data.length = strlen(extra);
4235 return ret;
4236
4237 }
4238
4239 static int rtw_p2p_get_groupid(struct net_device *dev,
4240 struct iw_request_info *info,
4241 union iwreq_data *wrqu, char *extra)
4242
4243 {
4244
4245 int ret = 0;
4246 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4247 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4248
4249 sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4250 pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
4251 pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
4252 pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
4253 pwdinfo->groupid_info.ssid);
4254 wrqu->data.length = strlen(extra);
4255 return ret;
4256
4257 }
4258
4259 static int rtw_p2p_get_op_ch(struct net_device *dev,
4260 struct iw_request_info *info,
4261 union iwreq_data *wrqu, char *extra)
4262
4263 {
4264
4265 int ret = 0;
4266 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4267 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4268
4269
4270 RTW_INFO("[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4271
4272 sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
4273 wrqu->data.length = strlen(extra);
4274 return ret;
4275
4276 }
4277
4278 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4279 struct iw_request_info *info,
4280 union iwreq_data *wrqu, char *extra, char *subcmd)
4281 {
4282
4283 int ret = 0;
4284 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4285 u8 peerMAC[ETH_ALEN] = { 0x00 };
4286 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4287 _irqL irqL;
4288 _list *plist, *phead;
4289 _queue *queue = &(pmlmepriv->scanned_queue);
4290 struct wlan_network *pnetwork = NULL;
4291 u8 blnMatch = 0;
4292 u16 attr_content = 0;
4293 uint attr_contentlen = 0;
4294 u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4295
4296 /* Commented by Albert 20110727 */
4297 /* The input data is the MAC address which the application wants to know its WPS config method. */
4298 /* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
4299 /* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
4300
4301 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4302
4303 macstr2num(peerMAC, subcmd);
4304
4305 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4306
4307 phead = get_list_head(queue);
4308 plist = get_next(phead);
4309
4310 while (1) {
4311 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4312 break;
4313
4314 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4315 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4316 u8 *wpsie;
4317 uint wpsie_len = 0;
4318
4319 /* The mac address is matched. */
4320
4321 wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4322 if (wpsie) {
4323 attr_contentlen = sizeof(attr_content);
4324 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4325 if (attr_contentlen) {
4326 attr_content = be16_to_cpu(attr_content);
4327 sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4328 blnMatch = 1;
4329 }
4330 }
4331
4332 break;
4333 }
4334
4335 plist = get_next(plist);
4336
4337 }
4338
4339 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4340
4341 if (!blnMatch)
4342 sprintf(attr_content_str, "\n\nM=0000");
4343
4344 wrqu->data.length = strlen(attr_content_str);
4345 _rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4346
4347 return ret;
4348
4349 }
4350
4351 #ifdef CONFIG_WFD
4352 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4353 struct iw_request_info *info,
4354 union iwreq_data *wrqu, char *extra)
4355 {
4356
4357 int ret = 0;
4358 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4359 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4360
4361 RTW_INFO("[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
4362
4363 sprintf(extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport);
4364 RTW_INFO("[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
4365
4366 wrqu->data.length = strlen(extra);
4367 return ret;
4368
4369 }
4370
4371 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4372 struct iw_request_info *info,
4373 union iwreq_data *wrqu, char *extra)
4374 {
4375
4376 int ret = 0;
4377 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4378 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4379
4380 sprintf(extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc);
4381 RTW_INFO("[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc);
4382
4383 wrqu->data.length = strlen(extra);
4384 pwdinfo->wfd_info->wfd_pc = _FALSE; /* Reset the WFD preferred connection to P2P */
4385 return ret;
4386
4387 }
4388
4389 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4390 struct iw_request_info *info,
4391 union iwreq_data *wrqu, char *extra)
4392 {
4393
4394 int ret = 0;
4395 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4396 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4397
4398 sprintf(extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail);
4399 RTW_INFO("[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail);
4400
4401 wrqu->data.length = strlen(extra);
4402 pwdinfo->wfd_info->peer_session_avail = _TRUE; /* Reset the WFD session available */
4403 return ret;
4404
4405 }
4406 #endif /* CONFIG_WFD */
4407
4408 static int rtw_p2p_get_go_device_address(struct net_device *dev,
4409 struct iw_request_info *info,
4410 union iwreq_data *wrqu, char *extra, char *subcmd)
4411 {
4412
4413 int ret = 0;
4414 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4415 u8 peerMAC[ETH_ALEN] = { 0x00 };
4416 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4417 _irqL irqL;
4418 _list *plist, *phead;
4419 _queue *queue = &(pmlmepriv->scanned_queue);
4420 struct wlan_network *pnetwork = NULL;
4421 u8 blnMatch = 0;
4422 u8 *p2pie;
4423 uint p2pielen = 0, attr_contentlen = 0;
4424 u8 attr_content[100] = { 0x00 };
4425 u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4426
4427 /* Commented by Albert 20121209 */
4428 /* The input data is the GO's interface address which the application wants to know its device address. */
4429 /* Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 */
4430
4431 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4432
4433 macstr2num(peerMAC, subcmd);
4434
4435 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4436
4437 phead = get_list_head(queue);
4438 plist = get_next(phead);
4439
4440 while (1) {
4441 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4442 break;
4443
4444 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4445 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4446 /* Commented by Albert 2011/05/18 */
4447 /* Match the device address located in the P2P IE */
4448 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
4449
4450 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4451 if (p2pie) {
4452 while (p2pie) {
4453 /* The P2P Device ID attribute is included in the Beacon frame. */
4454 /* The P2P Device Info attribute is included in the probe response frame. */
4455
4456 _rtw_memset(attr_content, 0x00, 100);
4457 attr_contentlen = sizeof(attr_content);
4458 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
4459 /* Handle the P2P Device ID attribute of Beacon first */
4460 blnMatch = 1;
4461 break;
4462
4463 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
4464 /* Handle the P2P Device Info attribute of probe response */
4465 blnMatch = 1;
4466 break;
4467 }
4468
4469 /* Get the next P2P IE */
4470 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
4471 }
4472 }
4473 }
4474
4475 plist = get_next(plist);
4476
4477 }
4478
4479 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4480
4481 if (!blnMatch)
4482 sprintf(go_devadd_str, "\n\ndev_add=NULL");
4483 else {
4484 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4485 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
4486 }
4487
4488 wrqu->data.length = strlen(go_devadd_str);
4489 _rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
4490
4491 return ret;
4492
4493 }
4494
4495 static int rtw_p2p_get_device_type(struct net_device *dev,
4496 struct iw_request_info *info,
4497 union iwreq_data *wrqu, char *extra, char *subcmd)
4498 {
4499
4500 int ret = 0;
4501 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4502 u8 peerMAC[ETH_ALEN] = { 0x00 };
4503 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4504 _irqL irqL;
4505 _list *plist, *phead;
4506 _queue *queue = &(pmlmepriv->scanned_queue);
4507 struct wlan_network *pnetwork = NULL;
4508 u8 blnMatch = 0;
4509 u8 dev_type[8] = { 0x00 };
4510 uint dev_type_len = 0;
4511 u8 dev_type_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; /* +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */
4512
4513 /* Commented by Albert 20121209 */
4514 /* The input data is the MAC address which the application wants to know its device type. */
4515 /* Such user interface could know the device type. */
4516 /* Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 */
4517
4518 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4519
4520 macstr2num(peerMAC, subcmd);
4521
4522 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4523
4524 phead = get_list_head(queue);
4525 plist = get_next(phead);
4526
4527 while (1) {
4528 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4529 break;
4530
4531 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4532 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4533 u8 *wpsie;
4534 uint wpsie_len = 0;
4535
4536 /* The mac address is matched. */
4537
4538 wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4539 if (wpsie) {
4540 dev_type_len = sizeof(dev_type);
4541 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
4542 if (dev_type_len) {
4543 u16 type = 0;
4544
4545 _rtw_memcpy(&type, dev_type, 2);
4546 type = be16_to_cpu(type);
4547 sprintf(dev_type_str, "\n\nN=%.2d", type);
4548 blnMatch = 1;
4549 }
4550 }
4551 break;
4552 }
4553
4554 plist = get_next(plist);
4555
4556 }
4557
4558 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4559
4560 if (!blnMatch)
4561 sprintf(dev_type_str, "\n\nN=00");
4562
4563 wrqu->data.length = strlen(dev_type_str);
4564 _rtw_memcpy(extra, dev_type_str, wrqu->data.length);
4565
4566 return ret;
4567
4568 }
4569
4570 static int rtw_p2p_get_device_name(struct net_device *dev,
4571 struct iw_request_info *info,
4572 union iwreq_data *wrqu, char *extra, char *subcmd)
4573 {
4574
4575 int ret = 0;
4576 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4577 u8 peerMAC[ETH_ALEN] = { 0x00 };
4578 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4579 _irqL irqL;
4580 _list *plist, *phead;
4581 _queue *queue = &(pmlmepriv->scanned_queue);
4582 struct wlan_network *pnetwork = NULL;
4583 u8 blnMatch = 0;
4584 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
4585 uint dev_len = 0;
4586 u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4587
4588 /* Commented by Albert 20121225 */
4589 /* The input data is the MAC address which the application wants to know its device name. */
4590 /* Such user interface could show peer device's device name instead of ssid. */
4591 /* Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 */
4592
4593 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4594
4595 macstr2num(peerMAC, subcmd);
4596
4597 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4598
4599 phead = get_list_head(queue);
4600 plist = get_next(phead);
4601
4602 while (1) {
4603 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4604 break;
4605
4606 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4607 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4608 u8 *wpsie;
4609 uint wpsie_len = 0;
4610
4611 /* The mac address is matched. */
4612
4613 wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4614 if (wpsie) {
4615 dev_len = sizeof(dev_name);
4616 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
4617 if (dev_len) {
4618 sprintf(dev_name_str, "\n\nN=%s", dev_name);
4619 blnMatch = 1;
4620 }
4621 }
4622 break;
4623 }
4624
4625 plist = get_next(plist);
4626
4627 }
4628
4629 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4630
4631 if (!blnMatch)
4632 sprintf(dev_name_str, "\n\nN=0000");
4633
4634 wrqu->data.length = strlen(dev_name_str);
4635 _rtw_memcpy(extra, dev_name_str, wrqu->data.length);
4636
4637 return ret;
4638
4639 }
4640
4641 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
4642 struct iw_request_info *info,
4643 union iwreq_data *wrqu, char *extra, char *subcmd)
4644 {
4645
4646 int ret = 0;
4647 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4648 u8 peerMAC[ETH_ALEN] = { 0x00 };
4649 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4650 _irqL irqL;
4651 _list *plist, *phead;
4652 _queue *queue = &(pmlmepriv->scanned_queue);
4653 struct wlan_network *pnetwork = NULL;
4654 u8 blnMatch = 0;
4655 u8 *p2pie;
4656 uint p2pielen = 0, attr_contentlen = 2;
4657 u8 attr_content[2] = { 0x00 };
4658 u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4659
4660 /* Commented by Ouden 20121226 */
4661 /* The application wants to know P2P initation procedure is support or not. */
4662 /* Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 */
4663
4664 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4665
4666 macstr2num(peerMAC, subcmd);
4667
4668 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4669
4670 phead = get_list_head(queue);
4671 plist = get_next(phead);
4672
4673 while (1) {
4674 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4675 break;
4676
4677 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4678 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4679 /* Commented by Albert 20121226 */
4680 /* Match the device address located in the P2P IE */
4681 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
4682
4683 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4684 if (p2pie) {
4685 while (p2pie) {
4686 /* _rtw_memset( attr_content, 0x00, 2); */
4687 attr_contentlen = sizeof(attr_content);
4688 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
4689 /* Handle the P2P capability attribute */
4690 blnMatch = 1;
4691 break;
4692
4693 }
4694
4695 /* Get the next P2P IE */
4696 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
4697 }
4698 }
4699 }
4700
4701 plist = get_next(plist);
4702
4703 }
4704
4705 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4706
4707 if (!blnMatch)
4708 sprintf(inv_proc_str, "\nIP=-1");
4709 else {
4710 if ((attr_content[0] & 0x20) == 0x20)
4711 sprintf(inv_proc_str, "\nIP=1");
4712 else
4713 sprintf(inv_proc_str, "\nIP=0");
4714 }
4715
4716 wrqu->data.length = strlen(inv_proc_str);
4717 _rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
4718
4719 return ret;
4720
4721 }
4722
4723 static int rtw_p2p_connect(struct net_device *dev,
4724 struct iw_request_info *info,
4725 union iwreq_data *wrqu, char *extra)
4726 {
4727
4728 int ret = 0;
4729 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4730 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4731 u8 peerMAC[ETH_ALEN] = { 0x00 };
4732 int jj, kk;
4733 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4734 _irqL irqL;
4735 _list *plist, *phead;
4736 _queue *queue = &(pmlmepriv->scanned_queue);
4737 struct wlan_network *pnetwork = NULL;
4738 uint uintPeerChannel = 0;
4739 #ifdef CONFIG_CONCURRENT_MODE
4740 struct roch_info *prochinfo = &padapter->rochinfo;
4741 #endif
4742
4743 /* Commented by Albert 20110304 */
4744 /* The input data contains two informations. */
4745 /* 1. First information is the MAC address which wants to formate with */
4746 /* 2. Second information is the WPS PINCode or "pbc" string for push button method */
4747 /* Format: 00:E0:4C:00:00:05 */
4748 /* Format: 00:E0:4C:00:00:05 */
4749
4750 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
4751
4752 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
4753 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
4754 return ret;
4755 }
4756
4757 if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
4758 return -1;
4759
4760 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4761 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4762
4763 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4764
4765 phead = get_list_head(queue);
4766 plist = get_next(phead);
4767
4768 while (1) {
4769 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4770 break;
4771
4772 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4773 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4774 if (pnetwork->network.Configuration.DSConfig != 0)
4775 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4776 else if (pwdinfo->nego_req_info.peer_ch != 0)
4777 uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch;
4778 else {
4779 /* Unexpected case */
4780 uintPeerChannel = 0;
4781 RTW_INFO("%s uintPeerChannel = 0\n", __func__);
4782 }
4783 break;
4784 }
4785
4786 plist = get_next(plist);
4787
4788 }
4789
4790 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4791
4792 if (uintPeerChannel) {
4793 #ifdef CONFIG_CONCURRENT_MODE
4794 if (rtw_mi_check_status(padapter, MI_LINKED))
4795 _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
4796 #endif /* CONFIG_CONCURRENT_MODE */
4797
4798 _rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
4799 _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
4800
4801 pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
4802 _rtw_memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
4803 pwdinfo->nego_req_info.benable = _TRUE;
4804
4805 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
4806 if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
4807 /* Restore to the listen state if the current p2p state is not nego OK */
4808 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4809 }
4810
4811 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4812 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
4813
4814 #ifdef CONFIG_CONCURRENT_MODE
4815 if (rtw_mi_check_status(padapter, MI_LINKED)) {
4816 u8 union_ch = rtw_mi_get_union_chan(padapter);
4817 u8 union_bw = rtw_mi_get_union_bw(padapter);
4818 u8 union_offset = rtw_mi_get_union_offset(padapter);
4819
4820 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
4821 rtw_leave_opch(padapter);
4822 }
4823 #endif /* CONFIG_CONCURRENT_MODE */
4824
4825 RTW_INFO("[%s] Start PreTx Procedure!\n", __FUNCTION__);
4826 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
4827 #ifdef CONFIG_CONCURRENT_MODE
4828 if (rtw_mi_check_status(padapter, MI_LINKED))
4829 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT);
4830 else
4831 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
4832 #else
4833 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
4834 #endif /* CONFIG_CONCURRENT_MODE */
4835
4836 } else {
4837 RTW_INFO("[%s] Not Found in Scanning Queue~\n", __FUNCTION__);
4838 ret = -1;
4839 }
4840
4841 return ret;
4842 }
4843
4844 static int rtw_p2p_invite_req(struct net_device *dev,
4845 struct iw_request_info *info,
4846 union iwreq_data *wrqu, char *extra)
4847 {
4848
4849 int ret = 0;
4850 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4851 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4852 int jj, kk;
4853 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4854 _list *plist, *phead;
4855 _queue *queue = &(pmlmepriv->scanned_queue);
4856 struct wlan_network *pnetwork = NULL;
4857 uint uintPeerChannel = 0;
4858 u8 attr_content[50] = { 0x00 };
4859 u8 *p2pie;
4860 uint p2pielen = 0, attr_contentlen = 50;
4861 _irqL irqL;
4862 struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
4863 #ifdef CONFIG_CONCURRENT_MODE
4864 struct roch_info *prochinfo = &padapter->rochinfo;
4865 #endif
4866
4867 /* Commented by Albert 20120321 */
4868 /* The input data contains two informations. */
4869 /* 1. First information is the P2P device address which you want to send to. */
4870 /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
4871 /* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
4872 /* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
4873
4874 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
4875
4876 if (wrqu->data.length <= 37) {
4877 RTW_INFO("[%s] Wrong format!\n", __FUNCTION__);
4878 return ret;
4879 }
4880
4881 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4882 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
4883 return ret;
4884 } else {
4885 /* Reset the content of struct tx_invite_req_info */
4886 pinvite_req_info->benable = _FALSE;
4887 _rtw_memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
4888 _rtw_memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
4889 pinvite_req_info->ssidlen = 0x00;
4890 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
4891 _rtw_memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
4892 pinvite_req_info->token = 3;
4893 }
4894
4895 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4896 pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4897
4898 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4899
4900 phead = get_list_head(queue);
4901 plist = get_next(phead);
4902
4903 while (1) {
4904 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4905 break;
4906
4907 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4908
4909 /* Commented by Albert 2011/05/18 */
4910 /* Match the device address located in the P2P IE */
4911 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
4912
4913 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4914 if (p2pie) {
4915 /* The P2P Device ID attribute is included in the Beacon frame. */
4916 /* The P2P Device Info attribute is included in the probe response frame. */
4917
4918 attr_contentlen = sizeof(attr_content);
4919 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
4920 /* Handle the P2P Device ID attribute of Beacon first */
4921 if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
4922 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4923 break;
4924 }
4925 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
4926 /* Handle the P2P Device Info attribute of probe response */
4927 if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
4928 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4929 break;
4930 }
4931 }
4932
4933 }
4934
4935 plist = get_next(plist);
4936
4937 }
4938
4939 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4940
4941 #ifdef CONFIG_WFD
4942 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) {
4943 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
4944 u8 *wfd_ie;
4945 uint wfd_ielen = 0;
4946
4947 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
4948 if (wfd_ie) {
4949 u8 *wfd_devinfo;
4950 uint wfd_devlen;
4951
4952 RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
4953 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
4954 if (wfd_devinfo) {
4955 u16 wfd_devinfo_field = 0;
4956
4957 /* Commented by Albert 20120319 */
4958 /* The first two bytes are the WFD device information field of WFD device information subelement. */
4959 /* In big endian format. */
4960 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
4961 if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
4962 pwfd_info->peer_session_avail = _TRUE;
4963 else
4964 pwfd_info->peer_session_avail = _FALSE;
4965 }
4966 }
4967
4968 if (_FALSE == pwfd_info->peer_session_avail) {
4969 RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
4970 goto exit;
4971 }
4972 }
4973 #endif /* CONFIG_WFD */
4974
4975 if (uintPeerChannel) {
4976 #ifdef CONFIG_CONCURRENT_MODE
4977 if (rtw_mi_check_status(padapter, MI_LINKED))
4978 _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
4979 #endif /* CONFIG_CONCURRENT_MODE */
4980
4981 /* Store the GO's bssid */
4982 for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
4983 pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4984
4985 /* Store the GO's ssid */
4986 pinvite_req_info->ssidlen = wrqu->data.length - 36;
4987 _rtw_memcpy(pinvite_req_info->go_ssid, &extra[36], (u32) pinvite_req_info->ssidlen);
4988 pinvite_req_info->benable = _TRUE;
4989 pinvite_req_info->peer_ch = uintPeerChannel;
4990
4991 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4992 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
4993
4994 #ifdef CONFIG_CONCURRENT_MODE
4995 if (rtw_mi_check_status(padapter, MI_LINKED)) {
4996 u8 union_ch = rtw_mi_get_union_chan(padapter);
4997 u8 union_bw = rtw_mi_get_union_bw(padapter);
4998 u8 union_offset = rtw_mi_get_union_offset(padapter);
4999
5000 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5001 rtw_leave_opch(padapter);
5002
5003 } else
5004 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5005 #else
5006 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5007 #endif/*CONFIG_CONCURRENT_MODE*/
5008
5009 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5010
5011 #ifdef CONFIG_CONCURRENT_MODE
5012 if (rtw_mi_check_status(padapter, MI_LINKED))
5013 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT);
5014 else
5015 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5016 #else
5017 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5018 #endif /* CONFIG_CONCURRENT_MODE */
5019
5020
5021 } else
5022 RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5023 exit:
5024
5025 return ret;
5026
5027 }
5028
5029 static int rtw_p2p_set_persistent(struct net_device *dev,
5030 struct iw_request_info *info,
5031 union iwreq_data *wrqu, char *extra)
5032 {
5033
5034 int ret = 0;
5035 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5036 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5037
5038 /* Commented by Albert 20120328 */
5039 /* The input data is 0 or 1 */
5040 /* 0: disable persistent group functionality */
5041 /* 1: enable persistent group founctionality */
5042
5043 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5044
5045 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5046 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5047 return ret;
5048 } else {
5049 if (extra[0] == '0') /* Disable the persistent group function. */
5050 pwdinfo->persistent_supported = _FALSE;
5051 else if (extra[0] == '1') /* Enable the persistent group function. */
5052 pwdinfo->persistent_supported = _TRUE;
5053 else
5054 pwdinfo->persistent_supported = _FALSE;
5055 }
5056 printk("[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported);
5057
5058 return ret;
5059
5060 }
5061
5062 static int uuid_str2bin(const char *str, u8 *bin)
5063 {
5064 const char *pos;
5065 u8 *opos;
5066
5067 pos = str;
5068 opos = bin;
5069
5070 if (hexstr2bin(pos, opos, 4))
5071 return -1;
5072 pos += 8;
5073 opos += 4;
5074
5075 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5076 return -1;
5077 pos += 4;
5078 opos += 2;
5079
5080 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5081 return -1;
5082 pos += 4;
5083 opos += 2;
5084
5085 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5086 return -1;
5087 pos += 4;
5088 opos += 2;
5089
5090 if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5091 return -1;
5092
5093 return 0;
5094 }
5095
5096 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5097 struct iw_request_info *info,
5098 union iwreq_data *wrqu, char *extra)
5099 {
5100
5101 int ret = 0;
5102 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5103 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5104
5105 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5106
5107 if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))
5108 pwdinfo->external_uuid = 1;
5109 else {
5110 pwdinfo->external_uuid = 0;
5111 ret = -EINVAL;
5112 }
5113
5114 return ret;
5115
5116 }
5117 #ifdef CONFIG_WFD
5118 static int rtw_p2p_set_pc(struct net_device *dev,
5119 struct iw_request_info *info,
5120 union iwreq_data *wrqu, char *extra)
5121 {
5122
5123 int ret = 0;
5124 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5125 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5126 u8 peerMAC[ETH_ALEN] = { 0x00 };
5127 int jj, kk;
5128 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5129 _list *plist, *phead;
5130 _queue *queue = &(pmlmepriv->scanned_queue);
5131 struct wlan_network *pnetwork = NULL;
5132 u8 attr_content[50] = { 0x00 };
5133 u8 *p2pie;
5134 uint p2pielen = 0, attr_contentlen = 50;
5135 _irqL irqL;
5136 uint uintPeerChannel = 0;
5137
5138 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5139
5140 /* Commented by Albert 20120512 */
5141 /* 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) */
5142 /* Format: 00:E0:4C:00:00:05 */
5143
5144 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5145
5146 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5147 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5148 return ret;
5149 }
5150
5151 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5152 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5153
5154 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5155
5156 phead = get_list_head(queue);
5157 plist = get_next(phead);
5158
5159 while (1) {
5160 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5161 break;
5162
5163 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5164
5165 /* Commented by Albert 2011/05/18 */
5166 /* Match the device address located in the P2P IE */
5167 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
5168
5169 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5170 if (p2pie) {
5171 /* The P2P Device ID attribute is included in the Beacon frame. */
5172 /* The P2P Device Info attribute is included in the probe response frame. */
5173 printk("[%s] Got P2P IE\n", __FUNCTION__);
5174 attr_contentlen = sizeof(attr_content);
5175 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5176 /* Handle the P2P Device ID attribute of Beacon first */
5177 printk("[%s] P2P_ATTR_DEVICE_ID\n", __FUNCTION__);
5178 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5179 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5180 break;
5181 }
5182 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5183 /* Handle the P2P Device Info attribute of probe response */
5184 printk("[%s] P2P_ATTR_DEVICE_INFO\n", __FUNCTION__);
5185 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5186 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5187 break;
5188 }
5189 }
5190
5191 }
5192
5193 plist = get_next(plist);
5194
5195 }
5196
5197 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5198 printk("[%s] channel = %d\n", __FUNCTION__, uintPeerChannel);
5199
5200 if (uintPeerChannel) {
5201 u8 *wfd_ie;
5202 uint wfd_ielen = 0;
5203
5204 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5205 if (wfd_ie) {
5206 u8 *wfd_devinfo;
5207 uint wfd_devlen;
5208
5209 RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5210 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5211 if (wfd_devinfo) {
5212 u16 wfd_devinfo_field = 0;
5213
5214 /* Commented by Albert 20120319 */
5215 /* The first two bytes are the WFD device information field of WFD device information subelement. */
5216 /* In big endian format. */
5217 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5218 if (wfd_devinfo_field & WFD_DEVINFO_PC_TDLS)
5219 pwfd_info->wfd_pc = _TRUE;
5220 else
5221 pwfd_info->wfd_pc = _FALSE;
5222 }
5223 }
5224 } else
5225 RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5226
5227 return ret;
5228
5229 }
5230
5231 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5232 struct iw_request_info *info,
5233 union iwreq_data *wrqu, char *extra)
5234 {
5235
5236 int ret = 0;
5237 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5238 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5239 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5240
5241 /* Commented by Albert 20120328 */
5242 /* The input data is 0 or 1 */
5243 /* 0: specify to Miracast source device */
5244 /* 1 or others: specify to Miracast sink device (display device) */
5245
5246 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5247
5248 if (extra[0] == '0') /* Set to Miracast source device. */
5249 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5250 else /* Set to Miracast sink device. */
5251 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5252
5253 return ret;
5254
5255 }
5256
5257 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
5258 struct iw_request_info *info,
5259 union iwreq_data *wrqu, char *extra)
5260 {
5261 /* Commented by Kurt 20121206
5262 * This function is used to set wfd enabled */
5263
5264 int ret = 0;
5265 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5266 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5267
5268 if (*extra == '0')
5269 rtw_wfd_enable(padapter, 0);
5270 else if (*extra == '1')
5271 rtw_wfd_enable(padapter, 1);
5272
5273 RTW_INFO("[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable);
5274
5275 return ret;
5276
5277 }
5278
5279 static int rtw_p2p_set_driver_iface(struct net_device *dev,
5280 struct iw_request_info *info,
5281 union iwreq_data *wrqu, char *extra)
5282 {
5283 /* Commented by Kurt 20121206
5284 * This function is used to set driver iface is WEXT or CFG80211 */
5285 int ret = 0;
5286 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5287 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5288
5289 if (*extra == '1') {
5290 pwdinfo->driver_interface = DRIVER_WEXT;
5291 RTW_INFO("[%s] driver_interface = WEXT\n", __FUNCTION__);
5292 } else if (*extra == '2') {
5293 pwdinfo->driver_interface = DRIVER_CFG80211;
5294 RTW_INFO("[%s] driver_interface = CFG80211\n", __FUNCTION__);
5295 }
5296
5297 return ret;
5298
5299 }
5300
5301 /* To set the WFD session available to enable or disable */
5302 static int rtw_p2p_set_sa(struct net_device *dev,
5303 struct iw_request_info *info,
5304 union iwreq_data *wrqu, char *extra)
5305 {
5306
5307 int ret = 0;
5308 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5309 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5310
5311 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5312
5313 if (0) {
5314 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5315 return ret;
5316 } else {
5317 if (extra[0] == '0') /* Disable the session available. */
5318 pwdinfo->session_available = _FALSE;
5319 else if (extra[0] == '1') /* Enable the session available. */
5320 pwdinfo->session_available = _TRUE;
5321 else
5322 pwdinfo->session_available = _FALSE;
5323 }
5324 printk("[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available);
5325
5326 return ret;
5327
5328 }
5329 #endif /* CONFIG_WFD */
5330
5331 static int rtw_p2p_prov_disc(struct net_device *dev,
5332 struct iw_request_info *info,
5333 union iwreq_data *wrqu, char *extra)
5334 {
5335 int ret = 0;
5336 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5337 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5338 u8 peerMAC[ETH_ALEN] = { 0x00 };
5339 int jj, kk;
5340 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5341 _list *plist, *phead;
5342 _queue *queue = &(pmlmepriv->scanned_queue);
5343 struct wlan_network *pnetwork = NULL;
5344 uint uintPeerChannel = 0;
5345 u8 attr_content[100] = { 0x00 };
5346 u8 *p2pie;
5347 uint p2pielen = 0, attr_contentlen = 100;
5348 _irqL irqL;
5349 #ifdef CONFIG_CONCURRENT_MODE
5350 struct roch_info *prochinfo = &padapter->rochinfo;
5351 #endif
5352
5353 /* Commented by Albert 20110301 */
5354 /* The input data contains two informations. */
5355 /* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
5356 /* 2. Second information is the WPS configuration method which wants to discovery */
5357 /* Format: 00:E0:4C:00:00:05_display */
5358 /* Format: 00:E0:4C:00:00:05_keypad */
5359 /* Format: 00:E0:4C:00:00:05_pbc */
5360 /* Format: 00:E0:4C:00:00:05_label */
5361
5362 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5363
5364 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
5365 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5366 return ret;
5367 } else {
5368 /* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
5369 _rtw_memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
5370 _rtw_memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
5371 _rtw_memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(NDIS_802_11_SSID));
5372 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
5373 pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
5374 pwdinfo->tx_prov_disc_info.benable = _FALSE;
5375 }
5376
5377 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5378 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5379
5380 if (_rtw_memcmp(&extra[18], "display", 7))
5381 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
5382 else if (_rtw_memcmp(&extra[18], "keypad", 7))
5383 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
5384 else if (_rtw_memcmp(&extra[18], "pbc", 3))
5385 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
5386 else if (_rtw_memcmp(&extra[18], "label", 5))
5387 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
5388 else {
5389 RTW_INFO("[%s] Unknown WPS config methodn", __FUNCTION__);
5390 return ret ;
5391 }
5392
5393 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5394
5395 phead = get_list_head(queue);
5396 plist = get_next(phead);
5397
5398 while (1) {
5399 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5400 break;
5401
5402 if (uintPeerChannel != 0)
5403 break;
5404
5405 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5406
5407 /* Commented by Albert 2011/05/18 */
5408 /* Match the device address located in the P2P IE */
5409 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
5410
5411 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5412 if (p2pie) {
5413 while (p2pie) {
5414 /* The P2P Device ID attribute is included in the Beacon frame. */
5415 /* The P2P Device Info attribute is included in the probe response frame. */
5416 attr_contentlen = sizeof(attr_content);
5417 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5418 /* Handle the P2P Device ID attribute of Beacon first */
5419 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5420 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5421 break;
5422 }
5423 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5424 /* Handle the P2P Device Info attribute of probe response */
5425 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5426 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5427 break;
5428 }
5429 }
5430
5431 /* Get the next P2P IE */
5432 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5433 }
5434
5435 }
5436
5437 plist = get_next(plist);
5438
5439 }
5440
5441 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5442
5443 if (uintPeerChannel) {
5444 #ifdef CONFIG_WFD
5445 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5446 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5447 u8 *wfd_ie;
5448 uint wfd_ielen = 0;
5449
5450 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5451 if (wfd_ie) {
5452 u8 *wfd_devinfo;
5453 uint wfd_devlen;
5454
5455 RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5456 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5457 if (wfd_devinfo) {
5458 u16 wfd_devinfo_field = 0;
5459
5460 /* Commented by Albert 20120319 */
5461 /* The first two bytes are the WFD device information field of WFD device information subelement. */
5462 /* In big endian format. */
5463 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5464 if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
5465 pwfd_info->peer_session_avail = _TRUE;
5466 else
5467 pwfd_info->peer_session_avail = _FALSE;
5468 }
5469 }
5470
5471 if (_FALSE == pwfd_info->peer_session_avail) {
5472 RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
5473 goto exit;
5474 }
5475 }
5476 #endif /* CONFIG_WFD */
5477
5478 RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel);
5479 #ifdef CONFIG_CONCURRENT_MODE
5480 if (rtw_mi_check_status(padapter, MI_LINKED))
5481 _cancel_timer_ex(&prochinfo->ap_roch_ch_switch_timer);
5482 #endif /* CONFIG_CONCURRENT_MODE */
5483 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
5484 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
5485 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16) uintPeerChannel;
5486 pwdinfo->tx_prov_disc_info.benable = _TRUE;
5487 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5488 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
5489
5490 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
5491 _rtw_memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));
5492 else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5493 _rtw_memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
5494 pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
5495 }
5496
5497 #ifdef CONFIG_CONCURRENT_MODE
5498 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5499 u8 union_ch = rtw_mi_get_union_chan(padapter);
5500 u8 union_bw = rtw_mi_get_union_bw(padapter);
5501 u8 union_offset = rtw_mi_get_union_offset(padapter);
5502
5503 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5504 rtw_leave_opch(padapter);
5505
5506 } else
5507 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5508 #else
5509 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5510 #endif
5511
5512 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5513
5514 #ifdef CONFIG_CONCURRENT_MODE
5515 if (rtw_mi_check_status(padapter, MI_LINKED))
5516 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT);
5517 else
5518 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
5519 #else
5520 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
5521 #endif /* CONFIG_CONCURRENT_MODE */
5522
5523 } else {
5524 RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5525 }
5526 exit:
5527
5528 return ret;
5529
5530 }
5531
5532 /* Added by Albert 20110328
5533 * This function is used to inform the driver the user had specified the pin code value or pbc
5534 * to application. */
5535
5536 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
5537 struct iw_request_info *info,
5538 union iwreq_data *wrqu, char *extra)
5539 {
5540
5541 int ret = 0;
5542 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5543 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5544
5545
5546 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5547 /* Added by Albert 20110328 */
5548 /* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
5549 /* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
5550 /* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
5551 /* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
5552
5553 if (*extra == '0')
5554 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5555 else if (*extra == '1')
5556 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
5557 else if (*extra == '2')
5558 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
5559 else if (*extra == '3')
5560 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
5561 else
5562 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5563
5564 return ret;
5565
5566 }
5567
5568 #endif /* CONFIG_P2P */
5569
5570 static int rtw_p2p_set(struct net_device *dev,
5571 struct iw_request_info *info,
5572 union iwreq_data *wrqu, char *extra)
5573 {
5574 int ret = 0;
5575 #ifdef CONFIG_P2P
5576 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5577
5578 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
5579
5580 if (_rtw_memcmp(extra, "enable=", 7))
5581 rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
5582 else if (_rtw_memcmp(extra, "setDN=", 6)) {
5583 wrqu->data.length -= 6;
5584 rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
5585 } else if (_rtw_memcmp(extra, "profilefound=", 13)) {
5586 wrqu->data.length -= 13;
5587 rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
5588 } else if (_rtw_memcmp(extra, "prov_disc=", 10)) {
5589 wrqu->data.length -= 10;
5590 rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
5591 } else if (_rtw_memcmp(extra, "nego=", 5)) {
5592 wrqu->data.length -= 5;
5593 rtw_p2p_connect(dev, info, wrqu, &extra[5]);
5594 } else if (_rtw_memcmp(extra, "intent=", 7)) {
5595 /* Commented by Albert 2011/03/23 */
5596 /* The wrqu->data.length will include the null character */
5597 /* So, we will decrease 7 + 1 */
5598 wrqu->data.length -= 8;
5599 rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
5600 } else if (_rtw_memcmp(extra, "ssid=", 5)) {
5601 wrqu->data.length -= 5;
5602 rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
5603 } else if (_rtw_memcmp(extra, "got_wpsinfo=", 12)) {
5604 wrqu->data.length -= 12;
5605 rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
5606 } else if (_rtw_memcmp(extra, "listen_ch=", 10)) {
5607 /* Commented by Albert 2011/05/24 */
5608 /* The wrqu->data.length will include the null character */
5609 /* So, we will decrease (10 + 1) */
5610 wrqu->data.length -= 11;
5611 rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
5612 } else if (_rtw_memcmp(extra, "op_ch=", 6)) {
5613 /* Commented by Albert 2011/05/24 */
5614 /* The wrqu->data.length will include the null character */
5615 /* So, we will decrease (6 + 1) */
5616 wrqu->data.length -= 7;
5617 rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
5618 } else if (_rtw_memcmp(extra, "invite=", 7)) {
5619 wrqu->data.length -= 8;
5620 rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
5621 } else if (_rtw_memcmp(extra, "persistent=", 11)) {
5622 wrqu->data.length -= 11;
5623 rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
5624 } else if (_rtw_memcmp(extra, "uuid=", 5)) {
5625 wrqu->data.length -= 5;
5626 ret = rtw_p2p_set_wps_uuid(dev, info, wrqu, &extra[5]);
5627 }
5628
5629 #ifdef CONFIG_WFD
5630 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5631 if (_rtw_memcmp(extra, "sa=", 3)) {
5632 /* sa: WFD Session Available information */
5633 wrqu->data.length -= 3;
5634 rtw_p2p_set_sa(dev, info, wrqu, &extra[3]);
5635 } else if (_rtw_memcmp(extra, "pc=", 3)) {
5636 /* pc: WFD Preferred Connection */
5637 wrqu->data.length -= 3;
5638 rtw_p2p_set_pc(dev, info, wrqu, &extra[3]);
5639 } else if (_rtw_memcmp(extra, "wfd_type=", 9)) {
5640 wrqu->data.length -= 9;
5641 rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]);
5642 } else if (_rtw_memcmp(extra, "wfd_enable=", 11)) {
5643 wrqu->data.length -= 11;
5644 rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]);
5645 } else if (_rtw_memcmp(extra, "driver_iface=", 13)) {
5646 wrqu->data.length -= 13;
5647 rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]);
5648 }
5649 }
5650 #endif /* CONFIG_WFD */
5651
5652 #endif /* CONFIG_P2P */
5653
5654 return ret;
5655
5656 }
5657
5658 static int rtw_p2p_get(struct net_device *dev,
5659 struct iw_request_info *info,
5660 union iwreq_data *wrqu, char *extra)
5661 {
5662 int ret = 0;
5663 #ifdef CONFIG_P2P
5664 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5665
5666 if (padapter->bShowGetP2PState)
5667 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
5668
5669 if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
5670 rtw_p2p_get_status(dev, info, wrqu, extra);
5671 else if (_rtw_memcmp(wrqu->data.pointer, "role", 4))
5672 rtw_p2p_get_role(dev, info, wrqu, extra);
5673 else if (_rtw_memcmp(wrqu->data.pointer, "peer_ifa", 8))
5674 rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
5675 else if (_rtw_memcmp(wrqu->data.pointer, "req_cm", 6))
5676 rtw_p2p_get_req_cm(dev, info, wrqu, extra);
5677 else if (_rtw_memcmp(wrqu->data.pointer, "peer_deva", 9)) {
5678 /* Get the P2P device address when receiving the provision discovery request frame. */
5679 rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
5680 } else if (_rtw_memcmp(wrqu->data.pointer, "group_id", 8))
5681 rtw_p2p_get_groupid(dev, info, wrqu, extra);
5682 else if (_rtw_memcmp(wrqu->data.pointer, "inv_peer_deva", 13)) {
5683 /* Get the P2P device address when receiving the P2P Invitation request frame. */
5684 rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
5685 } else if (_rtw_memcmp(wrqu->data.pointer, "op_ch", 5))
5686 rtw_p2p_get_op_ch(dev, info, wrqu, extra);
5687
5688 #ifdef CONFIG_WFD
5689 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5690 if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9))
5691 rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra);
5692 else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6))
5693 rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra);
5694 else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6))
5695 rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra);
5696 }
5697 #endif /* CONFIG_WFD */
5698
5699 #endif /* CONFIG_P2P */
5700
5701 return ret;
5702
5703 }
5704
5705 static int rtw_p2p_get2(struct net_device *dev,
5706 struct iw_request_info *info,
5707 union iwreq_data *wrqu, char *extra)
5708 {
5709
5710 int ret = 0;
5711
5712 #ifdef CONFIG_P2P
5713
5714 int length = wrqu->data.length;
5715 char *buffer = (u8 *)rtw_malloc(length);
5716
5717 if (buffer == NULL) {
5718 ret = -ENOMEM;
5719 goto bad;
5720 }
5721
5722 if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) {
5723 ret = -EFAULT;
5724 goto bad;
5725 }
5726
5727 RTW_INFO("[%s] buffer = %s\n", __FUNCTION__, buffer);
5728
5729 if (_rtw_memcmp(buffer, "wpsCM=", 6))
5730 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
5731 else if (_rtw_memcmp(buffer, "devN=", 5))
5732 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
5733 else if (_rtw_memcmp(buffer, "dev_type=", 9))
5734 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
5735 else if (_rtw_memcmp(buffer, "go_devadd=", 10))
5736 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
5737 else if (_rtw_memcmp(buffer, "InvProc=", 8))
5738 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
5739 else {
5740 snprintf(extra, sizeof("Command not found."), "Command not found.");
5741 wrqu->data.length = strlen(extra);
5742 }
5743
5744 bad:
5745 if (buffer)
5746 rtw_mfree(buffer, length);
5747
5748 #endif /* CONFIG_P2P */
5749
5750 return ret;
5751
5752 }
5753
5754 #ifdef CONFIG_MP_INCLUDED
5755 static int rtw_cta_test_start(struct net_device *dev,
5756 struct iw_request_info *info,
5757 union iwreq_data *wrqu, char *extra)
5758 {
5759 int ret = 0;
5760 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5761 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
5762
5763 RTW_INFO("%s %s\n", __func__, extra);
5764 if (!strcmp(extra, "1"))
5765 hal_data->in_cta_test = 1;
5766 else
5767 hal_data->in_cta_test = 0;
5768
5769 rtw_hal_rcr_set_chk_bssid(padapter, MLME_ACTION_NONE);
5770
5771 return ret;
5772 }
5773 #endif
5774
5775 #ifdef CONFIG_IOL
5776 #include <rtw_iol.h>
5777 #endif
5778 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
5779 #include "../../hal/hal_dm_acs.h"
5780 #endif
5781 #ifdef DBG_CMD_QUEUE
5782 u8 dump_cmd_id = 0;
5783 #endif
5784
5785 static int rtw_dbg_port(struct net_device *dev,
5786 struct iw_request_info *info,
5787 union iwreq_data *wrqu, char *extra)
5788 {
5789 int ret = 0;
5790 #ifdef CONFIG_RTW_DEBUG
5791 _irqL irqL;
5792 u8 major_cmd, minor_cmd;
5793 u16 arg;
5794 u32 extra_arg, *pdata, val32;
5795 struct sta_info *psta;
5796 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5797 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5798 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5799 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5800 struct security_priv *psecuritypriv = &padapter->securitypriv;
5801 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
5802 struct sta_priv *pstapriv = &padapter->stapriv;
5803
5804
5805 pdata = (u32 *)&wrqu->data;
5806
5807 val32 = *pdata;
5808 arg = (u16)(val32 & 0x0000ffff);
5809 major_cmd = (u8)(val32 >> 24);
5810 minor_cmd = (u8)((val32 >> 16) & 0x00ff);
5811
5812 extra_arg = *(pdata + 1);
5813
5814 switch (major_cmd) {
5815 case 0x70: /* read_reg */
5816 switch (minor_cmd) {
5817 case 1:
5818 RTW_INFO("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5819 break;
5820 case 2:
5821 RTW_INFO("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5822 break;
5823 case 4:
5824 RTW_INFO("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5825 break;
5826 }
5827 break;
5828 case 0x71: /* write_reg */
5829 switch (minor_cmd) {
5830 case 1:
5831 rtw_write8(padapter, arg, extra_arg);
5832 RTW_INFO("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5833 break;
5834 case 2:
5835 rtw_write16(padapter, arg, extra_arg);
5836 RTW_INFO("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5837 break;
5838 case 4:
5839 rtw_write32(padapter, arg, extra_arg);
5840 RTW_INFO("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5841 break;
5842 }
5843 break;
5844 case 0x72: /* read_bb */
5845 RTW_INFO("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5846 break;
5847 case 0x73: /* write_bb */
5848 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
5849 RTW_INFO("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5850 break;
5851 case 0x74: /* read_rf */
5852 RTW_INFO("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));
5853 break;
5854 case 0x75: /* write_rf */
5855 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
5856 RTW_INFO("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));
5857 break;
5858
5859 case 0x76:
5860 switch (minor_cmd) {
5861 case 0x00: /* normal mode, */
5862 padapter->recvpriv.is_signal_dbg = 0;
5863 break;
5864 case 0x01: /* dbg mode */
5865 padapter->recvpriv.is_signal_dbg = 1;
5866 extra_arg = extra_arg > 100 ? 100 : extra_arg;
5867 padapter->recvpriv.signal_strength_dbg = extra_arg;
5868 break;
5869 }
5870 break;
5871 case 0x78: /* IOL test */
5872 switch (minor_cmd) {
5873 #ifdef CONFIG_IOL
5874 case 0x04: { /* LLT table initialization test */
5875 u8 page_boundary = 0xf9;
5876 {
5877 struct xmit_frame *xmit_frame;
5878
5879 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5880 if (xmit_frame == NULL) {
5881 ret = -ENOMEM;
5882 break;
5883 }
5884
5885 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
5886
5887
5888 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))
5889 ret = -EPERM;
5890 }
5891 }
5892 break;
5893 case 0x05: { /* blink LED test */
5894 u16 reg = 0x4c;
5895 u32 blink_num = 50;
5896 u32 blink_delay_ms = 200;
5897 int i;
5898
5899 {
5900 struct xmit_frame *xmit_frame;
5901
5902 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5903 if (xmit_frame == NULL) {
5904 ret = -ENOMEM;
5905 break;
5906 }
5907
5908 for (i = 0; i < blink_num; i++) {
5909 #ifdef CONFIG_IOL_NEW_GENERATION
5910 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
5911 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5912 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
5913 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5914 #else
5915 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
5916 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5917 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
5918 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5919 #endif
5920 }
5921 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0))
5922 ret = -EPERM;
5923 }
5924 }
5925 break;
5926
5927 case 0x06: { /* continuous wirte byte test */
5928 u16 reg = arg;
5929 u16 start_value = 0;
5930 u32 write_num = extra_arg;
5931 int i;
5932 u8 final;
5933
5934 {
5935 struct xmit_frame *xmit_frame;
5936
5937 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5938 if (xmit_frame == NULL) {
5939 ret = -ENOMEM;
5940 break;
5941 }
5942
5943 for (i = 0; i < write_num; i++) {
5944 #ifdef CONFIG_IOL_NEW_GENERATION
5945 rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
5946 #else
5947 rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value);
5948 #endif
5949 }
5950 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
5951 ret = -EPERM;
5952 }
5953
5954 final = rtw_read8(padapter, reg);
5955 if (start_value + write_num - 1 == final)
5956 RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
5957 else
5958 RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
5959 }
5960 break;
5961
5962 case 0x07: { /* continuous wirte word test */
5963 u16 reg = arg;
5964 u16 start_value = 200;
5965 u32 write_num = extra_arg;
5966
5967 int i;
5968 u16 final;
5969
5970 {
5971 struct xmit_frame *xmit_frame;
5972
5973 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5974 if (xmit_frame == NULL) {
5975 ret = -ENOMEM;
5976 break;
5977 }
5978
5979 for (i = 0; i < write_num; i++) {
5980 #ifdef CONFIG_IOL_NEW_GENERATION
5981 rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
5982 #else
5983 rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value);
5984 #endif
5985 }
5986 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
5987 ret = -EPERM;
5988 }
5989
5990 final = rtw_read16(padapter, reg);
5991 if (start_value + write_num - 1 == final)
5992 RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
5993 else
5994 RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
5995 }
5996 break;
5997
5998 case 0x08: { /* continuous wirte dword test */
5999 u16 reg = arg;
6000 u32 start_value = 0x110000c7;
6001 u32 write_num = extra_arg;
6002
6003 int i;
6004 u32 final;
6005
6006 {
6007 struct xmit_frame *xmit_frame;
6008
6009 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6010 if (xmit_frame == NULL) {
6011 ret = -ENOMEM;
6012 break;
6013 }
6014
6015 for (i = 0; i < write_num; i++) {
6016 #ifdef CONFIG_IOL_NEW_GENERATION
6017 rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
6018 #else
6019 rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value);
6020 #endif
6021 }
6022 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6023 ret = -EPERM;
6024
6025 }
6026
6027 final = rtw_read32(padapter, reg);
6028 if (start_value + write_num - 1 == final)
6029 RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6030 else
6031 RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6032 }
6033 break;
6034 #endif /* CONFIG_IOL */
6035 }
6036 break;
6037 case 0x79: {
6038 /*
6039 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
6040 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
6041 */
6042 u8 value = extra_arg & 0x0f;
6043 u8 sign = minor_cmd;
6044 u16 write_value = 0;
6045
6046 RTW_INFO("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
6047
6048 if (sign)
6049 value = value | 0x10;
6050
6051 write_value = value | (value << 5);
6052 rtw_write16(padapter, 0x6d9, write_value);
6053 }
6054 break;
6055 case 0x7a:
6056 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
6057 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
6058 break;
6059 case 0x7F:
6060 switch (minor_cmd) {
6061 case 0x0:
6062 RTW_INFO("fwstate=0x%x\n", get_fwstate(pmlmepriv));
6063 break;
6064 case 0x01:
6065 RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
6066 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
6067 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
6068 break;
6069 case 0x03:
6070 RTW_INFO("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
6071 #ifdef CONFIG_80211N_HT
6072 RTW_INFO("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
6073 #endif /* CONFIG_80211N_HT */
6074 break;
6075 case 0x04:
6076 RTW_INFO("cur_ch=%d\n", pmlmeext->cur_channel);
6077 RTW_INFO("cur_bw=%d\n", pmlmeext->cur_bwmode);
6078 RTW_INFO("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
6079
6080 RTW_INFO("oper_ch=%d\n", rtw_get_oper_ch(padapter));
6081 RTW_INFO("oper_bw=%d\n", rtw_get_oper_bw(padapter));
6082 RTW_INFO("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
6083
6084 break;
6085 case 0x05:
6086 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
6087 if (psta) {
6088 RTW_INFO("SSID=%s\n", cur_network->network.Ssid.Ssid);
6089 RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
6090 RTW_INFO("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
6091 RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6092 RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",
6093 psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);
6094 #ifdef CONFIG_80211N_HT
6095 RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6096 RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n"
6097 , psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
6098 RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6099 RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6100 #endif /* CONFIG_80211N_HT */
6101
6102 sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6103 } else
6104 RTW_INFO("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
6105 break;
6106 case 0x06: {
6107 u64 tsf = 0;
6108
6109 tsf = rtw_hal_get_tsftr_by_port(padapter, extra_arg);
6110 RTW_INFO(" PORT-%d TSF :%21lld\n", extra_arg, tsf);
6111 }
6112 break;
6113 case 0x07:
6114 RTW_INFO("bSurpriseRemoved=%s, bDriverStopped=%s\n"
6115 , rtw_is_surprise_removed(padapter) ? "True" : "False"
6116 , rtw_is_drv_stopped(padapter) ? "True" : "False");
6117 break;
6118 case 0x08: {
6119 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6120 struct recv_priv *precvpriv = &padapter->recvpriv;
6121
6122 RTW_INFO("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
6123 ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
6124 ", free_recvframe_cnt=%d\n",
6125 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
6126 pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
6127 precvpriv->free_recvframe_cnt);
6128 #ifdef CONFIG_USB_HCI
6129 RTW_INFO("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt)));
6130 #endif
6131 }
6132 break;
6133 case 0x09: {
6134 int i;
6135 _list *plist, *phead;
6136
6137 #ifdef CONFIG_AP_MODE
6138 RTW_INFO_DUMP("sta_dz_bitmap:", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len);
6139 RTW_INFO_DUMP("tim_bitmap:", pstapriv->tim_bitmap, pstapriv->aid_bmp_len);
6140 #endif
6141 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6142
6143 for (i = 0; i < NUM_STA; i++) {
6144 phead = &(pstapriv->sta_hash[i]);
6145 plist = get_next(phead);
6146
6147 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
6148 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
6149
6150 plist = get_next(plist);
6151
6152 if (extra_arg == psta->cmn.aid) {
6153 RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
6154 RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6155 RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",
6156 psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);
6157 #ifdef CONFIG_80211N_HT
6158 RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6159 RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n",
6160 psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m,
6161 psta->htpriv.sgi_40m);
6162 RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6163 RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6164 #endif /* CONFIG_80211N_HT */
6165
6166 #ifdef CONFIG_AP_MODE
6167 RTW_INFO("capability=0x%x\n", psta->capability);
6168 RTW_INFO("flags=0x%x\n", psta->flags);
6169 RTW_INFO("wpa_psk=0x%x\n", psta->wpa_psk);
6170 RTW_INFO("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
6171 RTW_INFO("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
6172 RTW_INFO("qos_info=0x%x\n", psta->qos_info);
6173 #endif
6174 RTW_INFO("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
6175
6176 sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6177 }
6178
6179 }
6180 }
6181
6182 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6183
6184 }
6185 break;
6186
6187 case 0x0b: { /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6188 /* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6189 /* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
6190
6191 if (arg == 0) {
6192 RTW_INFO("disable driver ctrl vcs\n");
6193 padapter->driver_vcs_en = 0;
6194 } else if (arg == 1) {
6195 RTW_INFO("enable driver ctrl vcs = %d\n", extra_arg);
6196 padapter->driver_vcs_en = 1;
6197
6198 if (extra_arg > 2)
6199 padapter->driver_vcs_type = 1;
6200 else
6201 padapter->driver_vcs_type = extra_arg;
6202 }
6203 }
6204 break;
6205 case 0x0c: { /* dump rx/tx packet */
6206 if (arg == 0) {
6207 RTW_INFO("dump rx packet (%d)\n", extra_arg);
6208 /* pHalData->bDumpRxPkt =extra_arg; */
6209 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
6210 } else if (arg == 1) {
6211 RTW_INFO("dump tx packet (%d)\n", extra_arg);
6212 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
6213 }
6214 }
6215 break;
6216 case 0x0e: {
6217 if (arg == 0) {
6218 RTW_INFO("disable driver ctrl rx_ampdu_factor\n");
6219 padapter->driver_rx_ampdu_factor = 0xFF;
6220 } else if (arg == 1) {
6221
6222 RTW_INFO("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
6223
6224 if (extra_arg > 0x03)
6225 padapter->driver_rx_ampdu_factor = 0xFF;
6226 else
6227 padapter->driver_rx_ampdu_factor = extra_arg;
6228 }
6229 }
6230 break;
6231 #ifdef DBG_CONFIG_ERROR_DETECT
6232 case 0x0f: {
6233 if (extra_arg == 0) {
6234 RTW_INFO("###### silent reset test.......#####\n");
6235 rtw_hal_sreset_reset(padapter);
6236 } else {
6237 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
6238 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
6239 psrtpriv->dbg_trigger_point = extra_arg;
6240 }
6241
6242 }
6243 break;
6244 case 0x15: {
6245 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6246 RTW_INFO("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
6247 }
6248 break;
6249
6250 #endif
6251
6252 case 0x10: /* driver version display */
6253 dump_drv_version(RTW_DBGDUMP);
6254 break;
6255 case 0x11: { /* dump linked status */
6256 int pre_mode;
6257 pre_mode = padapter->bLinkInfoDump;
6258 /* linked_info_dump(padapter,extra_arg); */
6259 if (extra_arg == 1 || (extra_arg == 0 && pre_mode == 1)) /* not consider pwr_saving 0: */
6260 padapter->bLinkInfoDump = extra_arg;
6261
6262 else if ((extra_arg == 2) || (extra_arg == 0 && pre_mode == 2)) { /* consider power_saving */
6263 /* RTW_INFO("linked_info_dump =%s\n", (padapter->bLinkInfoDump)?"enable":"disable") */
6264 linked_info_dump(padapter, extra_arg);
6265 }
6266
6267
6268
6269 }
6270 break;
6271 #ifdef CONFIG_80211N_HT
6272 case 0x12: { /* set rx_stbc */
6273 struct registry_priv *pregpriv = &padapter->registrypriv;
6274 /* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
6275 /* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
6276 if (pregpriv && (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3)) {
6277 pregpriv->rx_stbc = extra_arg;
6278 RTW_INFO("set rx_stbc=%d\n", pregpriv->rx_stbc);
6279 } else
6280 RTW_INFO("get rx_stbc=%d\n", pregpriv->rx_stbc);
6281
6282 }
6283 break;
6284 case 0x13: { /* set ampdu_enable */
6285 struct registry_priv *pregpriv = &padapter->registrypriv;
6286 /* 0: disable, 0x1:enable */
6287 if (pregpriv && extra_arg < 2) {
6288 pregpriv->ampdu_enable = extra_arg;
6289 RTW_INFO("set ampdu_enable=%d\n", pregpriv->ampdu_enable);
6290 } else
6291 RTW_INFO("get ampdu_enable=%d\n", pregpriv->ampdu_enable);
6292
6293 }
6294 break;
6295 #endif
6296 case 0x14: { /* get wifi_spec */
6297 struct registry_priv *pregpriv = &padapter->registrypriv;
6298 RTW_INFO("get wifi_spec=%d\n", pregpriv->wifi_spec);
6299
6300 }
6301 break;
6302
6303 #ifdef DBG_FIXED_CHAN
6304 case 0x17: {
6305 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6306 printk("===> Fixed channel to %d\n", extra_arg);
6307 pmlmeext->fixed_chan = extra_arg;
6308
6309 }
6310 break;
6311 #endif
6312 #ifdef CONFIG_80211N_HT
6313 case 0x19: {
6314 struct registry_priv *pregistrypriv = &padapter->registrypriv;
6315 /* extra_arg : */
6316 /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */
6317 /* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */
6318 if (arg == 0) {
6319 RTW_INFO("driver disable LDPC\n");
6320 pregistrypriv->ldpc_cap = 0x00;
6321 } else if (arg == 1) {
6322 RTW_INFO("driver set LDPC cap = 0x%x\n", extra_arg);
6323 pregistrypriv->ldpc_cap = (u8)(extra_arg & 0x33);
6324 }
6325 }
6326 break;
6327 case 0x1a: {
6328 struct registry_priv *pregistrypriv = &padapter->registrypriv;
6329 /* extra_arg : */
6330 /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */
6331 /* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */
6332 if (arg == 0) {
6333 RTW_INFO("driver disable STBC\n");
6334 pregistrypriv->stbc_cap = 0x00;
6335 } else if (arg == 1) {
6336 RTW_INFO("driver set STBC cap = 0x%x\n", extra_arg);
6337 pregistrypriv->stbc_cap = (u8)(extra_arg & 0x33);
6338 }
6339 }
6340 break;
6341 #endif /* CONFIG_80211N_HT */
6342 case 0x1b: {
6343 struct registry_priv *pregistrypriv = &padapter->registrypriv;
6344
6345 if (arg == 0) {
6346 RTW_INFO("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
6347 init_mlme_default_rate_set(padapter);
6348 #ifdef CONFIG_80211N_HT
6349 pregistrypriv->ht_enable = (u8)rtw_ht_enable;
6350 #endif /* CONFIG_80211N_HT */
6351 } else if (arg == 1) {
6352
6353 int i;
6354 u8 max_rx_rate;
6355
6356 RTW_INFO("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
6357
6358 max_rx_rate = (u8)extra_arg;
6359
6360 if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0->B or G -> disable HT */
6361 #ifdef CONFIG_80211N_HT
6362 pregistrypriv->ht_enable = 0;
6363 #endif /* CONFIG_80211N_HT */
6364 for (i = 0; i < NumRates; i++) {
6365 if (pmlmeext->datarate[i] > max_rx_rate)
6366 pmlmeext->datarate[i] = 0xff;
6367 }
6368
6369 }
6370 #ifdef CONFIG_80211N_HT
6371 else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */
6372 u32 mcs_bitmap = 0x0;
6373
6374 for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++)
6375 mcs_bitmap |= BIT(i);
6376
6377 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
6378 }
6379 #endif /* CONFIG_80211N_HT */
6380 }
6381 }
6382 break;
6383 case 0x1c: { /* enable/disable driver control AMPDU Density for peer sta's rx */
6384 if (arg == 0) {
6385 RTW_INFO("disable driver ctrl ampdu density\n");
6386 padapter->driver_ampdu_spacing = 0xFF;
6387 } else if (arg == 1) {
6388
6389 RTW_INFO("enable driver ctrl ampdu density = %d\n", extra_arg);
6390
6391 if (extra_arg > 0x07)
6392 padapter->driver_ampdu_spacing = 0xFF;
6393 else
6394 padapter->driver_ampdu_spacing = extra_arg;
6395 }
6396 }
6397 break;
6398 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
6399 case 0x1e: {
6400 RTW_INFO("===========================================\n");
6401 rtw_noise_measure_curchan(padapter);
6402 RTW_INFO("===========================================\n");
6403 }
6404 break;
6405 #endif
6406
6407
6408 #if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)
6409 case 0x1f:
6410 {
6411 int i, j = 0, test_cnts = 0;
6412 static u8 test_code = 0x5A;
6413 static u32 data_misatch_cnt = 0, d_acc_err_cnt = 0;
6414
6415 u32 d_data, i_data;
6416 u32 imr;
6417
6418 test_cnts = extra_arg;
6419 for (i = 0; i < test_cnts; i++) {
6420 if (RTW_CANNOT_IO(padapter))
6421 break;
6422
6423 rtw_write8(padapter, 0x07, test_code);
6424
6425 d_data = rtw_read32(padapter, 0x04);
6426 imr = rtw_read32(padapter, 0x10250014);
6427 rtw_write32(padapter, 0x10250014, 0);
6428 rtw_msleep_os(50);
6429
6430 i_data = rtw_sd_iread32(padapter, 0x04);
6431
6432 rtw_write32(padapter, 0x10250014, imr);
6433
6434 if (d_data != i_data) {
6435 data_misatch_cnt++;
6436 RTW_ERR("d_data :0x%08x, i_data : 0x%08x\n", d_data, i_data);
6437 }
6438
6439 if (test_code != (i_data >> 24)) {
6440 d_acc_err_cnt++;
6441 rtw_write8(padapter, 0x07, 0xAA);
6442 RTW_ERR("test_code :0x%02x, i_data : 0x%08x\n", test_code, i_data);
6443 }
6444 if ((j++) == 100) {
6445 rtw_msleep_os(2000);
6446 RTW_INFO(" Indirect access testing..........%d/%d\n", i, test_cnts);
6447 j = 0;
6448 }
6449
6450 test_code = ~test_code;
6451 rtw_msleep_os(50);
6452 }
6453 RTW_INFO("========Indirect access test=========\n");
6454 RTW_INFO(" test_cnts = %d\n", test_cnts);
6455 RTW_INFO(" direct & indirect read32 data missatch cnts = %d\n", data_misatch_cnt);
6456 RTW_INFO(" indirect rdata is not equal to wdata cnts = %d\n", d_acc_err_cnt);
6457 RTW_INFO("========Indirect access test=========\n\n");
6458 data_misatch_cnt = d_acc_err_cnt = 0;
6459
6460 }
6461 break;
6462 #endif
6463 case 0x20:
6464 {
6465 if (arg == 0xAA) {
6466 u8 page_offset, page_num;
6467
6468 page_offset = (u8)(extra_arg >> 16);
6469 page_num = (u8)(extra_arg & 0xFF);
6470 rtw_dump_rsvd_page(RTW_DBGDUMP, padapter, page_offset, page_num);
6471 }
6472 #ifdef CONFIG_SUPPORT_FIFO_DUMP
6473 else {
6474 u8 fifo_sel;
6475 u32 addr, size;
6476
6477 fifo_sel = (u8)(arg & 0x0F);
6478 addr = (extra_arg >> 16) & 0xFFFF;
6479 size = extra_arg & 0xFFFF;
6480 rtw_dump_fifo(RTW_DBGDUMP, padapter, fifo_sel, addr, size);
6481 }
6482 #endif
6483 }
6484 break;
6485
6486 case 0x23: {
6487 RTW_INFO("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
6488 padapter->bNotifyChannelChange = extra_arg;
6489 break;
6490 }
6491 case 0x24: {
6492 #ifdef CONFIG_P2P
6493 RTW_INFO("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
6494 padapter->bShowGetP2PState = extra_arg;
6495 #endif /* CONFIG_P2P */
6496 break;
6497 }
6498 #ifdef CONFIG_GPIO_API
6499 case 0x25: { /* Get GPIO register */
6500 /*
6501 * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
6502 */
6503
6504 u8 value;
6505 RTW_INFO("Read GPIO Value extra_arg = %d\n", extra_arg);
6506 value = rtw_hal_get_gpio(padapter, extra_arg);
6507 RTW_INFO("Read GPIO Value = %d\n", value);
6508 break;
6509 }
6510 case 0x26: { /* Set GPIO direction */
6511
6512 /* dbg 0x7f26000x [y], Set gpio direction,
6513 * x: gpio_num,4~7 y: indicate direction, 0~1
6514 */
6515
6516 int value;
6517 RTW_INFO("Set GPIO Direction! arg = %d ,extra_arg=%d\n", arg , extra_arg);
6518 value = rtw_hal_config_gpio(padapter, arg, extra_arg);
6519 RTW_INFO("Set GPIO Direction %s\n", (value == -1) ? "Fail!!!" : "Success");
6520 break;
6521 }
6522 case 0x27: { /* Set GPIO output direction value */
6523 /*
6524 * dbg 0x7f27000x [y], Set gpio output direction value,
6525 * x: gpio_num,4~7 y: indicate direction, 0~1
6526 */
6527
6528 int value;
6529 RTW_INFO("Set GPIO Value! arg = %d ,extra_arg=%d\n", arg , extra_arg);
6530 value = rtw_hal_set_gpio_output_value(padapter, arg, extra_arg);
6531 RTW_INFO("Set GPIO Value %s\n", (value == -1) ? "Fail!!!" : "Success");
6532 break;
6533 }
6534 #endif
6535 #ifdef DBG_CMD_QUEUE
6536 case 0x28: {
6537 dump_cmd_id = extra_arg;
6538 RTW_INFO("dump_cmd_id:%d\n", dump_cmd_id);
6539 }
6540 break;
6541 #endif /* DBG_CMD_QUEUE */
6542 case 0xaa: {
6543 if ((extra_arg & 0x7F) > 0x3F)
6544 extra_arg = 0xFF;
6545 RTW_INFO("chang data rate to :0x%02x\n", extra_arg);
6546 padapter->fix_rate = extra_arg;
6547 }
6548 break;
6549 case 0xdd: { /* registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg */
6550 if (extra_arg == 0)
6551 mac_reg_dump(RTW_DBGDUMP, padapter);
6552 else if (extra_arg == 1)
6553 bb_reg_dump(RTW_DBGDUMP, padapter);
6554 else if (extra_arg == 2)
6555 rf_reg_dump(RTW_DBGDUMP, padapter);
6556 else if (extra_arg == 11)
6557 bb_reg_dump_ex(RTW_DBGDUMP, padapter);
6558 }
6559 break;
6560
6561 case 0xee: {
6562 RTW_INFO(" === please control /proc to trun on/off PHYDM func ===\n");
6563 }
6564 break;
6565
6566 case 0xfd:
6567 rtw_write8(padapter, 0xc50, arg);
6568 RTW_INFO("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6569 rtw_write8(padapter, 0xc58, arg);
6570 RTW_INFO("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6571 break;
6572 case 0xfe:
6573 RTW_INFO("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6574 RTW_INFO("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6575 break;
6576 case 0xff: {
6577 RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
6578 RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
6579 RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
6580 RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
6581 RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
6582
6583 RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
6584
6585
6586 RTW_INFO("\n");
6587
6588 RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
6589 RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
6590
6591 RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
6592
6593 RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
6594
6595 RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
6596 RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
6597
6598 RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
6599 RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
6600 RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
6601 RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
6602 }
6603 break;
6604 }
6605 break;
6606 default:
6607 RTW_INFO("error dbg cmd!\n");
6608 break;
6609 }
6610
6611 #endif
6612 return ret;
6613
6614 }
6615
6616 #ifdef CONFIG_IOCTL_WEXT
6617 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
6618 {
6619 uint ret = 0;
6620 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6621
6622 switch (name) {
6623 case IEEE_PARAM_WPA_ENABLED:
6624
6625 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
6626
6627 /* ret = ieee80211_wpa_enable(ieee, value); */
6628
6629 switch ((value) & 0xff) {
6630 case 1: /* WPA */
6631 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
6632 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
6633 break;
6634 case 2: /* WPA2 */
6635 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
6636 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
6637 break;
6638 }
6639
6640
6641 break;
6642
6643 case IEEE_PARAM_TKIP_COUNTERMEASURES:
6644 /* ieee->tkip_countermeasures=value; */
6645 break;
6646
6647 case IEEE_PARAM_DROP_UNENCRYPTED: {
6648 /* HACK:
6649 *
6650 * wpa_supplicant calls set_wpa_enabled when the driver
6651 * is loaded and unloaded, regardless of if WPA is being
6652 * used. No other calls are made which can be used to
6653 * determine if encryption will be used or not prior to
6654 * association being expected. If encryption is not being
6655 * used, drop_unencrypted is set to false, else true -- we
6656 * can use this to determine if the CAP_PRIVACY_ON bit should
6657 * be set.
6658 */
6659
6660 #if 0
6661 struct ieee80211_security sec = {
6662 .flags = SEC_ENABLED,
6663 .enabled = value,
6664 };
6665 ieee->drop_unencrypted = value;
6666 /* We only change SEC_LEVEL for open mode. Others
6667 * are set by ipw_wpa_set_encryption.
6668 */
6669 if (!value) {
6670 sec.flags |= SEC_LEVEL;
6671 sec.level = SEC_LEVEL_0;
6672 } else {
6673 sec.flags |= SEC_LEVEL;
6674 sec.level = SEC_LEVEL_1;
6675 }
6676 if (ieee->set_security)
6677 ieee->set_security(ieee->dev, &sec);
6678 #endif
6679 break;
6680
6681 }
6682 case IEEE_PARAM_PRIVACY_INVOKED:
6683
6684 /* ieee->privacy_invoked=value; */
6685
6686 break;
6687
6688 case IEEE_PARAM_AUTH_ALGS:
6689
6690 ret = wpa_set_auth_algs(dev, value);
6691
6692 break;
6693
6694 case IEEE_PARAM_IEEE_802_1X:
6695
6696 /* ieee->ieee802_1x=value; */
6697
6698 break;
6699
6700 case IEEE_PARAM_WPAX_SELECT:
6701
6702 /* added for WPA2 mixed mode */
6703 /*RTW_WARN("------------------------>wpax value = %x\n", value);*/
6704 /*
6705 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
6706 ieee->wpax_type_set = 1;
6707 ieee->wpax_type_notify = value;
6708 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
6709 */
6710
6711 break;
6712
6713 default:
6714
6715
6716
6717 ret = -EOPNOTSUPP;
6718
6719
6720 break;
6721
6722 }
6723
6724 return ret;
6725
6726 }
6727
6728 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
6729 {
6730 int ret = 0;
6731 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6732
6733 switch (command) {
6734 case IEEE_MLME_STA_DEAUTH:
6735
6736 if (!rtw_set_802_11_disassociate(padapter))
6737 ret = -1;
6738
6739 break;
6740
6741 case IEEE_MLME_STA_DISASSOC:
6742
6743 if (!rtw_set_802_11_disassociate(padapter))
6744 ret = -1;
6745
6746 break;
6747
6748 default:
6749 ret = -EOPNOTSUPP;
6750 break;
6751 }
6752 #ifdef CONFIG_RTW_REPEATER_SON
6753 rtw_rson_do_disconnect(padapter);
6754 #endif
6755 return ret;
6756
6757 }
6758
6759 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
6760 {
6761 struct ieee_param *param;
6762 uint ret = 0;
6763
6764 /* down(&ieee->wx_sem); */
6765
6766 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
6767 ret = -EINVAL;
6768 goto out;
6769 }
6770
6771 param = (struct ieee_param *)rtw_malloc(p->length);
6772 if (param == NULL) {
6773 ret = -ENOMEM;
6774 goto out;
6775 }
6776
6777 if (copy_from_user(param, p->pointer, p->length)) {
6778 rtw_mfree((u8 *)param, p->length);
6779 ret = -EFAULT;
6780 goto out;
6781 }
6782
6783 switch (param->cmd) {
6784
6785 case IEEE_CMD_SET_WPA_PARAM:
6786 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
6787 break;
6788
6789 case IEEE_CMD_SET_WPA_IE:
6790 /* ret = wpa_set_wpa_ie(dev, param, p->length); */
6791 ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
6792 break;
6793
6794 case IEEE_CMD_SET_ENCRYPTION:
6795 ret = wpa_set_encryption(dev, param, p->length);
6796 break;
6797
6798 case IEEE_CMD_MLME:
6799 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
6800 break;
6801
6802 default:
6803 RTW_INFO("Unknown WPA supplicant request: %d\n", param->cmd);
6804 ret = -EOPNOTSUPP;
6805 break;
6806
6807 }
6808
6809 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6810 ret = -EFAULT;
6811
6812 rtw_mfree((u8 *)param, p->length);
6813
6814 out:
6815
6816 /* up(&ieee->wx_sem); */
6817
6818 return ret;
6819
6820 }
6821
6822 #ifdef CONFIG_AP_MODE
6823 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
6824 {
6825 int ret = 0;
6826 u32 wep_key_idx, wep_key_len, wep_total_len;
6827 NDIS_802_11_WEP *pwep = NULL;
6828 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
6829 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6830 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6831 struct security_priv *psecuritypriv = &(padapter->securitypriv);
6832 struct sta_priv *pstapriv = &padapter->stapriv;
6833
6834 RTW_INFO("%s\n", __FUNCTION__);
6835
6836 param->u.crypt.err = 0;
6837 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
6838
6839 /* sizeof(struct ieee_param) = 64 bytes; */
6840 /* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
6841 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
6842 ret = -EINVAL;
6843 goto exit;
6844 }
6845
6846 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6847 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6848 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6849 if (param->u.crypt.idx >= WEP_KEYS
6850 #ifdef CONFIG_IEEE80211W
6851 && param->u.crypt.idx > BIP_MAX_KEYID
6852 #endif /* CONFIG_IEEE80211W */
6853 ) {
6854 ret = -EINVAL;
6855 goto exit;
6856 }
6857 } else {
6858 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
6859 if (!psta) {
6860 /* ret = -EINVAL; */
6861 RTW_INFO("rtw_set_encryption(), sta has already been removed or never been added\n");
6862 goto exit;
6863 }
6864 }
6865
6866 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
6867 /* todo:clear default encryption keys */
6868
6869 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
6870 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
6871 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
6872 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
6873
6874 RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
6875
6876 goto exit;
6877 }
6878
6879
6880 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
6881 RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
6882
6883 wep_key_idx = param->u.crypt.idx;
6884 wep_key_len = param->u.crypt.key_len;
6885
6886 RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
6887
6888 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
6889 ret = -EINVAL;
6890 goto exit;
6891 }
6892
6893
6894 if (wep_key_len > 0) {
6895 wep_key_len = wep_key_len <= 5 ? 5 : 13;
6896 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
6897 pwep = (NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
6898 if (pwep == NULL) {
6899 RTW_INFO(" r871x_set_encryption: pwep allocate fail !!!\n");
6900 goto exit;
6901 }
6902
6903 _rtw_memset(pwep, 0, wep_total_len);
6904
6905 pwep->KeyLength = wep_key_len;
6906 pwep->Length = wep_total_len;
6907
6908 }
6909
6910 pwep->KeyIndex = wep_key_idx;
6911
6912 _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
6913
6914 if (param->u.crypt.set_tx) {
6915 RTW_INFO("wep, set_tx=1\n");
6916
6917 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
6918 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
6919 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
6920 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6921
6922 if (pwep->KeyLength == 13) {
6923 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
6924 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
6925 }
6926
6927
6928 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
6929
6930 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6931
6932 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6933
6934 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
6935 } else {
6936 RTW_INFO("wep, set_tx=0\n");
6937
6938 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
6939 /* "psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam */
6940
6941 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6942
6943 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6944
6945 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
6946 }
6947
6948 goto exit;
6949
6950 }
6951
6952
6953 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* */ { /* group key */
6954 if (param->u.crypt.set_tx == 1) {
6955 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
6956 RTW_INFO(FUNC_ADPT_FMT" set WEP TX GTK idx:%u, len:%u\n"
6957 , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6958 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6959 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6960 if (param->u.crypt.key_len == 13)
6961 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
6962
6963 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
6964 RTW_INFO(FUNC_ADPT_FMT" set TKIP TX GTK idx:%u, len:%u\n"
6965 , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6966 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
6967 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6968 /* set mic key */
6969 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
6970 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
6971 psecuritypriv->busetkipkey = _TRUE;
6972
6973 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
6974 RTW_INFO(FUNC_ADPT_FMT" set CCMP TX GTK idx:%u, len:%u\n"
6975 , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6976 psecuritypriv->dot118021XGrpPrivacy = _AES_;
6977 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6978
6979 #ifdef CONFIG_IEEE80211W
6980 } else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
6981 RTW_INFO(FUNC_ADPT_FMT" set TX IGTK idx:%u, len:%u\n"
6982 , FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6983 _rtw_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));
6984 psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
6985 psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
6986 psecuritypriv->binstallBIPkey = _TRUE;
6987 goto exit;
6988 #endif /* CONFIG_IEEE80211W */
6989
6990 } else if (strcmp(param->u.crypt.alg, "none") == 0) {
6991 RTW_INFO(FUNC_ADPT_FMT" clear group key, idx:%u\n"
6992 , FUNC_ADPT_ARG(padapter), param->u.crypt.idx);
6993 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
6994 } else {
6995 RTW_WARN(FUNC_ADPT_FMT" set group key, not support\n"
6996 , FUNC_ADPT_ARG(padapter));
6997 goto exit;
6998 }
6999
7000 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7001 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7002 if (pbcmc_sta) {
7003 pbcmc_sta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
7004 pbcmc_sta->ieee8021x_blocked = _FALSE;
7005 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy */
7006 }
7007 psecuritypriv->binstallGrpkey = _TRUE;
7008 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
7009
7010 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7011 }
7012
7013 goto exit;
7014
7015 }
7016
7017 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
7018 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
7019 if (param->u.crypt.set_tx == 1) {
7020 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
7021
7022 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
7023 RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n"
7024 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7025 , param->u.crypt.idx, param->u.crypt.key_len);
7026 psta->dot118021XPrivacy = _WEP40_;
7027 if (param->u.crypt.key_len == 13)
7028 psta->dot118021XPrivacy = _WEP104_;
7029
7030 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7031 RTW_INFO(FUNC_ADPT_FMT" set TKIP PTK of "MAC_FMT" idx:%u, len:%u\n"
7032 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7033 , param->u.crypt.idx, param->u.crypt.key_len);
7034 psta->dot118021XPrivacy = _TKIP_;
7035 /* set mic key */
7036 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7037 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7038 psecuritypriv->busetkipkey = _TRUE;
7039
7040 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7041 RTW_INFO(FUNC_ADPT_FMT" set CCMP PTK of "MAC_FMT" idx:%u, len:%u\n"
7042 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7043 , param->u.crypt.idx, param->u.crypt.key_len);
7044 psta->dot118021XPrivacy = _AES_;
7045
7046 } else if (strcmp(param->u.crypt.alg, "none") == 0) {
7047 RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n"
7048 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7049 , param->u.crypt.idx);
7050 psta->dot118021XPrivacy = _NO_PRIVACY_;
7051
7052 } else {
7053 RTW_WARN(FUNC_ADPT_FMT" set pairwise key of "MAC_FMT", not support\n"
7054 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
7055 goto exit;
7056 }
7057
7058 psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
7059 psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
7060 psta->ieee8021x_blocked = _FALSE;
7061
7062 if (psta->dot118021XPrivacy != _NO_PRIVACY_) {
7063 psta->bpairwise_key_installed = _TRUE;
7064
7065 /* WPA2 key-handshake has completed */
7066 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
7067 psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
7068 }
7069
7070 rtw_ap_set_pairwise_key(padapter, psta);
7071 } else {
7072 RTW_WARN(FUNC_ADPT_FMT" set group key of "MAC_FMT", not support\n"
7073 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
7074 goto exit;
7075 }
7076
7077 }
7078
7079 }
7080
7081 exit:
7082
7083 if (pwep)
7084 rtw_mfree((u8 *)pwep, wep_total_len);
7085
7086 return ret;
7087
7088 }
7089
7090 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
7091 {
7092 int ret = 0;
7093 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7094 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7095 struct sta_priv *pstapriv = &padapter->stapriv;
7096 unsigned char *pbuf = param->u.bcn_ie.buf;
7097
7098
7099 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7100
7101 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7102 return -EINVAL;
7103
7104 _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
7105
7106 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
7107 pstapriv->max_num_sta = NUM_STA;
7108
7109
7110 if (rtw_check_beacon_data(padapter, pbuf, (len - 12 - 2)) == _SUCCESS) /* 12 = param header, 2:no packed */
7111 ret = 0;
7112 else
7113 ret = -EINVAL;
7114
7115
7116 return ret;
7117
7118 }
7119
7120 static int rtw_hostapd_sta_flush(struct net_device *dev)
7121 {
7122 /* _irqL irqL; */
7123 /* _list *phead, *plist; */
7124 int ret = 0;
7125 /* struct sta_info *psta = NULL; */
7126 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7127 /* struct sta_priv *pstapriv = &padapter->stapriv; */
7128
7129 RTW_INFO("%s\n", __FUNCTION__);
7130
7131 flush_all_cam_entry(padapter); /* clear CAM */
7132 #ifdef CONFIG_AP_MODE
7133 ret = rtw_sta_flush(padapter, _TRUE);
7134 #endif
7135 return ret;
7136
7137 }
7138
7139 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
7140 {
7141 int ret = 0;
7142 struct sta_info *psta = NULL;
7143 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7144 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7145 struct sta_priv *pstapriv = &padapter->stapriv;
7146
7147 RTW_INFO("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
7148
7149 if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7150 return -EINVAL;
7151
7152 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7153 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7154 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7155 return -EINVAL;
7156
7157 #if 0
7158 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7159 if (psta) {
7160 RTW_INFO("rtw_add_sta(), free has been added psta=%p\n", psta);
7161 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7162 rtw_free_stainfo(padapter, psta);
7163 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7164
7165 psta = NULL;
7166 }
7167 #endif
7168 /* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
7169 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7170 if (psta) {
7171 int flags = param->u.add_sta.flags;
7172
7173 /* RTW_INFO("rtw_add_sta(), init sta's variables, psta=%p\n", psta); */
7174
7175 psta->cmn.aid = param->u.add_sta.aid;/* aid=1~2007 */
7176
7177 _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
7178
7179
7180 /* check wmm cap. */
7181 if (WLAN_STA_WME & flags)
7182 psta->qos_option = 1;
7183 else
7184 psta->qos_option = 0;
7185
7186 if (pmlmepriv->qospriv.qos_option == 0)
7187 psta->qos_option = 0;
7188
7189
7190 #ifdef CONFIG_80211N_HT
7191 /* chec 802.11n ht cap. */
7192 if (padapter->registrypriv.ht_enable &&
7193 is_supported_ht(padapter->registrypriv.wireless_mode) &&
7194 (WLAN_STA_HT & flags)) {
7195 psta->htpriv.ht_option = _TRUE;
7196 psta->qos_option = 1;
7197 _rtw_memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7198 } else
7199 psta->htpriv.ht_option = _FALSE;
7200
7201 if (pmlmepriv->htpriv.ht_option == _FALSE)
7202 psta->htpriv.ht_option = _FALSE;
7203
7204 #endif
7205
7206
7207 update_sta_info_apmode(padapter, psta);
7208
7209
7210 } else
7211 ret = -ENOMEM;
7212
7213 return ret;
7214
7215 }
7216
7217 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
7218 {
7219 _irqL irqL;
7220 int ret = 0;
7221 struct sta_info *psta = NULL;
7222 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7223 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7224 struct sta_priv *pstapriv = &padapter->stapriv;
7225
7226 RTW_INFO("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
7227
7228 if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7229 return -EINVAL;
7230
7231 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7232 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7233 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7234 return -EINVAL;
7235
7236 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7237 if (psta) {
7238 u8 updated = _FALSE;
7239
7240 /* RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid); */
7241
7242 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7243 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
7244 rtw_list_delete(&psta->asoc_list);
7245 pstapriv->asoc_list_cnt--;
7246 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
7247 if (psta->tbtx_enable)
7248 pstapriv->tbtx_asoc_list_cnt--;
7249 #endif
7250 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
7251
7252 }
7253 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7254
7255 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
7256
7257 psta = NULL;
7258
7259 } else {
7260 RTW_INFO("rtw_del_sta(), sta has already been removed or never been added\n");
7261
7262 /* ret = -1; */
7263 }
7264
7265
7266 return ret;
7267
7268 }
7269
7270 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
7271 {
7272 int ret = 0;
7273 struct sta_info *psta = NULL;
7274 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7275 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7276 struct sta_priv *pstapriv = &padapter->stapriv;
7277 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
7278 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
7279
7280 RTW_INFO("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
7281
7282 if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7283 return -EINVAL;
7284
7285 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
7286 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
7287 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
7288 return -EINVAL;
7289
7290 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
7291 if (psta) {
7292 #if 0
7293 struct {
7294 u16 aid;
7295 u16 capability;
7296 int flags;
7297 u32 sta_set;
7298 u8 tx_supp_rates[16];
7299 u32 tx_supp_rates_len;
7300 struct rtw_ieee80211_ht_cap ht_cap;
7301 u64 rx_pkts;
7302 u64 rx_bytes;
7303 u64 rx_drops;
7304 u64 tx_pkts;
7305 u64 tx_bytes;
7306 u64 tx_drops;
7307 } get_sta;
7308 #endif
7309 psta_data->aid = (u16)psta->cmn.aid;
7310 psta_data->capability = psta->capability;
7311 psta_data->flags = psta->flags;
7312
7313 /*
7314 nonerp_set : BIT(0)
7315 no_short_slot_time_set : BIT(1)
7316 no_short_preamble_set : BIT(2)
7317 no_ht_gf_set : BIT(3)
7318 no_ht_set : BIT(4)
7319 ht_20mhz_set : BIT(5)
7320 */
7321
7322 psta_data->sta_set = ((psta->nonerp_set) |
7323 (psta->no_short_slot_time_set << 1) |
7324 (psta->no_short_preamble_set << 2) |
7325 (psta->no_ht_gf_set << 3) |
7326 (psta->no_ht_set << 4) |
7327 (psta->ht_20mhz_set << 5));
7328
7329 psta_data->tx_supp_rates_len = psta->bssratelen;
7330 _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
7331 #ifdef CONFIG_80211N_HT
7332 if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))
7333 _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7334 #endif /* CONFIG_80211N_HT */
7335 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
7336 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
7337 psta_data->rx_drops = psta->sta_stats.rx_drops;
7338
7339 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
7340 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
7341 psta_data->tx_drops = psta->sta_stats.tx_drops;
7342
7343
7344 } else
7345 ret = -1;
7346
7347 return ret;
7348
7349 }
7350
7351 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
7352 {
7353 int ret = 0;
7354 struct sta_info *psta = NULL;
7355 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7356 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7357 struct sta_priv *pstapriv = &padapter->stapriv;
7358
7359 RTW_INFO("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
7360
7361 if (check_fwstate(pmlmepriv, (WIFI_ASOC_STATE | WIFI_AP_STATE)) != _TRUE)
7362 return -EINVAL;
7363
7364 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7365 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7366 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7367 return -EINVAL;
7368
7369 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7370 if (psta) {
7371 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
7372 int wpa_ie_len;
7373 int copy_len;
7374
7375 wpa_ie_len = psta->wpa_ie[1];
7376
7377 copy_len = ((wpa_ie_len + 2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len + 2);
7378
7379 param->u.wpa_ie.len = copy_len;
7380
7381 _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
7382 } else {
7383 /* ret = -1; */
7384 RTW_INFO("sta's wpa_ie is NONE\n");
7385 }
7386 } else
7387 ret = -1;
7388
7389 return ret;
7390
7391 }
7392
7393 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
7394 {
7395 int ret = 0;
7396 unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
7397 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7398 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7399 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7400 int ie_len;
7401
7402 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7403
7404 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7405 return -EINVAL;
7406
7407 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7408
7409
7410 if (pmlmepriv->wps_beacon_ie) {
7411 rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7412 pmlmepriv->wps_beacon_ie = NULL;
7413 }
7414
7415 if (ie_len > 0) {
7416 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
7417 pmlmepriv->wps_beacon_ie_len = ie_len;
7418 if (pmlmepriv->wps_beacon_ie == NULL) {
7419 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7420 return -EINVAL;
7421 }
7422
7423 _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
7424
7425 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, 0);
7426
7427 pmlmeext->bstart_bss = _TRUE;
7428
7429 }
7430
7431
7432 return ret;
7433
7434 }
7435
7436 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
7437 {
7438 int ret = 0;
7439 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7440 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7441 int ie_len;
7442
7443 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7444
7445 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7446 return -EINVAL;
7447
7448 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7449
7450
7451 if (pmlmepriv->wps_probe_resp_ie) {
7452 rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
7453 pmlmepriv->wps_probe_resp_ie = NULL;
7454 }
7455
7456 if (ie_len > 0) {
7457 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
7458 pmlmepriv->wps_probe_resp_ie_len = ie_len;
7459 if (pmlmepriv->wps_probe_resp_ie == NULL) {
7460 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7461 return -EINVAL;
7462 }
7463 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
7464 }
7465
7466
7467 return ret;
7468
7469 }
7470
7471 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
7472 {
7473 int ret = 0;
7474 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7475 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7476 int ie_len;
7477
7478 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7479
7480 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7481 return -EINVAL;
7482
7483 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7484
7485
7486 if (pmlmepriv->wps_assoc_resp_ie) {
7487 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
7488 pmlmepriv->wps_assoc_resp_ie = NULL;
7489 }
7490
7491 if (ie_len > 0) {
7492 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
7493 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
7494 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
7495 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7496 return -EINVAL;
7497 }
7498
7499 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
7500 }
7501
7502
7503 return ret;
7504
7505 }
7506
7507 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
7508 {
7509 int ret = 0;
7510 _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
7511 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
7512 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
7513 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
7514 int ie_len;
7515 u8 *ssid_ie;
7516 char ssid[NDIS_802_11_LENGTH_SSID + 1];
7517 sint ssid_len = 0;
7518 u8 ignore_broadcast_ssid;
7519
7520 if (check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
7521 return -EPERM;
7522
7523 if (param->u.bcn_ie.reserved[0] != 0xea)
7524 return -EINVAL;
7525
7526 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
7527
7528 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7529 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
7530
7531 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
7532 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
7533 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
7534
7535 _rtw_memcpy(ssid, ssid_ie + 2, ssid_len);
7536 ssid[ssid_len] = 0x0;
7537
7538 if (0)
7539 RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7540 ssid, ssid_len,
7541 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7542 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7543
7544 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
7545 pbss_network->Ssid.SsidLength = ssid_len;
7546 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
7547 pbss_network_ext->Ssid.SsidLength = ssid_len;
7548
7549 if (0)
7550 RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7551 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7552 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7553 }
7554
7555 RTW_INFO(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
7556 ignore_broadcast_ssid, ssid, ssid_len);
7557
7558 return ret;
7559 }
7560
7561 #if CONFIG_RTW_MACADDR_ACL
7562 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
7563 {
7564 int ret = 0;
7565 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7566 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7567
7568 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7569 return -EINVAL;
7570
7571 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7572 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7573 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7574 return -EINVAL;
7575
7576 ret = rtw_acl_remove_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);
7577
7578 return ret;
7579
7580 }
7581
7582 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
7583 {
7584 int ret = 0;
7585 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7586 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7587
7588 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7589 return -EINVAL;
7590
7591 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7592 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7593 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7594 return -EINVAL;
7595
7596 ret = rtw_acl_add_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);
7597
7598 return ret;
7599
7600 }
7601
7602 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
7603 {
7604 int ret = 0;
7605 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7606 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7607
7608 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7609 return -EINVAL;
7610
7611 rtw_set_macaddr_acl(padapter, RTW_ACL_PERIOD_BSS, param->u.mlme.command);
7612
7613 return ret;
7614 }
7615 #endif /* CONFIG_RTW_MACADDR_ACL */
7616
7617 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
7618 {
7619 struct ieee_param *param;
7620 int ret = 0;
7621 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7622
7623 /* RTW_INFO("%s\n", __FUNCTION__); */
7624
7625 /*
7626 * this function is expect to call in master mode, which allows no power saving
7627 * so, we just check hw_init_completed
7628 */
7629
7630 if (!rtw_is_hw_init_completed(padapter)) {
7631 ret = -EPERM;
7632 goto out;
7633 }
7634
7635
7636 /* if (p->length < sizeof(struct ieee_param) || !p->pointer){ */
7637 if (!p->pointer) {
7638 ret = -EINVAL;
7639 goto out;
7640 }
7641
7642 param = (struct ieee_param *)rtw_malloc(p->length);
7643 if (param == NULL) {
7644 ret = -ENOMEM;
7645 goto out;
7646 }
7647
7648 if (copy_from_user(param, p->pointer, p->length)) {
7649 rtw_mfree((u8 *)param, p->length);
7650 ret = -EFAULT;
7651 goto out;
7652 }
7653
7654 /* RTW_INFO("%s, cmd=%d\n", __FUNCTION__, param->cmd); */
7655
7656 switch (param->cmd) {
7657 case RTL871X_HOSTAPD_FLUSH:
7658
7659 ret = rtw_hostapd_sta_flush(dev);
7660
7661 break;
7662
7663 case RTL871X_HOSTAPD_ADD_STA:
7664
7665 ret = rtw_add_sta(dev, param);
7666
7667 break;
7668
7669 case RTL871X_HOSTAPD_REMOVE_STA:
7670
7671 ret = rtw_del_sta(dev, param);
7672
7673 break;
7674
7675 case RTL871X_HOSTAPD_SET_BEACON:
7676
7677 ret = rtw_set_beacon(dev, param, p->length);
7678
7679 break;
7680
7681 case RTL871X_SET_ENCRYPTION:
7682
7683 ret = rtw_set_encryption(dev, param, p->length);
7684
7685 break;
7686
7687 case RTL871X_HOSTAPD_GET_WPAIE_STA:
7688
7689 ret = rtw_get_sta_wpaie(dev, param);
7690
7691 break;
7692
7693 case RTL871X_HOSTAPD_SET_WPS_BEACON:
7694
7695 ret = rtw_set_wps_beacon(dev, param, p->length);
7696
7697 break;
7698
7699 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
7700
7701 ret = rtw_set_wps_probe_resp(dev, param, p->length);
7702
7703 break;
7704
7705 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
7706
7707 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
7708
7709 break;
7710
7711 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
7712
7713 ret = rtw_set_hidden_ssid(dev, param, p->length);
7714
7715 break;
7716
7717 case RTL871X_HOSTAPD_GET_INFO_STA:
7718
7719 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
7720
7721 break;
7722
7723 #if CONFIG_RTW_MACADDR_ACL
7724 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
7725 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
7726 break;
7727 case RTL871X_HOSTAPD_ACL_ADD_STA:
7728 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
7729 break;
7730 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
7731 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
7732 break;
7733 #endif /* CONFIG_RTW_MACADDR_ACL */
7734
7735 default:
7736 RTW_INFO("Unknown hostapd request: %d\n", param->cmd);
7737 ret = -EOPNOTSUPP;
7738 break;
7739
7740 }
7741
7742 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7743 ret = -EFAULT;
7744
7745
7746 rtw_mfree((u8 *)param, p->length);
7747
7748 out:
7749
7750 return ret;
7751
7752 }
7753 #endif /* CONFIG_AP_MODE */
7754
7755 static int rtw_wx_set_priv(struct net_device *dev,
7756 struct iw_request_info *info,
7757 union iwreq_data *awrq,
7758 char *extra)
7759 {
7760
7761 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7762 char *ext_dbg;
7763 #endif
7764
7765 int ret = 0;
7766 int len = 0;
7767 char *ext;
7768 #ifdef CONFIG_RTW_ANDROID
7769 int i;
7770 #endif
7771
7772 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7773 struct iw_point *dwrq = (struct iw_point *)awrq;
7774
7775 if (dwrq->length == 0)
7776 return -EFAULT;
7777
7778 len = dwrq->length;
7779 ext = rtw_vmalloc(len);
7780 if (!ext)
7781 return -ENOMEM;
7782
7783 if (copy_from_user(ext, dwrq->pointer, len)) {
7784 rtw_vmfree(ext, len);
7785 return -EFAULT;
7786 }
7787
7788
7789
7790 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7791 ext_dbg = rtw_vmalloc(len);
7792 if (!ext_dbg) {
7793 rtw_vmfree(ext, len);
7794 return -ENOMEM;
7795 }
7796
7797 _rtw_memcpy(ext_dbg, ext, len);
7798 #endif
7799
7800 /* added for wps2.0 @20110524 */
7801 if (dwrq->flags == 0x8766 && len > 8) {
7802 u32 cp_sz;
7803 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7804 u8 *probereq_wpsie = ext;
7805 int probereq_wpsie_len = len;
7806 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
7807
7808 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
7809 (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) == _TRUE)) {
7810 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
7811
7812 if (pmlmepriv->wps_probe_req_ie) {
7813 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
7814 pmlmepriv->wps_probe_req_ie_len = 0;
7815 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
7816 pmlmepriv->wps_probe_req_ie = NULL;
7817 }
7818
7819 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
7820 if (pmlmepriv->wps_probe_req_ie == NULL) {
7821 printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7822 ret = -EINVAL;
7823 goto FREE_EXT;
7824
7825 }
7826
7827 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
7828 pmlmepriv->wps_probe_req_ie_len = cp_sz;
7829
7830 }
7831
7832 goto FREE_EXT;
7833
7834 }
7835
7836 if (len >= WEXT_CSCAN_HEADER_SIZE
7837 && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
7838 ) {
7839 ret = rtw_wx_set_scan(dev, info, awrq, ext);
7840 goto FREE_EXT;
7841 }
7842
7843 #ifdef CONFIG_RTW_ANDROID
7844 /* RTW_INFO("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); */
7845
7846 i = rtw_android_cmdstr_to_num(ext);
7847
7848 switch (i) {
7849 case ANDROID_WIFI_CMD_START:
7850 indicate_wx_custom_event(padapter, "START");
7851 break;
7852 case ANDROID_WIFI_CMD_STOP:
7853 indicate_wx_custom_event(padapter, "STOP");
7854 break;
7855 case ANDROID_WIFI_CMD_RSSI: {
7856 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7857 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
7858
7859 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
7860 sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
7861 else
7862 sprintf(ext, "OK");
7863 }
7864 break;
7865 case ANDROID_WIFI_CMD_LINKSPEED: {
7866 u16 mbps = rtw_get_cur_max_rate(padapter) / 10;
7867 sprintf(ext, "LINKSPEED %d", mbps);
7868 }
7869 break;
7870 case ANDROID_WIFI_CMD_MACADDR:
7871 sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
7872 break;
7873 case ANDROID_WIFI_CMD_SCAN_ACTIVE: {
7874 /* rtw_set_scan_mode(padapter, SCAN_ACTIVE); */
7875 sprintf(ext, "OK");
7876 }
7877 break;
7878 case ANDROID_WIFI_CMD_SCAN_PASSIVE: {
7879 /* rtw_set_scan_mode(padapter, SCAN_PASSIVE); */
7880 sprintf(ext, "OK");
7881 }
7882 break;
7883
7884 case ANDROID_WIFI_CMD_COUNTRY: {
7885 char country_code[10];
7886 sscanf(ext, "%*s %s", country_code);
7887 rtw_set_country(padapter, country_code, RTW_REGD_SET_BY_USER);
7888 sprintf(ext, "OK");
7889 }
7890 break;
7891 default:
7892 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7893 RTW_INFO("%s: %s unknowned req=%s\n", __FUNCTION__,
7894 dev->name, ext_dbg);
7895 #endif
7896
7897 sprintf(ext, "OK");
7898
7899 }
7900
7901 if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext) + 1))))
7902 ret = -EFAULT;
7903
7904 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7905 RTW_INFO("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
7906 dev->name, ext_dbg , ext, dwrq->length, (u16)(strlen(ext) + 1));
7907 #endif
7908 #endif /* end of CONFIG_ANDROID */
7909
7910
7911 FREE_EXT:
7912
7913 rtw_vmfree(ext, len);
7914 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7915 rtw_vmfree(ext_dbg, len);
7916 #endif
7917
7918 /* RTW_INFO("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", */
7919 /* dev->name, ret); */
7920
7921 return ret;
7922
7923 }
7924 #endif /*CONFIG_IOCTL_WEXT*/
7925
7926 #ifdef CONFIG_WOWLAN
7927 static int rtw_wowlan_ctrl(struct net_device *dev,
7928 struct iw_request_info *info,
7929 union iwreq_data *wrqu, char *extra)
7930 {
7931 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7932 struct wowlan_ioctl_param poidparam;
7933 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
7934 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7935 int ret = 0;
7936 systime start_time = rtw_get_current_time();
7937 poidparam.subcode = 0;
7938
7939 RTW_INFO("+rtw_wowlan_ctrl: %s\n", extra);
7940
7941 if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE) &&
7942 check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
7943 !WOWLAN_IS_STA_MIX_MODE(padapter)) {
7944 #ifdef CONFIG_PNO_SUPPORT
7945 pwrctrlpriv->wowlan_pno_enable = _TRUE;
7946 #else
7947 RTW_INFO("[%s] WARNING: Please Connect With AP First!!\n", __func__);
7948 goto _rtw_wowlan_ctrl_exit_free;
7949 #endif /* CONFIG_PNO_SUPPORT */
7950 }
7951
7952 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY))
7953 rtw_scan_abort(padapter);
7954
7955 if (_rtw_memcmp(extra, "enable", 6))
7956
7957
7958 rtw_suspend_common(padapter);
7959
7960 else if (_rtw_memcmp(extra, "disable", 7)) {
7961 #ifdef CONFIG_USB_HCI
7962 RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
7963 RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
7964 #endif
7965 rtw_resume_common(padapter);
7966
7967 #ifdef CONFIG_PNO_SUPPORT
7968 pwrctrlpriv->wowlan_pno_enable = _FALSE;
7969 #endif /* CONFIG_PNO_SUPPORT */
7970
7971 } else {
7972 RTW_INFO("[%s] Invalid Parameter.\n", __func__);
7973 goto _rtw_wowlan_ctrl_exit_free;
7974 }
7975 /* mutex_lock(&ioctl_mutex); */
7976 _rtw_wowlan_ctrl_exit_free:
7977 RTW_INFO("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
7978 RTW_PRINT("%s in %d ms\n", __func__,
7979 rtw_get_passing_time_ms(start_time));
7980 return ret;
7981 }
7982
7983 /*
7984 * IP filter This pattern if for a frame containing a ip packet:
7985 * AA:AA:AA:AA:AA:AA:BB:BB:BB:BB:BB:BB:CC:CC:DD:-:-:-:-:-:-:-:-:EE:-:-:FF:FF:FF:FF:GG:GG:GG:GG:HH:HH:II:II
7986 *
7987 * A: Ethernet destination address
7988 * B: Ethernet source address
7989 * C: Ethernet protocol type
7990 * D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20)
7991 * E: IP protocol
7992 * F: IP source address ( 192.168.0.4: C0:A8:00:2C )
7993 * G: IP destination address ( 192.168.0.4: C0:A8:00:2C )
7994 * H: Source port (1024: 04:00)
7995 * I: Destination port (1024: 04:00)
7996 */
7997
7998 static int rtw_wowlan_set_pattern(struct net_device *dev,
7999 struct iw_request_info *info,
8000 union iwreq_data *wrqu, char *extra)
8001 {
8002 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8003 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8004 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8005 struct wowlan_ioctl_param poidparam;
8006 int ret = 0;
8007 u8 input[MAX_IN_PATTERN_SIZE];
8008 u8 index = 0;
8009
8010 poidparam.subcode = 0;
8011
8012 if (!check_fwstate(pmlmepriv, WIFI_ASOC_STATE) &&
8013 check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
8014 ret = -EFAULT;
8015 RTW_INFO("Please Connect With AP First!!\n");
8016 goto _rtw_wowlan_set_pattern_exit;
8017 }
8018
8019 if ((wrqu->data.length <= 0) || (wrqu->data.length > MAX_IN_PATTERN_SIZE)) {
8020 ret = -EFAULT;
8021 RTW_INFO("ERROR: parameter length error, len=%d\n", wrqu->data.length);
8022 goto _rtw_wowlan_set_pattern_exit;
8023 } else {
8024 /* set pattern */
8025 if (copy_from_user(input,
8026 wrqu->data.pointer, wrqu->data.length))
8027 return -EFAULT;
8028 /* leave PS first */
8029 rtw_ps_deny(padapter, PS_DENY_IOCTL);
8030 LeaveAllPowerSaveModeDirect(padapter);
8031 if ((strncmp(input, "pattern=", 8) == 0) ||(strncmp(input, "ack_pattern=", 12) == 0)) {
8032 if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_CAM_NUM) {
8033 RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n",
8034 pwrpriv->wowlan_pattern_idx);
8035 RTW_INFO("WARNING: please clean priv-pattern first\n");
8036 ret = -EINVAL;
8037 goto _rtw_wowlan_set_pattern_exit;
8038 } else {
8039 index = pwrpriv->wowlan_pattern_idx;
8040 ret = rtw_wowlan_parser_pattern_cmd(input,
8041 pwrpriv->patterns[index].content,
8042 &pwrpriv->patterns[index].len,
8043 pwrpriv->patterns[index].mask);
8044
8045 if (ret == _TRUE) {
8046 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8047 if(strncmp(input, "ack_pattern=", 12) == 0)
8048 pwrpriv->wowlan_keep_alive_ack_index = index;
8049 else
8050 pwrpriv->wowlan_wake_pattern_index = index;
8051 RTW_INFO("pwrpriv->wowlan_keep_alive_ack_index =%d\n",pwrpriv->wowlan_keep_alive_ack_index);
8052 RTW_INFO("pwrpriv->wowlan_wake_pattern_index =%d\n",pwrpriv->wowlan_wake_pattern_index);
8053 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8054 pwrpriv->wowlan_pattern_idx++;
8055 }
8056 }
8057 } else if (strncmp(input, "clean", 5) == 0) {
8058 poidparam.subcode = WOWLAN_PATTERN_CLEAN;
8059 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8060 pwrpriv->wowlan_wake_pattern_index = 0xFF;
8061 pwrpriv->wowlan_keep_alive_ack_index = 0xFF;
8062 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8063
8064 rtw_hal_set_hwreg(padapter,
8065 HW_VAR_WOWLAN, (u8 *)&poidparam);
8066 } else if (strncmp(input, "show", 4) == 0) {
8067 rtw_wow_pattern_cam_dump(padapter);
8068 rtw_wow_pattern_sw_dump(padapter);
8069 } else {
8070 RTW_INFO("ERROR: incorrect parameter!\n");
8071 ret = -EINVAL;
8072 }
8073 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
8074 }
8075 _rtw_wowlan_set_pattern_exit:
8076 return ret;
8077 }
8078
8079 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
8080 static int rtw_wowlan_set_keep_alive_pattern(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8081 {
8082 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8083 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8084
8085 int ret = 0,totoal_len=0,i=0,len=0;
8086 char *cp = NULL;
8087 u32 mode = 0xFF; /*para1*/
8088 u16 period = 15*10; /* para2;units:100ms,default 15s*/
8089 char tx_pattern[512]; /*para3*/
8090 u32 retry_intervel = 2*10; /* para4;units:100ms,default 2s*/
8091 u32 retry_limit_count = 5; /*para5*/
8092
8093 ret = sscanf(extra, "%d %hu %s %d %d", &mode , &period, tx_pattern, &retry_intervel, &retry_limit_count);
8094 pwrpriv->wowlan_keep_alive_mode = mode;
8095
8096 RTW_INFO("[%s] ret =%d \n", __func__ ,ret);
8097 totoal_len = strlen(tx_pattern);
8098 RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len);
8099
8100 if (mode && (ret < 3))
8101 return -EINVAL;
8102
8103 if (((mode ==2) ||(mode ==3)) && ((retry_intervel*retry_limit_count) > period)) {
8104 RTW_INFO("[%s] retry_intervel*retry_limit_count need smaller than period\n", __func__ );
8105 return -EINVAL;
8106 }
8107
8108 switch(mode){
8109 case wow_keep_alive_pattern_disable:
8110 /*disable this feature*/
8111 pwrpriv->keep_alive_pattern_loc = 0;
8112 pwrpriv->keep_alive_pattern_len = 0;
8113 pwrpriv->wowlan_keep_alive_period = 0;
8114 pwrpriv->wowlan_keep_alive_ack_index = 0xFF;
8115 pwrpriv->wowlan_wake_pattern_index = 0xFF;
8116 pwrpriv->wowlan_keep_alive_retry_interval = 0;
8117 pwrpriv->wowlan_keep_alive_retry_counter = 0;
8118 _rtw_memset(pwrpriv->keep_alive_pattern,0,WLAN_MAX_KEEP_ALIVE_IE_LEN);
8119 RTW_INFO("[%s] clear pattern \n", __func__ );
8120 ret = _SUCCESS;
8121 break;
8122 case wow_keep_alive_pattern_tx:
8123 /*only tx udp packet*/
8124 pwrpriv->wowlan_keep_alive_period = period;
8125 pwrpriv->wowlan_keep_alive_retry_interval = 0;
8126 pwrpriv->wowlan_keep_alive_retry_counter = 0;
8127 RTW_INFO("[%s] wow_keep_alive_pattern_tx \n", __func__ );
8128 break;
8129 case wow_keep_alive_pattern_trx:
8130 /*trx+no need wakeup*/
8131 pwrpriv->wowlan_keep_alive_period = period;
8132 pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel;
8133 pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count;
8134 RTW_INFO("[%s] wow_keep_alive_pattern_trx \n", __func__ );
8135 break;
8136 case wow_keep_alive_pattern_trx_with_ack:
8137 /*trx+need wakeup*/
8138 pwrpriv->wowlan_keep_alive_period = period;
8139 pwrpriv->wowlan_keep_alive_retry_interval = retry_intervel;
8140 pwrpriv->wowlan_keep_alive_retry_counter = retry_limit_count;
8141 RTW_INFO("[%s] wow_keep_alive_pattern_trx_with_ack \n", __func__ );
8142 break;
8143 default:
8144 RTW_INFO("[%s] please setting valid mode \n", __func__ );
8145 ret = -EINVAL;
8146 break;
8147
8148 }
8149
8150 if((mode == 0) || (mode > 4))
8151 return ret;
8152
8153 totoal_len = strlen(tx_pattern);
8154 RTW_INFO("[%s] totoal_len=%d \n", __func__ ,totoal_len);
8155 if (totoal_len > WLAN_MAX_KEEP_ALIVE_IE_LEN*2) {
8156 RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_KEEP_ALIVE_IE_LEN);
8157 return -EFAULT;
8158 }
8159 RTW_INFO("[%s] period = %hu ,ie = %s , len = %d\n", __func__ , period , tx_pattern , totoal_len);
8160
8161
8162 if (totoal_len > 0) {
8163 RTW_INFO("[%s] pwrpriv->keep_alive_pattern==========> \n", __func__ );
8164 for (i = 0 ; i <totoal_len ; i += 2) {
8165 pwrpriv->keep_alive_pattern[len] = key_2char2num(tx_pattern[i], tx_pattern[i + 1]);
8166 RTW_INFO("[0x%x] ",pwrpriv->keep_alive_pattern[len]);
8167 len++;
8168 }
8169 RTW_INFO(" \n" );
8170 pwrpriv->keep_alive_pattern_len = len;
8171 }
8172
8173 return ret;
8174 }
8175 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
8176
8177 #endif /* CONFIG_WOWLAN */
8178
8179 #ifdef CONFIG_AP_WOWLAN
8180 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
8181 struct iw_request_info *info,
8182 union iwreq_data *wrqu, char *extra)
8183 {
8184 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8185 struct wowlan_ioctl_param poidparam;
8186 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8187 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8188 struct sta_info *psta = NULL;
8189 int ret = 0;
8190 systime start_time = rtw_get_current_time();
8191 poidparam.subcode = 0;
8192
8193 RTW_INFO("+rtw_ap_wowlan_ctrl: %s\n", extra);
8194
8195 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
8196 RTW_INFO("[%s] It is not AP mode!!\n", __func__);
8197 goto _rtw_ap_wowlan_ctrl_exit_free;
8198 }
8199
8200 if (_rtw_memcmp(extra, "enable", 6)) {
8201
8202 pwrctrlpriv->wowlan_ap_mode = _TRUE;
8203
8204 rtw_suspend_common(padapter);
8205 } else if (_rtw_memcmp(extra, "disable", 7)) {
8206 #ifdef CONFIG_USB_HCI
8207 RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
8208 RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
8209 #endif
8210 rtw_resume_common(padapter);
8211 } else {
8212 RTW_INFO("[%s] Invalid Parameter.\n", __func__);
8213 goto _rtw_ap_wowlan_ctrl_exit_free;
8214 }
8215 /* mutex_lock(&ioctl_mutex); */
8216 _rtw_ap_wowlan_ctrl_exit_free:
8217 RTW_INFO("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8218 RTW_PRINT("%s in %d ms\n", __func__,
8219 rtw_get_passing_time_ms(start_time));
8220 _rtw_ap_wowlan_ctrl_exit:
8221 return ret;
8222 }
8223 #endif /* CONFIG_AP_WOWLAN */
8224
8225 static int rtw_pm_set(struct net_device *dev,
8226 struct iw_request_info *info,
8227 union iwreq_data *wrqu, char *extra)
8228 {
8229 int ret = 0;
8230 unsigned mode = 0;
8231 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8232
8233 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
8234
8235 if (_rtw_memcmp(extra, "lps=", 4)) {
8236 sscanf(extra + 4, "%u", &mode);
8237 ret = rtw_pm_set_lps(padapter, mode);
8238 } else if (_rtw_memcmp(extra, "ips=", 4)) {
8239 sscanf(extra + 4, "%u", &mode);
8240 ret = rtw_pm_set_ips(padapter, mode);
8241 } else if (_rtw_memcmp(extra, "lps_level=", 10)) {
8242 if (sscanf(extra + 10, "%u", &mode) > 0)
8243 ret = rtw_pm_set_lps_level(padapter, mode);
8244 #ifdef CONFIG_LPS_1T1R
8245 } else if (_rtw_memcmp(extra, "lps_1t1r=", 9)) {
8246 if (sscanf(extra + 9, "%u", &mode) > 0)
8247 ret = rtw_pm_set_lps_1t1r(padapter, mode);
8248 #endif
8249 }
8250 #ifdef CONFIG_WOWLAN
8251 else if (_rtw_memcmp(extra, "wow_lps=", 8)) {
8252 sscanf(extra + 8, "%u", &mode);
8253 ret = rtw_pm_set_wow_lps(padapter, mode);
8254 } else if (_rtw_memcmp(extra, "wow_lps_level=", 14)) {
8255 if (sscanf(extra + 14, "%u", &mode) > 0)
8256 ret = rtw_pm_set_wow_lps_level(padapter, mode);
8257 #ifdef CONFIG_LPS_1T1R
8258 } else if (_rtw_memcmp(extra, "wow_lps_1t1r=", 13)) {
8259 if (sscanf(extra + 13, "%u", &mode) > 0)
8260 ret = rtw_pm_set_wow_lps_1t1r(padapter, mode);
8261 #endif
8262 }
8263 #endif /* CONFIG_WOWLAN */
8264 else
8265 ret = -EINVAL;
8266
8267 return ret;
8268 }
8269 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8270
8271 int rtw_vendor_ie_get_raw_data(struct net_device *dev, u32 vendor_ie_num,
8272 char *extra, u32 length)
8273 {
8274 int j;
8275 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8276 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8277 u32 vendor_ie_mask = 0;
8278 char *pstring;
8279
8280 if (vendor_ie_num >= WLAN_MAX_VENDOR_IE_NUM) {
8281 RTW_INFO("[%s] only support %d vendor ie\n", __func__ ,
8282 WLAN_MAX_VENDOR_IE_NUM);
8283 return -EFAULT;
8284 }
8285
8286 if (pmlmepriv->vendor_ielen[vendor_ie_num] == 0) {
8287 RTW_INFO("[%s] Fail, vendor_ie_num: %d is not set\n", __func__,
8288 vendor_ie_num);
8289 return -EFAULT;
8290 }
8291
8292 if (length < 2 * pmlmepriv->vendor_ielen[vendor_ie_num] + 5) {
8293 RTW_INFO("[%s] Fail, buffer size is too small\n", __func__);
8294 return -EFAULT;
8295 }
8296
8297 vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8298 _rtw_memset(extra, 0, length);
8299
8300 pstring = extra;
8301 pstring += sprintf(pstring, "%d,%x,", vendor_ie_num, vendor_ie_mask);
8302
8303 for (j = 0; j < pmlmepriv->vendor_ielen[vendor_ie_num]; j++)
8304 pstring += sprintf(pstring, "%02x", pmlmepriv->vendor_ie[vendor_ie_num][j]);
8305
8306 length = pstring - extra;
8307 return length;
8308 }
8309
8310 int rtw_vendor_ie_get_data(struct net_device *dev, int vendor_ie_num, char *extra)
8311 {
8312 int j;
8313 char *pstring;
8314 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8315 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8316 u32 vendor_ie_mask = 0;
8317 __u16 length = 0;
8318
8319 vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8320 pstring = extra;
8321 pstring += sprintf(pstring , "\nVendor IE num %d , Mask:%x " , vendor_ie_num , vendor_ie_mask);
8322
8323 if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8324 pstring += sprintf(pstring , "[Beacon]");
8325 if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8326 pstring += sprintf(pstring , "[Probe Req]");
8327 if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8328 pstring += sprintf(pstring , "[Probe Resp]");
8329 if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8330 pstring += sprintf(pstring , "[Assoc Req]");
8331 if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8332 pstring += sprintf(pstring , "[Assoc Resp]");
8333 #ifdef CONFIG_P2P
8334 if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)
8335 pstring += sprintf(pstring , "[P2P_Probe Req]");
8336 if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)
8337 pstring += sprintf(pstring , "[P2P_Probe Resp]");
8338 #endif
8339
8340 pstring += sprintf(pstring , "\nVendor IE:\n");
8341 for (j = 0 ; j < pmlmepriv->vendor_ielen[vendor_ie_num] ; j++)
8342 pstring += sprintf(pstring , "%02x" , pmlmepriv->vendor_ie[vendor_ie_num][j]);
8343
8344 length = pstring - extra;
8345 return length;
8346
8347 }
8348
8349 int rtw_vendor_ie_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8350 {
8351 int ret = 0, vendor_ie_num = 0, cmdlen;
8352 struct iw_point *p;
8353 u8 *ptmp;
8354
8355 p = &wrqu->data;
8356 cmdlen = p->length;
8357 if (0 == cmdlen)
8358 return -EINVAL;
8359
8360 ptmp = (u8 *)rtw_malloc(cmdlen);
8361 if (NULL == ptmp)
8362 return -ENOMEM;
8363
8364 if (copy_from_user(ptmp, p->pointer, cmdlen)) {
8365 ret = -EFAULT;
8366 goto exit;
8367 }
8368 ret = sscanf(ptmp , "%d", &vendor_ie_num);
8369 if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8370 ret = -EFAULT;
8371 goto exit;
8372 }
8373
8374 wrqu->data.length = rtw_vendor_ie_get_data(dev, vendor_ie_num, extra);
8375
8376 exit:
8377 rtw_mfree(ptmp, cmdlen);
8378
8379 return 0;
8380 }
8381
8382 int rtw_vendor_ie_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8383 {
8384 int ret = 0, i , len = 0 , totoal_ie_len = 0 , total_ie_len_byte = 0;
8385 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8386 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8387 u32 vendor_ie_mask = 0;
8388 u32 vendor_ie_num = 0;
8389 u32 vendor_ie_mask_max = BIT(WLAN_MAX_VENDOR_IE_MASK_MAX) - 1;
8390 u32 id, elen;
8391
8392 ret = sscanf(extra, "%d,%x,%*s", &vendor_ie_num , &vendor_ie_mask);
8393 if (strrchr(extra , ','))
8394 extra = strrchr(extra , ',') + 1;
8395 else
8396 return -EINVAL;
8397 totoal_ie_len = strlen(extra);
8398 RTW_INFO("[%s] vendor_ie_num = %d , vendor_ie_mask = 0x%x , vendor_ie = %s , len = %d\n", __func__ , vendor_ie_num , vendor_ie_mask , extra , totoal_ie_len);
8399
8400 if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8401 RTW_INFO("[%s] Fail, only support %d vendor ie\n", __func__ , WLAN_MAX_VENDOR_IE_NUM);
8402 return -EFAULT;
8403 }
8404
8405 if (totoal_ie_len > WLAN_MAX_VENDOR_IE_LEN) {
8406 RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_VENDOR_IE_LEN);
8407 return -EFAULT;
8408 }
8409
8410 if (vendor_ie_mask > vendor_ie_mask_max) {
8411 RTW_INFO("[%s] Fail, not support vendor_ie_mask more than 0x%x\n", __func__ , vendor_ie_mask_max);
8412 return -EFAULT;
8413 }
8414
8415 if (vendor_ie_mask == 0) {
8416 RTW_INFO("[%s] Clear vendor_ie_num %d group\n", __func__ , vendor_ie_num);
8417 goto _clear_path;
8418 }
8419
8420 if (totoal_ie_len % 2 != 0) {
8421 RTW_INFO("[%s] Fail , IE length = %zu is odd\n" , __func__ , strlen(extra));
8422 return -EFAULT;
8423 }
8424
8425 if (totoal_ie_len > 0) {
8426 for (i = 0 ; i < strlen(extra) ; i += 2) {
8427 pmlmepriv->vendor_ie[vendor_ie_num][len] = key_2char2num(extra[i] , extra[i + 1]);
8428 if (len == 0) {
8429 id = pmlmepriv->vendor_ie[vendor_ie_num][len];
8430 if (id != WLAN_EID_VENDOR_SPECIFIC) {
8431 RTW_INFO("[%s] Fail , VENDOR SPECIFIC IE ID \"%x\" was not correct\n", __func__ , id);
8432 goto _clear_path;
8433 }
8434 } else if (len == 1) {
8435 total_ie_len_byte = (totoal_ie_len / 2) - 2;
8436 elen = pmlmepriv->vendor_ie[vendor_ie_num][len];
8437 if (elen != total_ie_len_byte) {
8438 RTW_INFO("[%s] Fail , Input IE length = \"%d\"(hex:%x) bytes , not match input total IE context length \"%d\" bytes\n", __func__ , elen , elen ,
8439 total_ie_len_byte);
8440 goto _clear_path;
8441 }
8442 }
8443 len++;
8444 }
8445 pmlmepriv->vendor_ielen[vendor_ie_num] = len;
8446 } else
8447 pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
8448
8449
8450
8451 if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8452 RTW_INFO("[%s] Beacon append vendor ie\n", __func__);
8453 if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8454 RTW_INFO("[%s] Probe Req append vendor ie\n", __func__);
8455 if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8456 RTW_INFO("[%s] Probe Resp append vendor ie\n", __func__);
8457 if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8458 RTW_INFO("[%s] Assoc Req append vendor ie\n", __func__);
8459 if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8460 RTW_INFO("[%s] Assoc Resp append vendor ie\n", __func__);
8461 #ifdef CONFIG_P2P
8462 if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)
8463 RTW_INFO("[%s] P2P Probe Req append vendor ie\n", __func__);
8464 if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)
8465 RTW_INFO("[%s] P2P Probe Resp append vendor ie\n", __func__);
8466 #endif
8467
8468 pmlmepriv->vendor_ie_mask[vendor_ie_num] = vendor_ie_mask;
8469
8470 return ret;
8471
8472 _clear_path:
8473 _rtw_memset(pmlmepriv->vendor_ie[vendor_ie_num] , 0 , sizeof(u32) * WLAN_MAX_VENDOR_IE_LEN);
8474 pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
8475 pmlmepriv->vendor_ie_mask[vendor_ie_num] = 0;
8476 return -EFAULT;
8477 }
8478 #endif
8479
8480 static int rtw_get_ic_type(struct net_device *dev,
8481 struct iw_request_info *info,
8482 union iwreq_data *wrqu, char *extra)
8483 {
8484 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8485 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8486 char *pstring = extra;
8487 u8 regdata;
8488
8489 _rtw_memset(pstring, 0, wrqu->data.length);
8490
8491 regdata = (rtw_read32(padapter, 0xF0) & 0xf000) >> 12;
8492 RTW_INFO("%s: f0[15:12]= 0x%x\n", __FUNCTION__, regdata);
8493
8494 if (regdata == 0x04)
8495 pstring += sprintf(pstring , ":%s\n" ,"rtl8822c-vbs");
8496 else
8497 pstring += sprintf(pstring , ":%s\n" ,"rtl8822c-vs");
8498
8499 wrqu->data.length = strlen(extra);
8500
8501 return 0;
8502 }
8503
8504 static int rtw_mp_efuse_get(struct net_device *dev,
8505 struct iw_request_info *info,
8506 union iwreq_data *wdata, char *extra)
8507 {
8508 PADAPTER padapter = rtw_netdev_priv(dev);
8509 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8510
8511 PEFUSE_HAL pEfuseHal;
8512 struct iw_point *wrqu;
8513
8514 u8 ips_mode = IPS_NUM; /* init invalid value */
8515 u8 lps_mode = PS_MODE_NUM; /* init invalid value */
8516 struct pwrctrl_priv *pwrctrlpriv ;
8517 u8 *data = NULL;
8518 u8 *rawdata = NULL;
8519 char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
8520 u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;
8521 u16 max_available_len = 0, raw_cursize = 0, raw_maxsize = 0;
8522 u16 mask_len;
8523 u8 mask_buf[64] = "";
8524 int err;
8525 char *pextra = NULL;
8526 #ifdef CONFIG_IOL
8527 u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
8528 #endif
8529
8530 wrqu = (struct iw_point *)wdata;
8531 pwrctrlpriv = adapter_to_pwrctl(padapter);
8532 pEfuseHal = &pHalData->EfuseHal;
8533
8534 err = 0;
8535 data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
8536 if (data == NULL) {
8537 err = -ENOMEM;
8538 goto exit;
8539 }
8540 rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
8541 if (rawdata == NULL) {
8542 err = -ENOMEM;
8543 goto exit;
8544 }
8545
8546 if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {
8547 err = -EFAULT;
8548 goto exit;
8549 }
8550
8551 *(extra + wrqu->length) = '\0';
8552
8553 #ifdef CONFIG_LPS
8554 lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
8555 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
8556 #endif
8557
8558 #ifdef CONFIG_IPS
8559 ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
8560 rtw_pm_set_ips(padapter, IPS_NONE);
8561 #endif
8562
8563 pch = extra;
8564 RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
8565
8566 i = 0;
8567 /* mac 16 "00e04c871200" rmap,00,2 */
8568 while ((token = strsep(&pch, ",")) != NULL) {
8569 if (i > 2)
8570 break;
8571 tmp[i] = token;
8572 i++;
8573 }
8574 #ifdef CONFIG_IOL
8575 padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */
8576 #endif
8577
8578 if (strcmp(tmp[0], "status") == 0) {
8579 sprintf(extra, "Load File efuse=%s,Load File MAC=%s"
8580 , pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK"
8581 , pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK"
8582 );
8583 goto exit;
8584 } else if (strcmp(tmp[0], "drvmap") == 0) {
8585 static u8 drvmaporder = 0;
8586 u8 *efuse;
8587 u32 shift, cnt;
8588 u32 blksz = 0x200; /* The size of one time show, default 512 */
8589 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
8590
8591 efuse = pHalData->efuse_eeprom_data;
8592
8593 shift = blksz * drvmaporder;
8594 efuse += shift;
8595 cnt = mapLen - shift;
8596
8597 if (cnt > blksz) {
8598 cnt = blksz;
8599 drvmaporder++;
8600 } else
8601 drvmaporder = 0;
8602
8603 sprintf(extra, "\n");
8604 for (i = 0; i < cnt; i += 16) {
8605 pextra = extra + strlen(extra);
8606 pextra += sprintf(pextra, "0x%02x\t", shift + i);
8607 for (j = 0; j < 8; j++)
8608 pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8609 pextra += sprintf(pextra, "\t");
8610 for (; j < 16; j++)
8611 pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8612 pextra += sprintf(pextra, "\n");
8613 }
8614 if ((shift + cnt) < mapLen)
8615 pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8616
8617 } else if (strcmp(tmp[0], "realmap") == 0) {
8618 static u8 order = 0;
8619 u8 *efuse;
8620 u32 shift, cnt;
8621 u32 blksz = 0x200; /* The size of one time show, default 512 */
8622
8623 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
8624 efuse = pEfuseHal->fakeEfuseInitMap;
8625 if (rtw_efuse_mask_map_read(padapter, 0, mapLen, efuse) == _FAIL) {
8626 RTW_INFO("%s: read realmap Fail!!\n", __FUNCTION__);
8627 err = -EFAULT;
8628 goto exit;
8629 }
8630
8631 #if 0
8632 RTW_INFO("OFFSET\tVALUE(hex)\n");
8633 for (i = 0; i < mapLen; i += 16) {
8634 RTW_INFO("0x%02x\t", i);
8635 for (j = 0; j < 8; j++)
8636 RTW_INFO("%02X ", efuse[i + j]);
8637 RTW_INFO("\t");
8638 for (; j < 16; j++)
8639 RTW_INFO("%02X ", efuse[i + j]);
8640 RTW_INFO("\n");
8641 }
8642 RTW_INFO("\n");
8643 #endif
8644
8645 shift = blksz * order;
8646 efuse += shift;
8647 cnt = mapLen - shift;
8648 if (cnt > blksz) {
8649 cnt = blksz;
8650 order++;
8651 } else
8652 order = 0;
8653
8654 sprintf(extra, "\n");
8655 for (i = 0; i < cnt; i += 16) {
8656 pextra = extra + strlen(extra);
8657 pextra += sprintf(pextra, "0x%02x\t", shift + i);
8658 for (j = 0; j < 8; j++)
8659 pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8660 pextra += sprintf(pextra, "\t");
8661 for (; j < 16; j++)
8662 pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8663 pextra += sprintf(pextra, "\n");
8664 }
8665 if ((shift + cnt) < mapLen)
8666 pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8667 } else if (strcmp(tmp[0], "rmap") == 0) {
8668 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8669 RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
8670 err = -EINVAL;
8671 goto exit;
8672 }
8673
8674 /* rmap addr cnts */
8675 addr = simple_strtoul(tmp[1], &ptmp, 16);
8676 RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
8677
8678 cnts = simple_strtoul(tmp[2], &ptmp, 10);
8679 if (cnts == 0) {
8680 RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
8681 err = -EINVAL;
8682 goto exit;
8683 }
8684 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
8685
8686 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&max_available_len, _FALSE);
8687 if ((addr + cnts) > max_available_len) {
8688 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8689 err = -EINVAL;
8690 goto exit;
8691 }
8692
8693 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8694 RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
8695 err = -EFAULT;
8696 goto exit;
8697 }
8698
8699 /* RTW_INFO("%s: data={", __FUNCTION__); */
8700 *extra = 0;
8701 pextra = extra;
8702 for (i = 0; i < cnts; i++) {
8703 /* RTW_INFO("0x%02x ", data[i]); */
8704 pextra += sprintf(pextra, "0x%02X ", data[i]);
8705 }
8706 /* RTW_INFO("}\n"); */
8707 } else if (strcmp(tmp[0], "realraw") == 0) {
8708 static u8 raw_order = 0;
8709 u32 shift, cnt;
8710 u32 blksz = 0x200; /* The size of one time show, default 512 */
8711
8712 addr = 0;
8713 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN , (void *)&mapLen, _FALSE);
8714 RTW_INFO("Real content len = %d\n",mapLen );
8715
8716 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
8717 RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8718 err = -EFAULT;
8719 goto exit;
8720 }
8721
8722 _rtw_memset(extra, '\0', strlen(extra));
8723
8724 shift = blksz * raw_order;
8725 rawdata += shift;
8726 cnt = mapLen - shift;
8727 if (cnt > blksz) {
8728 cnt = blksz;
8729 raw_order++;
8730 } else
8731 raw_order = 0;
8732
8733 sprintf(extra, "\n");
8734 for (i = 0; i < cnt; i += 16) {
8735 pextra = extra + strlen(extra);
8736 pextra += sprintf(pextra, "0x%02x\t", shift + i);
8737 for (j = 0; j < 8; j++)
8738 pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8739 pextra += sprintf(pextra, "\t");
8740 for (; j < 16; j++)
8741 pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8742 pextra += sprintf(pextra, "\n");
8743 }
8744 if ((shift + cnt) < mapLen)
8745 pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8746
8747 } else if (strcmp(tmp[0], "btrealraw") == 0) {
8748 static u8 bt_raw_order = 0;
8749 u32 shift, cnt;
8750 u32 blksz = 0x200; /* The size of one time show, default 512 */
8751
8752 addr = 0;
8753 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&mapLen, _FALSE);
8754 RTW_INFO("Real content len = %d\n", mapLen);
8755 #ifdef RTW_HALMAC
8756 if (rtw_efuse_bt_access(padapter, _FALSE, 0, mapLen, rawdata) == _FAIL) {
8757 RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8758 err = -EFAULT;
8759 goto exit;
8760 }
8761 #else
8762 rtw_write8(padapter, 0x35, 0x1);
8763
8764 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
8765 RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8766 err = -EFAULT;
8767 goto exit;
8768 }
8769 #endif
8770 _rtw_memset(extra, '\0', strlen(extra));
8771
8772 shift = blksz * bt_raw_order;
8773 rawdata += shift;
8774 cnt = mapLen - shift;
8775 if (cnt > blksz) {
8776 cnt = blksz;
8777 bt_raw_order++;
8778 } else
8779 bt_raw_order = 0;
8780
8781 sprintf(extra, "\n");
8782 for (i = 0; i < cnt; i += 16) {
8783 pextra = extra + strlen(extra);
8784 pextra += sprintf(pextra, "0x%02x\t", shift + i);
8785 for (j = 0; j < 8; j++)
8786 pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8787 pextra += sprintf(pextra, "\t");
8788 for (; j < 16; j++)
8789 pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8790 pextra += sprintf(pextra, "\n");
8791 }
8792 if ((shift + cnt) < mapLen)
8793 pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8794
8795 } else if (strcmp(tmp[0], "mac") == 0) {
8796 if (hal_efuse_macaddr_offset(padapter) == -1) {
8797 err = -EFAULT;
8798 goto exit;
8799 }
8800
8801 addr = hal_efuse_macaddr_offset(padapter);
8802 cnts = 6;
8803
8804 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8805 if ((addr + cnts) > max_available_len) {
8806 RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8807 err = -EFAULT;
8808 goto exit;
8809 }
8810
8811 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8812 RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
8813 err = -EFAULT;
8814 goto exit;
8815 }
8816
8817 /* RTW_INFO("%s: MAC address={", __FUNCTION__); */
8818 *extra = 0;
8819 pextra = extra;
8820 for (i = 0; i < cnts; i++) {
8821 /* RTW_INFO("%02X", data[i]); */
8822 pextra += sprintf(pextra, "%02X", data[i]);
8823 if (i != (cnts - 1)) {
8824 /* RTW_INFO(":"); */
8825 pextra += sprintf(pextra, ":");
8826 }
8827 }
8828 /* RTW_INFO("}\n"); */
8829 } else if (strcmp(tmp[0], "vidpid") == 0) {
8830 #ifdef CONFIG_RTL8188E
8831 #ifdef CONFIG_USB_HCI
8832 addr = EEPROM_VID_88EU;
8833 #endif
8834 #ifdef CONFIG_PCI_HCI
8835 addr = EEPROM_VID_88EE;
8836 #endif
8837 #endif /* CONFIG_RTL8188E */
8838
8839 #ifdef CONFIG_RTL8192E
8840 #ifdef CONFIG_USB_HCI
8841 addr = EEPROM_VID_8192EU;
8842 #endif
8843 #ifdef CONFIG_PCI_HCI
8844 addr = EEPROM_VID_8192EE;
8845 #endif
8846 #endif /* CONFIG_RTL8192E */
8847 #ifdef CONFIG_RTL8723B
8848 addr = EEPROM_VID_8723BU;
8849 #endif /* CONFIG_RTL8192E */
8850
8851 #ifdef CONFIG_RTL8188F
8852 addr = EEPROM_VID_8188FU;
8853 #endif /* CONFIG_RTL8188F */
8854
8855 #ifdef CONFIG_RTL8188GTV
8856 addr = EEPROM_VID_8188GTVU;
8857 #endif
8858
8859 #ifdef CONFIG_RTL8703B
8860 #ifdef CONFIG_USB_HCI
8861 addr = EEPROM_VID_8703BU;
8862 #endif
8863 #endif /* CONFIG_RTL8703B */
8864
8865 #ifdef CONFIG_RTL8723D
8866 #ifdef CONFIG_USB_HCI
8867 addr = EEPROM_VID_8723DU;
8868 #endif /* CONFIG_USB_HCI */
8869 #endif /* CONFIG_RTL8723D */
8870
8871 cnts = 4;
8872
8873 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8874 if ((addr + cnts) > max_available_len) {
8875 RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8876 err = -EFAULT;
8877 goto exit;
8878 }
8879 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8880 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
8881 err = -EFAULT;
8882 goto exit;
8883 }
8884
8885 /* RTW_INFO("%s: {VID,PID}={", __FUNCTION__); */
8886 *extra = 0;
8887 pextra = extra;
8888 for (i = 0; i < cnts; i++) {
8889 /* RTW_INFO("0x%02x", data[i]); */
8890 pextra += sprintf(pextra, "0x%02X", data[i]);
8891 if (i != (cnts - 1)) {
8892 /* RTW_INFO(","); */
8893 pextra += sprintf(pextra, ",");
8894 }
8895 }
8896 /* RTW_INFO("}\n"); */
8897 } else if (strcmp(tmp[0], "ableraw") == 0) {
8898 #ifdef RTW_HALMAC
8899 raw_maxsize = efuse_GetavailableSize(padapter);
8900 #else
8901 efuse_GetCurrentSize(padapter, &raw_cursize);
8902 raw_maxsize = efuse_GetMaxSize(padapter);
8903 #endif
8904 sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
8905 } else if (strcmp(tmp[0], "btableraw") == 0) {
8906 efuse_bt_GetCurrentSize(padapter, &raw_cursize);
8907 raw_maxsize = efuse_bt_GetMaxSize(padapter);
8908 sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
8909 } else if (strcmp(tmp[0], "btfmap") == 0) {
8910
8911 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8912
8913 mapLen = EFUSE_BT_MAX_MAP_LEN;
8914 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
8915 RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
8916 err = -EFAULT;
8917 goto exit;
8918 }
8919
8920 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8921 sprintf(extra, "\n");
8922 for (i = 0; i < 512; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */
8923 /* RTW_INFO("0x%03x\t", i); */
8924 pextra = extra + strlen(extra);
8925 pextra += sprintf(pextra, "0x%03x\t", i);
8926 for (j = 0; j < 8; j++) {
8927 /* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
8928 pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8929 }
8930 /* RTW_INFO("\t"); */
8931 pextra += sprintf(pextra, "\t");
8932 for (; j < 16; j++) {
8933 /* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
8934 pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8935 }
8936 /* RTW_INFO("\n"); */
8937 pextra += sprintf(pextra, "\n");
8938 }
8939 /* RTW_INFO("\n"); */
8940 } else if (strcmp(tmp[0], "btbmap") == 0) {
8941 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8942
8943 mapLen = EFUSE_BT_MAX_MAP_LEN;
8944 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
8945 RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
8946 err = -EFAULT;
8947 goto exit;
8948 }
8949
8950 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8951 sprintf(extra, "\n");
8952 for (i = 512; i < 1024 ; i += 16) {
8953 /* RTW_INFO("0x%03x\t", i); */
8954 pextra = extra + strlen(extra);
8955 pextra += sprintf(pextra, "0x%03x\t", i);
8956 for (j = 0; j < 8; j++) {
8957 /* RTW_INFO("%02X ", data[i+j]); */
8958 pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8959 }
8960 /* RTW_INFO("\t"); */
8961 pextra += sprintf(pextra, "\t");
8962 for (; j < 16; j++) {
8963 /* RTW_INFO("%02X ", data[i+j]); */
8964 pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8965 }
8966 /* RTW_INFO("\n"); */
8967 pextra += sprintf(pextra, "\n");
8968 }
8969 /* RTW_INFO("\n"); */
8970 } else if (strcmp(tmp[0], "btrmap") == 0) {
8971 u8 BTStatus;
8972
8973 rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
8974 BTStatus = rtw_read8(padapter, 0xa0);
8975
8976 RTW_INFO("%s: Check 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
8977 if (BTStatus != 0x04) {
8978 sprintf(extra, "BT Status not Active ,can't to read BT eFuse\n");
8979 goto exit;
8980 }
8981
8982 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8983 err = -EINVAL;
8984 goto exit;
8985 }
8986
8987 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8988
8989 /* rmap addr cnts */
8990 addr = simple_strtoul(tmp[1], &ptmp, 16);
8991 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
8992
8993 cnts = simple_strtoul(tmp[2], &ptmp, 10);
8994 if (cnts == 0) {
8995 RTW_INFO("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
8996 err = -EINVAL;
8997 goto exit;
8998 }
8999 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9000 #ifndef RTW_HALMAC
9001 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9002 if ((addr + cnts) > max_available_len) {
9003 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9004 err = -EFAULT;
9005 goto exit;
9006 }
9007 #endif
9008 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
9009 RTW_INFO("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
9010 err = -EFAULT;
9011 goto exit;
9012 }
9013
9014 *extra = 0;
9015 pextra = extra;
9016 /* RTW_INFO("%s: bt efuse data={", __FUNCTION__); */
9017 for (i = 0; i < cnts; i++) {
9018 /* RTW_INFO("0x%02x ", data[i]); */
9019 pextra += sprintf(pextra, " 0x%02X ", data[i]);
9020 }
9021 /* RTW_INFO("}\n"); */
9022 RTW_INFO(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
9023 } else if (strcmp(tmp[0], "btffake") == 0) {
9024 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9025 sprintf(extra, "\n");
9026 for (i = 0; i < 512; i += 16) {
9027 /* RTW_INFO("0x%03x\t", i); */
9028 pextra = extra + strlen(extra);
9029 pextra += sprintf(pextra, "0x%03x\t", i);
9030 for (j = 0; j < 8; j++) {
9031 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9032 pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9033 }
9034 /* RTW_INFO("\t"); */
9035 pextra += sprintf(pextra, "\t");
9036 for (; j < 16; j++) {
9037 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9038 pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9039 }
9040 /* RTW_INFO("\n"); */
9041 pextra += sprintf(pextra, "\n");
9042 }
9043 /* RTW_INFO("\n"); */
9044 } else if (strcmp(tmp[0], "btbfake") == 0) {
9045 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9046 sprintf(extra, "\n");
9047 for (i = 512; i < 1024; i += 16) {
9048 /* RTW_INFO("0x%03x\t", i); */
9049 pextra = extra + strlen(extra);
9050 pextra += sprintf(pextra, "0x%03x\t", i);
9051 for (j = 0; j < 8; j++) {
9052 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9053 pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9054 }
9055 /* RTW_INFO("\t"); */
9056 pextra += sprintf(pextra, "\t");
9057 for (; j < 16; j++) {
9058 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9059 pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
9060 }
9061 /* RTW_INFO("\n"); */
9062 pextra += sprintf(pextra, "\n");
9063 }
9064 /* RTW_INFO("\n"); */
9065 } else if (strcmp(tmp[0], "wlrfkmap") == 0) {
9066 static u8 fk_order = 0;
9067 u8 *efuse;
9068 u32 shift, cnt;
9069 u32 blksz = 0x200; /* The size of one time show, default 512 */
9070
9071 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
9072 efuse = pEfuseHal->fakeEfuseModifiedMap;
9073
9074 shift = blksz * fk_order;
9075 efuse += shift;
9076 cnt = mapLen - shift;
9077 if (cnt > blksz) {
9078 cnt = blksz;
9079 fk_order++;
9080 } else
9081 fk_order = 0;
9082
9083 sprintf(extra, "\n");
9084 for (i = 0; i < cnt; i += 16) {
9085 pextra = extra + strlen(extra);
9086 pextra += sprintf(pextra, "0x%02x\t", shift + i);
9087 for (j = 0; j < 8; j++)
9088 pextra += sprintf(pextra, "%02X ", efuse[i + j]);
9089 pextra += sprintf(pextra, "\t");
9090 for (; j < 16; j++)
9091 pextra += sprintf(pextra, "%02X ", efuse[i + j]);
9092 pextra += sprintf(pextra, "\n");
9093 }
9094 if ((shift + cnt) < mapLen)
9095 pextra += sprintf(pextra, "\t...more\n");
9096
9097 } else if (strcmp(tmp[0], "wlrfkrmap") == 0) {
9098 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9099 RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9100 err = -EINVAL;
9101 goto exit;
9102 }
9103 /* rmap addr cnts */
9104 addr = simple_strtoul(tmp[1], &ptmp, 16);
9105 RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9106
9107 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9108 if (cnts == 0) {
9109 RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9110 err = -EINVAL;
9111 goto exit;
9112 }
9113 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9114
9115 /* RTW_INFO("%s: data={", __FUNCTION__); */
9116 *extra = 0;
9117 pextra = extra;
9118 for (i = 0; i < cnts; i++) {
9119 RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9120 pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9121 }
9122 } else if (strcmp(tmp[0], "btrfkrmap") == 0) {
9123 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9124 RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9125 err = -EINVAL;
9126 goto exit;
9127 }
9128 /* rmap addr cnts */
9129 addr = simple_strtoul(tmp[1], &ptmp, 16);
9130 RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9131
9132 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9133 if (cnts == 0) {
9134 RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9135 err = -EINVAL;
9136 goto exit;
9137 }
9138 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9139
9140 /* RTW_INFO("%s: data={", __FUNCTION__); */
9141 *extra = 0;
9142 pextra = extra;
9143 for (i = 0; i < cnts; i++) {
9144 RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeBTEfuseModifiedMap[addr + i]);
9145 pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9146 }
9147 } else if (strcmp(tmp[0], "mask") == 0) {
9148 *extra = 0;
9149 mask_len = sizeof(u8) * rtw_get_efuse_mask_arraylen(padapter);
9150 rtw_efuse_mask_array(padapter, mask_buf);
9151
9152 if (padapter->registrypriv.bFileMaskEfuse == _TRUE)
9153 _rtw_memcpy(mask_buf, maskfileBuffer, mask_len);
9154
9155 sprintf(extra, "\n");
9156 pextra = extra + strlen(extra);
9157 for (i = 0; i < mask_len; i++)
9158 pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);
9159
9160 } else if (strcmp(tmp[0], "btmask") == 0) {
9161 *extra = 0;
9162 mask_len = sizeof(u8) * rtw_get_bt_efuse_mask_arraylen(padapter);
9163 rtw_bt_efuse_mask_array(padapter, mask_buf);
9164
9165 if (padapter->registrypriv.bBTFileMaskEfuse == _TRUE)
9166 _rtw_memcpy(mask_buf, btmaskfileBuffer, mask_len);
9167
9168 sprintf(extra, "\n");
9169 pextra = extra + strlen(extra);
9170 for (i = 0; i < mask_len; i++)
9171 pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);
9172
9173 } else
9174 sprintf(extra, "Command not found!");
9175
9176 exit:
9177 if (data)
9178 rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9179 if (rawdata)
9180 rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9181 if (!err)
9182 wrqu->length = strlen(extra);
9183
9184 if (padapter->registrypriv.mp_mode == 0) {
9185 #ifdef CONFIG_IPS
9186 rtw_pm_set_ips(padapter, ips_mode);
9187 #endif /* CONFIG_IPS */
9188
9189 #ifdef CONFIG_LPS
9190 rtw_pm_set_lps(padapter, lps_mode);
9191 #endif /* CONFIG_LPS */
9192 }
9193
9194 #ifdef CONFIG_IOL
9195 padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
9196 #endif
9197 return err;
9198 }
9199
9200
9201 #ifdef CONFIG_MP_INCLUDED
9202 static int rtw_mp_efuse_set(struct net_device *dev,
9203 struct iw_request_info *info,
9204 union iwreq_data *wdata, char *extra)
9205 {
9206 struct iw_point *wrqu;
9207 PADAPTER padapter;
9208 struct pwrctrl_priv *pwrctrlpriv ;
9209 PHAL_DATA_TYPE pHalData;
9210 PEFUSE_HAL pEfuseHal;
9211 struct hal_ops *pHalFunc;
9212 struct mp_priv *pmp_priv;
9213
9214 u8 ips_mode = IPS_NUM; /* init invalid value */
9215 u8 lps_mode = PS_MODE_NUM; /* init invalid value */
9216 u32 i = 0, j = 0, jj, kk;
9217 u8 *setdata = NULL;
9218 u8 *ShadowMapBT = NULL;
9219 u8 *ShadowMapWiFi = NULL;
9220 u8 *setrawdata = NULL;
9221 char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
9222 u16 addr = 0xFF, cnts = 0, BTStatus = 0 , max_available_len = 0;
9223 u16 wifimaplen;
9224 int err;
9225 boolean bcmpchk = _TRUE;
9226
9227
9228 wrqu = (struct iw_point *)wdata;
9229 padapter = rtw_netdev_priv(dev);
9230 pwrctrlpriv = adapter_to_pwrctl(padapter);
9231 pHalData = GET_HAL_DATA(padapter);
9232 pEfuseHal = &pHalData->EfuseHal;
9233 pHalFunc = &padapter->hal_func;
9234 pmp_priv = &padapter->mppriv;
9235
9236 err = 0;
9237
9238 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9239 return -EFAULT;
9240 #ifdef CONFIG_RTL8822C
9241 rtw_pre_bt_efuse(padapter);
9242 #endif
9243 *(extra + wrqu->length) = '\0';
9244
9245 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&wifimaplen, _FALSE);
9246
9247 setdata = rtw_zmalloc(1024);
9248 if (setdata == NULL) {
9249 err = -ENOMEM;
9250 goto exit;
9251 }
9252 ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9253 if (ShadowMapBT == NULL) {
9254 err = -ENOMEM;
9255 goto exit;
9256 }
9257 ShadowMapWiFi = rtw_malloc(wifimaplen);
9258 if (ShadowMapWiFi == NULL) {
9259 err = -ENOMEM;
9260 goto exit;
9261 }
9262 setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9263 if (setrawdata == NULL) {
9264 err = -ENOMEM;
9265 goto exit;
9266 }
9267
9268 #ifdef CONFIG_LPS
9269 lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
9270 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
9271 #endif
9272
9273 #ifdef CONFIG_IPS
9274 ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
9275 rtw_pm_set_ips(padapter, IPS_NONE);
9276 #endif
9277
9278 pch = extra;
9279 RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
9280
9281 i = 0;
9282 while ((token = strsep(&pch, ",")) != NULL) {
9283 if (i > 2)
9284 break;
9285 tmp[i] = token;
9286 i++;
9287 }
9288
9289 /* tmp[0],[1],[2] */
9290 /* wmap,addr,00e04c871200 */
9291 if (strcmp(tmp[0], "wmap") == 0) {
9292 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9293 err = -EINVAL;
9294 goto exit;
9295 }
9296
9297 #ifndef RTW_HALMAC
9298 /* unknown bug workaround, need to fix later */
9299 addr = 0x1ff;
9300 rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9301 rtw_msleep_os(10);
9302 rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9303 rtw_msleep_os(10);
9304 rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9305 rtw_msleep_os(10);
9306 rtw_read8(padapter, EFUSE_CTRL);
9307 #endif /* RTW_HALMAC */
9308
9309 addr = simple_strtoul(tmp[1], &ptmp, 16);
9310 addr &= 0xFFF;
9311
9312 cnts = strlen(tmp[2]);
9313 if (cnts % 2) {
9314 err = -EINVAL;
9315 goto exit;
9316 }
9317 cnts /= 2;
9318 if (cnts == 0) {
9319 err = -EINVAL;
9320 goto exit;
9321 }
9322
9323 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9324 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9325 RTW_INFO("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9326
9327 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9328 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9329
9330 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9331
9332 if ((addr + cnts) > max_available_len) {
9333 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9334 err = -EFAULT;
9335 goto exit;
9336 }
9337
9338 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9339 RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9340 err = -EFAULT;
9341 goto exit;
9342 }
9343 *extra = 0;
9344 RTW_INFO("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__);
9345 if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS) {
9346 if (_rtw_memcmp((void *)ShadowMapWiFi , (void *)setdata, cnts)) {
9347 RTW_INFO("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9348 sprintf(extra, "WiFi write map compare OK\n");
9349 err = 0;
9350 goto exit;
9351 } else {
9352 sprintf(extra, "WiFi write map compare FAIL\n");
9353 RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9354 err = 0;
9355 goto exit;
9356 }
9357 }
9358 } else if (strcmp(tmp[0], "wraw") == 0) {
9359 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9360 err = -EINVAL;
9361 goto exit;
9362 }
9363
9364 addr = simple_strtoul(tmp[1], &ptmp, 16);
9365 addr &= 0xFFF;
9366
9367 cnts = strlen(tmp[2]);
9368 if (cnts % 2) {
9369 err = -EINVAL;
9370 goto exit;
9371 }
9372 cnts /= 2;
9373 if (cnts == 0) {
9374 err = -EINVAL;
9375 goto exit;
9376 }
9377
9378 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9379 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9380 RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9381
9382 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9383 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9384
9385 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9386 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9387 err = -EFAULT;
9388 goto exit;
9389 }
9390 } else if (strcmp(tmp[0], "btwraw") == 0) {
9391 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9392 err = -EINVAL;
9393 goto exit;
9394 }
9395
9396 addr = simple_strtoul(tmp[1], &ptmp, 16);
9397 addr &= 0xFFF;
9398
9399 cnts = strlen(tmp[2]);
9400 if (cnts % 2) {
9401 err = -EINVAL;
9402 goto exit;
9403 }
9404 cnts /= 2;
9405 if (cnts == 0) {
9406 err = -EINVAL;
9407 goto exit;
9408 }
9409
9410 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9411 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9412 RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9413
9414 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9415 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9416 #ifdef RTW_HALMAC
9417 if (rtw_efuse_bt_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9418 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9419 err = -EFAULT;
9420 goto exit;
9421 }
9422 #else
9423 rtw_write8(padapter, 0x35, 1); /* switch bank 1 (BT)*/
9424 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9425 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9426 rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9427 err = -EFAULT;
9428 goto exit;
9429 }
9430 rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9431 #endif
9432 } else if (strcmp(tmp[0], "mac") == 0) {
9433 if (tmp[1] == NULL) {
9434 err = -EINVAL;
9435 goto exit;
9436 }
9437
9438 /* mac,00e04c871200 */
9439
9440 if (hal_efuse_macaddr_offset(padapter) == -1) {
9441 err = -EFAULT;
9442 goto exit;
9443 }
9444
9445 addr = hal_efuse_macaddr_offset(padapter);
9446 cnts = strlen(tmp[1]);
9447 if (cnts % 2) {
9448 err = -EINVAL;
9449 goto exit;
9450 }
9451 cnts /= 2;
9452 if (cnts == 0) {
9453 err = -EINVAL;
9454 goto exit;
9455 }
9456 if (cnts > 6) {
9457 RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9458 err = -EFAULT;
9459 goto exit;
9460 }
9461
9462 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9463 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9464 RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9465
9466 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9467 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9468
9469 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9470
9471 if ((addr + cnts) > max_available_len) {
9472 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9473 err = -EFAULT;
9474 goto exit;
9475 }
9476
9477 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9478 RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9479 err = -EFAULT;
9480 goto exit;
9481 }
9482 } else if (strcmp(tmp[0], "vidpid") == 0) {
9483 if (tmp[1] == NULL) {
9484 err = -EINVAL;
9485 goto exit;
9486 }
9487
9488 /* pidvid,da0b7881 */
9489 #ifdef CONFIG_RTL8188E
9490 #ifdef CONFIG_USB_HCI
9491 addr = EEPROM_VID_88EU;
9492 #endif
9493 #ifdef CONFIG_PCI_HCI
9494 addr = EEPROM_VID_88EE;
9495 #endif
9496 #endif /* CONFIG_RTL8188E */
9497
9498 #ifdef CONFIG_RTL8192E
9499 #ifdef CONFIG_USB_HCI
9500 addr = EEPROM_VID_8192EU;
9501 #endif
9502 #ifdef CONFIG_PCI_HCI
9503 addr = EEPROM_VID_8192EE;
9504 #endif
9505 #endif /* CONFIG_RTL8188E */
9506
9507 #ifdef CONFIG_RTL8723B
9508 addr = EEPROM_VID_8723BU;
9509 #endif
9510
9511 #ifdef CONFIG_RTL8188F
9512 addr = EEPROM_VID_8188FU;
9513 #endif
9514
9515 #ifdef CONFIG_RTL8188GTV
9516 addr = EEPROM_VID_8188GTVU;
9517 #endif
9518
9519 #ifdef CONFIG_RTL8703B
9520 #ifdef CONFIG_USB_HCI
9521 addr = EEPROM_VID_8703BU;
9522 #endif /* CONFIG_USB_HCI */
9523 #endif /* CONFIG_RTL8703B */
9524
9525 #ifdef CONFIG_RTL8723D
9526 #ifdef CONFIG_USB_HCI
9527 addr = EEPROM_VID_8723DU;
9528 #endif /* CONFIG_USB_HCI */
9529 #endif /* CONFIG_RTL8723D */
9530
9531 cnts = strlen(tmp[1]);
9532 if (cnts % 2) {
9533 err = -EINVAL;
9534 goto exit;
9535 }
9536 cnts /= 2;
9537 if (cnts == 0) {
9538 err = -EINVAL;
9539 goto exit;
9540 }
9541
9542 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9543 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9544 RTW_INFO("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
9545
9546 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9547 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9548
9549 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9550 if ((addr + cnts) > max_available_len) {
9551 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9552 err = -EFAULT;
9553 goto exit;
9554 }
9555
9556 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9557 RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9558 err = -EFAULT;
9559 goto exit;
9560 }
9561 } else if (strcmp(tmp[0], "wldumpfake") == 0) {
9562 if (wifimaplen > EFUSE_MAX_MAP_LEN)
9563 cnts = EFUSE_MAX_MAP_LEN;
9564 else
9565 cnts = wifimaplen;
9566 if (rtw_efuse_mask_map_read(padapter, 0, cnts, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS)
9567 RTW_INFO("%s: WiFi hw efuse dump to Fake map success\n", __func__);
9568 else {
9569 RTW_INFO("%s: WiFi hw efuse dump to Fake map Fail\n", __func__);
9570 err = -EFAULT;
9571 }
9572 } else if (strcmp(tmp[0], "btwmap") == 0) {
9573 rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
9574 BTStatus = rtw_read8(padapter, 0xa0);
9575 RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9576 if (BTStatus != 0x04) {
9577 sprintf(extra, "BT Status not Active ,can't do Write\n");
9578 goto exit;
9579 }
9580
9581 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9582 err = -EINVAL;
9583 goto exit;
9584 }
9585
9586 #ifndef RTW_HALMAC
9587 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9588 addr = 0x1ff;
9589 rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9590 rtw_msleep_os(10);
9591 rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9592 rtw_msleep_os(10);
9593 rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9594 rtw_msleep_os(10);
9595 rtw_read8(padapter, EFUSE_CTRL);
9596 BTEfuse_PowerSwitch(padapter, 1, _FALSE);
9597 #endif /* RTW_HALMAC */
9598
9599 addr = simple_strtoul(tmp[1], &ptmp, 16);
9600 addr &= 0xFFF;
9601
9602 cnts = strlen(tmp[2]);
9603 if (cnts % 2) {
9604 err = -EINVAL;
9605 goto exit;
9606 }
9607 cnts /= 2;
9608 if (cnts == 0) {
9609 err = -EINVAL;
9610 goto exit;
9611 }
9612
9613 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9614 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9615 RTW_INFO("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
9616
9617 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9618 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9619 #ifndef RTW_HALMAC
9620 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9621 if ((addr + cnts) > max_available_len) {
9622 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9623 err = -EFAULT;
9624 goto exit;
9625 }
9626 #endif
9627 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9628 RTW_INFO("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
9629 sprintf(extra, "BT write FAIL !!!\n");
9630 err = -EFAULT;
9631 goto exit;
9632 }
9633 *extra = 0;
9634 RTW_INFO("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __FUNCTION__);
9635 if ((rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT) == _SUCCESS)) {
9636 if (_rtw_memcmp((void *)ShadowMapBT , (void *)setdata, cnts)) {
9637 RTW_INFO("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9638 sprintf(extra, "BT write map compare OK");
9639 err = 0;
9640 goto exit;
9641 } else {
9642 sprintf(extra, "BT write map compare FAIL");
9643 RTW_INFO("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9644 err = 0;
9645 goto exit;
9646 }
9647 }
9648 } else if (strcmp(tmp[0], "btwfake") == 0) {
9649 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9650 err = -EINVAL;
9651 goto exit;
9652 }
9653 if (pmp_priv->bprocess_mp_mode != _TRUE) {
9654 RTW_INFO("%s: btwfake not to be exec, please first to mp_start\n", __FUNCTION__);
9655 sprintf(extra, "Error, btwfake cant to be exec, please first to mp_start !!!!\n");
9656 err = 0;
9657 goto exit;
9658 }
9659 addr = simple_strtoul(tmp[1], &ptmp, 16);
9660 addr &= 0xFFF;
9661
9662 cnts = strlen(tmp[2]);
9663 if (cnts % 2) {
9664 err = -EINVAL;
9665 goto exit;
9666 }
9667 cnts /= 2;
9668 if (cnts == 0) {
9669 err = -EINVAL;
9670 goto exit;
9671 }
9672
9673 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9674 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9675 RTW_INFO("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
9676
9677 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9678 pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9679 } else if (strcmp(tmp[0], "btdumpfake") == 0) {
9680 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS)
9681 RTW_INFO("%s: BT read all map success\n", __FUNCTION__);
9682 else {
9683 RTW_INFO("%s: BT read all map Fail!\n", __FUNCTION__);
9684 err = -EFAULT;
9685 }
9686 } else if (strcmp(tmp[0], "btfk2map") == 0) {
9687 #ifdef CONFIG_BT_EFUSE_MASK
9688 if (padapter->registrypriv.bBTFileMaskEfuse != _TRUE && pmp_priv->bloadBTefusemap == _TRUE) {
9689 RTW_INFO("%s: File BT eFuse mask file not to be loaded\n", __FUNCTION__);
9690 sprintf(extra, "Not load BT eFuse mask file yet, Please advance to use [ efuse_bt_mask ], now remove the Adapter.!!!!\n");
9691 rtw_set_surprise_removed(padapter);
9692 err = 0;
9693 goto exit;
9694 }
9695 #endif
9696 rtw_write8(padapter, 0xa3, 0x05);
9697 BTStatus = rtw_read8(padapter, 0xa0);
9698 RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9699 if (BTStatus != 0x04) {
9700 sprintf(extra, "BT Status not Active Write FAIL\n");
9701 goto exit;
9702 }
9703 if (pmp_priv->bprocess_mp_mode != _TRUE) {
9704 RTW_INFO("%s: btfk2map not to be exec, please first to mp_start\n", __FUNCTION__);
9705 sprintf(extra, "Error, btfk2map cant to be exec, please first to mp_start !!!!\n");
9706 err = 0;
9707 goto exit;
9708 }
9709 #ifndef RTW_HALMAC
9710 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9711 addr = 0x1ff;
9712 rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9713 rtw_msleep_os(10);
9714 rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9715 rtw_msleep_os(10);
9716 rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9717 rtw_msleep_os(10);
9718 rtw_read8(padapter, EFUSE_CTRL);
9719 BTEfuse_PowerSwitch(padapter, 1, _FALSE);
9720 #endif /* RTW_HALMAC */
9721
9722 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {
9723 RTW_INFO("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
9724 sprintf(extra, "BT write FAIL !!!\n");
9725 err = -EFAULT;
9726 goto exit;
9727 }
9728
9729 RTW_INFO("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
9730 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
9731 printk("0x%02x\t", i);
9732 for (j = 0; j < 8; j++)
9733 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9734 printk("\t");
9735
9736 for (; j < 16; j++)
9737 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9738 printk("\n");
9739 }
9740 printk("\n");
9741 #if 1
9742 err = -EFAULT;
9743 RTW_INFO("%s: rtw_BT_efuse_map_read _rtw_memcmp\n", __FUNCTION__);
9744 if ((rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)) {
9745 if (_rtw_memcmp((void *)pEfuseHal->fakeBTEfuseModifiedMap, (void *)pEfuseHal->fakeBTEfuseInitMap, EFUSE_BT_MAX_MAP_LEN)) {
9746 sprintf(extra, "BT write map compare OK");
9747 RTW_INFO("%s: BT write map afterf compare success BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9748 err = 0;
9749 goto exit;
9750 } else {
9751 sprintf(extra, "BT write map compare FAIL");
9752 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
9753 RTW_INFO("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__, i);
9754
9755 if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS) {
9756 RTW_INFO("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
9757
9758 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
9759 printk("0x%02x\t", i);
9760 for (j = 0; j < 8; j++)
9761 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
9762 printk("\t");
9763 for (; j < 16; j++)
9764 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
9765 printk("\n");
9766 }
9767 printk("\n");
9768 }
9769 RTW_INFO("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9770 goto exit;
9771 }
9772 }
9773 #endif
9774
9775 } else if (strcmp(tmp[0], "wlfk2map") == 0) {
9776 *extra = 0;
9777
9778 if (padapter->registrypriv.bFileMaskEfuse != _TRUE && pmp_priv->bloadefusemap == _TRUE) {
9779 RTW_INFO("%s: File eFuse mask file not to be loaded\n", __FUNCTION__);
9780 sprintf(extra, "Not load eFuse mask file yet, Please use the efuse_mask CMD, now remove the interface !!!!\n");
9781 rtw_set_surprise_removed(padapter);
9782 err = 0;
9783 goto exit;
9784 }
9785
9786 if (pmp_priv->bprocess_mp_mode != _TRUE) {
9787 RTW_INFO("%s: wlfk2map not to be exec, please first to mp_start\n", __FUNCTION__);
9788 sprintf(extra, "Error, wlfk2map cant to be exec, please first to mp_start !!!!\n");
9789 err = 0;
9790 goto exit;
9791 }
9792 if (wifimaplen > EFUSE_MAX_MAP_LEN)
9793 cnts = EFUSE_MAX_MAP_LEN;
9794 else
9795 cnts = wifimaplen;
9796 if (rtw_efuse_map_write(padapter, 0x00, cnts, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {
9797 RTW_INFO("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
9798 err = -EFAULT;
9799 goto exit;
9800 }
9801
9802 if (rtw_efuse_mask_map_read(padapter, 0x00, wifimaplen, ShadowMapWiFi) == _SUCCESS) {
9803 addr = 0x00;
9804 err = _TRUE;
9805
9806 for (i = 0; i < cnts; i++) {
9807 if (padapter->registrypriv.boffefusemask == 0) {
9808 if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {
9809 if (rtw_file_efuse_IsMasked(padapter, addr + i, maskfileBuffer) == _TRUE) /*use file efuse mask. */
9810 bcmpchk = _FALSE;
9811 } else {
9812 if (efuse_IsMasked(padapter, addr + i) == _TRUE)
9813 bcmpchk = _FALSE;
9814 }
9815 }
9816
9817 if (bcmpchk == _TRUE) {
9818 RTW_INFO("compare readMapWiFi[0x%02x] = %x, ModifiedMap = %x\n", addr + i, ShadowMapWiFi[ addr + i], pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9819 if (_rtw_memcmp((void *) &ShadowMapWiFi[addr + i], (void *)&pEfuseHal->fakeEfuseModifiedMap[addr + i], 1) == _FALSE){
9820 err = _FALSE;
9821 break;
9822 }
9823 }
9824 bcmpchk = _TRUE;
9825 }
9826 }
9827
9828 if (err) {
9829 RTW_INFO("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
9830 sprintf(extra, "WiFi write map compare OK\n");
9831 err = 0;
9832 goto exit;
9833 } else {
9834 sprintf(extra, "WiFi write map compare FAIL\n");
9835 RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9836 err = 0;
9837 goto exit;
9838 }
9839 } else if (strcmp(tmp[0], "wlwfake") == 0) {
9840 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9841 err = -EINVAL;
9842 goto exit;
9843 }
9844 if (pmp_priv->bprocess_mp_mode != _TRUE) {
9845 RTW_INFO("%s: wlwfake not to be exec, please first to mp_start\n", __FUNCTION__);
9846 sprintf(extra, "Error, wlwfake cant to be exec, please first to mp_start !!!!\n");
9847 err = 0;
9848 goto exit;
9849 }
9850 addr = simple_strtoul(tmp[1], &ptmp, 16);
9851 addr &= 0xFFF;
9852
9853 cnts = strlen(tmp[2]);
9854 if (cnts % 2) {
9855 err = -EINVAL;
9856 goto exit;
9857 }
9858 cnts /= 2;
9859 if (cnts == 0) {
9860 err = -EINVAL;
9861 goto exit;
9862 }
9863
9864 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9865 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9866 RTW_INFO("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
9867
9868 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9869 pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9870 _rtw_memset(extra, '\0', strlen(extra));
9871 sprintf(extra, "wlwfake OK\n");
9872
9873 }
9874 else if (strcmp(tmp[0], "wfakemac") == 0) {
9875 if (tmp[1] == NULL) {
9876 err = -EINVAL;
9877 goto exit;
9878 }
9879 if (pmp_priv->bprocess_mp_mode != _TRUE) {
9880 RTW_INFO("%s: wfakemac not to be exec, please first to mp_start\n", __FUNCTION__);
9881 sprintf(extra, "Error, wfakemac cant to be exec, please first to mp_start !!!!\n");
9882 err = 0;
9883 goto exit;
9884 }
9885 /* wfakemac,00e04c871200 */
9886 if (hal_efuse_macaddr_offset(padapter) == -1) {
9887 err = -EFAULT;
9888 goto exit;
9889 }
9890
9891 addr = hal_efuse_macaddr_offset(padapter);
9892 cnts = strlen(tmp[1]);
9893 if (cnts % 2) {
9894 err = -EINVAL;
9895 goto exit;
9896 }
9897 cnts /= 2;
9898 if (cnts == 0) {
9899 err = -EINVAL;
9900 goto exit;
9901 }
9902 if (cnts > 6) {
9903 RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9904 err = -EFAULT;
9905 goto exit;
9906 }
9907
9908 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9909 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9910 RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9911
9912 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9913 if ((addr + jj) < EFUSE_MAX_MAP_LEN)
9914 pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9915
9916 _rtw_memset(extra, '\0', strlen(extra));
9917 sprintf(extra, "write mac addr to fake map OK\n");
9918 } else if(strcmp(tmp[0], "update") == 0) {
9919 RTW_INFO("To Use new eFuse map ver3\n");
9920
9921 if (tmp[1] != 0x00) {
9922 if (strcmp(tmp[1], "fake") == 0) {
9923 pmp_priv->efuse_update_on = _TRUE;
9924 RTW_INFO("Set efuse update without file\n");
9925 } else if (strcmp(tmp[1], "phy") == 0) {
9926 pmp_priv->efuse_update_file = _FALSE;
9927 pmp_priv->efuse_update_on = _FALSE;
9928 RTW_INFO("Set efuse update with phy\n");
9929 } else {
9930 pmp_priv->efuse_update_file = _TRUE;
9931 strcpy(pmp_priv->efuse_file_path , tmp[1]);
9932 RTW_INFO("Got file path %s\n", pmp_priv->efuse_file_path);
9933 }
9934 }
9935 /*step read efuse/eeprom data and get mac_addr*/
9936 if (padapter->hal_func.read_adapter_info(padapter)) {
9937 _rtw_memset(extra, '\0', strlen(extra));
9938 #ifdef CONFIG_TXPWR_PG_WITH_PWR_IDX
9939 if (pHalData->txpwr_pg_mode == TXPWR_PG_WITH_PWR_IDX)
9940 hal_load_txpwr_info(padapter);
9941 #endif
9942 phy_load_tx_power_ext_info(padapter, 1);
9943 sprintf(extra, "eFuse Update OK\n");
9944 RTW_INFO("eFuse Update OK\n");
9945 } else {
9946 _rtw_memset(extra, '\0', strlen(extra));
9947 sprintf(extra, "eFuse Update FAIL\n");
9948 RTW_INFO("eFuse Update FAIL\n");
9949 }
9950
9951 RTW_INFO("To Use new eFuse map ver3 done\n");
9952 } else if (strcmp(tmp[0], "analyze") == 0) {
9953
9954 rtw_efuse_analyze(padapter, EFUSE_WIFI, 0);
9955 _rtw_memset(extra, '\0', strlen(extra));
9956 sprintf(extra, "eFuse Analyze OK,please to check kernel log\n");
9957 }
9958 exit:
9959 if (setdata)
9960 rtw_mfree(setdata, 1024);
9961 if (ShadowMapBT)
9962 rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
9963 if (ShadowMapWiFi)
9964 rtw_mfree(ShadowMapWiFi, wifimaplen);
9965 if (setrawdata)
9966 rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
9967
9968 wrqu->length = strlen(extra);
9969
9970 if (padapter->registrypriv.mp_mode == 0) {
9971 #ifdef CONFIG_IPS
9972 rtw_pm_set_ips(padapter, ips_mode);
9973 #endif /* CONFIG_IPS */
9974
9975 #ifdef CONFIG_LPS
9976 rtw_pm_set_lps(padapter, lps_mode);
9977 #endif /* CONFIG_LPS */
9978 }
9979
9980 return err;
9981 }
9982
9983 #ifdef CONFIG_RTW_CUSTOMER_STR
9984 static int rtw_mp_customer_str(
9985 struct net_device *dev,
9986 struct iw_request_info *info,
9987 union iwreq_data *wrqu, char *extra)
9988 {
9989 _adapter *adapter = rtw_netdev_priv(dev);
9990 u32 len;
9991 u8 *pbuf = NULL, *pch;
9992 char *ptmp;
9993 u8 param[RTW_CUSTOMER_STR_LEN];
9994 u8 count = 0;
9995 u8 tmp;
9996 u8 i;
9997 u32 pos;
9998 u8 ret;
9999 u8 read = 0;
10000
10001 if (adapter->registrypriv.mp_mode != 1
10002 || !adapter->registrypriv.mp_customer_str)
10003 return -EFAULT;
10004
10005 len = wrqu->data.length + 1;
10006
10007 pbuf = (u8 *)rtw_zmalloc(len);
10008 if (pbuf == NULL) {
10009 RTW_WARN("%s: no memory!\n", __func__);
10010 return -ENOMEM;
10011 }
10012
10013 if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length)) {
10014 rtw_mfree(pbuf, len);
10015 RTW_WARN("%s: copy from user fail!\n", __func__);
10016 return -EFAULT;
10017 }
10018 RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
10019
10020 ptmp = (char *)pbuf;
10021 pch = strsep(&ptmp, ",");
10022 if ((pch == NULL) || (strlen(pch) == 0)) {
10023 rtw_mfree(pbuf, len);
10024 RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
10025 return -EFAULT;
10026 }
10027
10028 _rtw_memset(param, 0xFF, RTW_CUSTOMER_STR_LEN);
10029
10030 if (strcmp(pch, "read") == 0) {
10031 read = 1;
10032 ret = rtw_hal_customer_str_read(adapter, param);
10033
10034 } else if (strcmp(pch, "write") == 0) {
10035 do {
10036 pch = strsep(&ptmp, ":");
10037 if ((pch == NULL) || (strlen(pch) == 0))
10038 break;
10039 if (strlen(pch) != 2
10040 || IsHexDigit(*pch) == _FALSE
10041 || IsHexDigit(*(pch + 1)) == _FALSE
10042 || sscanf(pch, "%hhx", &tmp) != 1
10043 ) {
10044 RTW_WARN("%s: invalid 8-bit hex!\n", __func__);
10045 rtw_mfree(pbuf, len);
10046 return -EFAULT;
10047 }
10048
10049 param[count++] = tmp;
10050
10051 } while (count < RTW_CUSTOMER_STR_LEN);
10052
10053 if (count == 0) {
10054 rtw_mfree(pbuf, len);
10055 RTW_WARN("%s: no input!\n", __func__);
10056 return -EFAULT;
10057 }
10058 ret = rtw_hal_customer_str_write(adapter, param);
10059 } else {
10060 rtw_mfree(pbuf, len);
10061 RTW_INFO("%s: parameter error(unknown cmd)!\n", __func__);
10062 return -EFAULT;
10063 }
10064
10065 pos = sprintf(extra, "%s: ", read ? "read" : "write");
10066 if (read == 0 || ret == _SUCCESS) {
10067 for (i = 0; i < RTW_CUSTOMER_STR_LEN; i++)
10068 pos += sprintf(extra + pos, "%02x:", param[i]);
10069 extra[pos] = 0;
10070 pos--;
10071 }
10072 pos += sprintf(extra + pos, " %s", ret == _SUCCESS ? "OK" : "FAIL");
10073
10074 wrqu->data.length = strlen(extra) + 1;
10075
10076 rtw_mfree(pbuf, len);
10077 return 0;
10078 }
10079 #endif /* CONFIG_RTW_CUSTOMER_STR */
10080
10081 static int rtw_priv_mp_set(struct net_device *dev,
10082 struct iw_request_info *info,
10083 union iwreq_data *wdata, char *extra)
10084 {
10085
10086 struct iw_point *wrqu = (struct iw_point *)wdata;
10087 u32 subcmd = wrqu->flags;
10088 PADAPTER padapter = rtw_netdev_priv(dev);
10089 int status = 0;
10090
10091 #ifdef CONFIG_CONCURRENT_MODE
10092 if (!is_primary_adapter(padapter)) {
10093 RTW_INFO("MP mode only primary Adapter support\n");
10094 return -EIO;
10095 }
10096 #endif
10097
10098 RTW_INFO("%s mutx in %d\n", __func__, subcmd);
10099 _enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10100 switch (subcmd) {
10101 case CTA_TEST:
10102 RTW_INFO("set CTA_TEST\n");
10103 status = rtw_cta_test_start(dev, info, wdata, extra);
10104 break;
10105 case MP_DISABLE_BT_COEXIST:
10106 RTW_INFO("set case MP_DISABLE_BT_COEXIST\n");
10107 status = rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
10108 break;
10109 case MP_IQK:
10110 RTW_INFO("set MP_IQK\n");
10111 status = rtw_mp_iqk(dev, info, wrqu, extra);
10112 break;
10113 case MP_LCK:
10114 RTW_INFO("set MP_LCK\n");
10115 status = rtw_mp_lck(dev, info, wrqu, extra);
10116 break;
10117
10118 default:
10119 status = -EIO;
10120 }
10121 _exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10122 RTW_INFO("%s mutx done %d\n", __func__, subcmd);
10123
10124 return status;
10125 }
10126
10127 static int rtw_priv_mp_get(struct net_device *dev,
10128 struct iw_request_info *info,
10129 union iwreq_data *wdata, char *extra)
10130 {
10131
10132 struct iw_point *wrqu = (struct iw_point *)wdata;
10133 u32 subcmd = wrqu->flags;
10134 PADAPTER padapter = rtw_netdev_priv(dev);
10135 int status = 0;
10136
10137 #ifdef CONFIG_CONCURRENT_MODE
10138 if (!is_primary_adapter(padapter)) {
10139 RTW_INFO("MP mode only primary Adapter support\n");
10140 return -EIO;
10141 }
10142 #endif
10143
10144 RTW_INFO("%s mutx in %d\n", __func__, subcmd);
10145 _enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10146
10147 switch (subcmd) {
10148 case MP_START:
10149 RTW_INFO("set case mp_start\n");
10150 status = rtw_mp_start(dev, info, wrqu, extra);
10151 break;
10152 case MP_STOP:
10153 RTW_INFO("set case mp_stop\n");
10154 status = rtw_mp_stop(dev, info, wrqu, extra);
10155 break;
10156 case MP_BANDWIDTH:
10157 RTW_INFO("set case mp_bandwidth\n");
10158 status = rtw_mp_bandwidth(dev, info, wrqu, extra);
10159 break;
10160 case MP_RESET_STATS:
10161 RTW_INFO("set case MP_RESET_STATS\n");
10162 status = rtw_mp_reset_stats(dev, info, wrqu, extra);
10163 break;
10164 case MP_SetRFPathSwh:
10165 RTW_INFO("set MP_SetRFPathSwitch\n");
10166 status = rtw_mp_SetRFPath(dev, info, wrqu, extra);
10167 break;
10168 case WRITE_REG:
10169 status = rtw_mp_write_reg(dev, info, wrqu, extra);
10170 break;
10171 case WRITE_RF:
10172 status = rtw_mp_write_rf(dev, info, wrqu, extra);
10173 break;
10174 case MP_PHYPARA:
10175 RTW_INFO("mp_get MP_PHYPARA\n");
10176 status = rtw_mp_phypara(dev, info, wrqu, extra);
10177 break;
10178 case MP_CHANNEL:
10179 RTW_INFO("set case mp_channel\n");
10180 status = rtw_mp_channel(dev , info, wrqu, extra);
10181 break;
10182 case MP_CHL_OFFSET:
10183 RTW_INFO("set case mp_ch_offset\n");
10184 status = rtw_mp_ch_offset(dev , info, wrqu, extra);
10185 break;
10186 case READ_REG:
10187 RTW_INFO("mp_get READ_REG\n");
10188 status = rtw_mp_read_reg(dev, info, wrqu, extra);
10189 break;
10190 case READ_RF:
10191 RTW_INFO("mp_get READ_RF\n");
10192 status = rtw_mp_read_rf(dev, info, wrqu, extra);
10193 break;
10194 case MP_RATE:
10195 RTW_INFO("set case mp_rate\n");
10196 status = rtw_mp_rate(dev, info, wrqu, extra);
10197 break;
10198 case MP_TXPOWER:
10199 RTW_INFO("set case MP_TXPOWER\n");
10200 status = rtw_mp_txpower(dev, info, wrqu, extra);
10201 break;
10202 case MP_ANT_TX:
10203 RTW_INFO("set case MP_ANT_TX\n");
10204 status = rtw_mp_ant_tx(dev, info, wrqu, extra);
10205 break;
10206 case MP_ANT_RX:
10207 RTW_INFO("set case MP_ANT_RX\n");
10208 status = rtw_mp_ant_rx(dev, info, wrqu, extra);
10209 break;
10210 case MP_QUERY:
10211 status = rtw_mp_trx_query(dev, info, wrqu, extra);
10212 break;
10213 case MP_CTX:
10214 RTW_INFO("set case MP_CTX\n");
10215 status = rtw_mp_ctx(dev, info, wrqu, extra);
10216 break;
10217 case MP_ARX:
10218 RTW_INFO("set case MP_ARX\n");
10219 status = rtw_mp_arx(dev, info, wrqu, extra);
10220 break;
10221 case MP_DUMP:
10222 RTW_INFO("set case MP_DUMP\n");
10223 status = rtw_mp_dump(dev, info, wrqu, extra);
10224 break;
10225 case MP_PSD:
10226 RTW_INFO("set case MP_PSD\n");
10227 status = rtw_mp_psd(dev, info, wrqu, extra);
10228 break;
10229 case MP_THER:
10230 RTW_INFO("set case MP_THER\n");
10231 status = rtw_mp_thermal(dev, info, wrqu, extra);
10232 break;
10233 case MP_PwrCtlDM:
10234 RTW_INFO("set MP_PwrCtlDM\n");
10235 status = rtw_mp_PwrCtlDM(dev, info, wrqu, extra);
10236 break;
10237 case MP_QueryDrvStats:
10238 RTW_INFO("mp_get MP_QueryDrvStats\n");
10239 status = rtw_mp_QueryDrv(dev, info, wdata, extra);
10240 break;
10241 case MP_PWRTRK:
10242 RTW_INFO("set case MP_PWRTRK\n");
10243 status = rtw_mp_pwrtrk(dev, info, wrqu, extra);
10244 break;
10245 case MP_SET_TSSIDE:
10246 RTW_INFO("set case MP_TSSI_DE\n");
10247 status = rtw_mp_set_tsside(dev, info, wrqu, extra);
10248 break;
10249 #ifdef CONFIG_MP_INCLUDED
10250 case EFUSE_SET:
10251 RTW_INFO("set case efuse set\n");
10252 status = rtw_mp_efuse_set(dev, info, wdata, extra);
10253 break;
10254 #endif
10255 case EFUSE_GET:
10256 RTW_INFO("efuse get EFUSE_GET\n");
10257 status = rtw_mp_efuse_get(dev, info, wdata, extra);
10258 break;
10259 case MP_GET_TXPOWER_INX:
10260 RTW_INFO("mp_get MP_GET_TXPOWER_INX\n");
10261 status = rtw_mp_txpower_index(dev, info, wrqu, extra);
10262 break;
10263 case MP_GETVER:
10264 RTW_INFO("mp_get MP_GETVER\n");
10265 status = rtw_mp_getver(dev, info, wdata, extra);
10266 break;
10267 case MP_MON:
10268 RTW_INFO("mp_get MP_MON\n");
10269 status = rtw_mp_mon(dev, info, wdata, extra);
10270 break;
10271 case EFUSE_BT_MASK:
10272 RTW_INFO("mp_get EFUSE_BT_MASK\n");
10273 status = rtw_bt_efuse_mask_file(dev, info, wdata, extra);
10274 break;
10275 case EFUSE_MASK:
10276 RTW_INFO("mp_get EFUSE_MASK\n");
10277 status = rtw_efuse_mask_file(dev, info, wdata, extra);
10278 break;
10279 case EFUSE_FILE:
10280 RTW_INFO("mp_get EFUSE_FILE\n");
10281 status = rtw_efuse_file_map(dev, info, wdata, extra);
10282 break;
10283 case EFUSE_FILE_STORE:
10284 #if !defined(CONFIG_RTW_ANDROID_GKI)
10285 RTW_INFO("mp_get EFUSE_FILE_STORE\n");
10286 status = rtw_efuse_file_map_store(dev, info, wdata, extra);
10287 #else
10288 RTW_ERR("Android GKI doesn't support: mp_get EFUSE_FILE_STORE\n");
10289 #endif /* !defined(CONFIG_RTW_ANDROID_GKI) */
10290 break;
10291 case MP_TX:
10292 RTW_INFO("mp_get MP_TX\n");
10293 status = rtw_mp_tx(dev, info, wdata, extra);
10294 break;
10295 case MP_RX:
10296 RTW_INFO("mp_get MP_RX\n");
10297 status = rtw_mp_rx(dev, info, wdata, extra);
10298 break;
10299 case MP_HW_TX_MODE:
10300 RTW_INFO("mp_get MP_HW_TX_MODE\n");
10301 status = rtw_mp_hwtx(dev, info, wdata, extra);
10302 break;
10303 case MP_GET_TSSIDE:
10304 RTW_INFO("mp_get TSSI_DE\n");
10305 status = rtw_mp_get_tsside(dev, info, wrqu, extra);
10306 break;
10307 #ifdef CONFIG_RTW_CUSTOMER_STR
10308 case MP_CUSTOMER_STR:
10309 RTW_INFO("customer str\n");
10310 status = rtw_mp_customer_str(dev, info, wdata, extra);
10311 break;
10312 #endif
10313 case MP_PWRLMT:
10314 RTW_INFO("mp_get MP_SETPWRLMT\n");
10315 status = rtw_mp_pwrlmt(dev, info, wdata, extra);
10316 break;
10317 case MP_PWRBYRATE:
10318 RTW_INFO("mp_get MP_SETPWRBYRATE\n");
10319 status = rtw_mp_pwrbyrate(dev, info, wdata, extra);
10320 break;
10321 case BT_EFUSE_FILE:
10322 RTW_INFO("mp_get BT EFUSE_FILE\n");
10323 status = rtw_bt_efuse_file_map(dev, info, wdata, extra);
10324 break;
10325 case MP_SWRFPath:
10326 RTW_INFO("mp_get MP_SWRFPath\n");
10327 status = rtw_mp_switch_rf_path(dev, info, wrqu, extra);
10328 break;
10329 case MP_LINK:
10330 RTW_INFO("mp_get MP_LINK\n");
10331 status = rtw_mp_link(dev, info, wrqu, extra);
10332 break;
10333 case MP_DPK_TRK:
10334 RTW_INFO("mp_get MP_DPK_TRK\n");
10335 status = rtw_mp_dpk_track(dev, info, wdata, extra);
10336 break;
10337 case MP_DPK:
10338 RTW_INFO("set MP_DPK\n");
10339 status = rtw_mp_dpk(dev, info, wdata, extra);
10340 break;
10341 default:
10342 status = -EIO;
10343 }
10344
10345 _exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10346 RTW_INFO("%s mutx done_%d\n", __func__, subcmd);
10347
10348 return status;
10349 }
10350 #endif /*#if defined(CONFIG_MP_INCLUDED)*/
10351
10352
10353 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
10354 #define DBG_MP_SDIO_INDIRECT_ACCESS 1
10355 static int rtw_mp_sd_iread(struct net_device *dev
10356 , struct iw_request_info *info
10357 , struct iw_point *wrqu
10358 , char *extra)
10359 {
10360 char input[16];
10361 u8 width;
10362 unsigned long addr;
10363 u32 ret = 0;
10364 PADAPTER padapter = rtw_netdev_priv(dev);
10365
10366 if (wrqu->length > 16) {
10367 RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10368 ret = -EINVAL;
10369 goto exit;
10370 }
10371
10372 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10373 RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10374 ret = -EFAULT;
10375 goto exit;
10376 }
10377
10378 _rtw_memset(extra, 0, wrqu->length);
10379
10380 if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) {
10381 RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10382 ret = -EINVAL;
10383 goto exit;
10384 }
10385
10386 if (addr > 0x3FFF) {
10387 RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10388 ret = -EINVAL;
10389 goto exit;
10390 }
10391
10392 if (DBG_MP_SDIO_INDIRECT_ACCESS)
10393 RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr);
10394
10395 switch (width) {
10396 case 1:
10397 sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr));
10398 wrqu->length = strlen(extra);
10399 break;
10400 case 2:
10401 sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr));
10402 wrqu->length = strlen(extra);
10403 break;
10404 case 4:
10405 sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr));
10406 wrqu->length = strlen(extra);
10407 break;
10408 default:
10409 wrqu->length = 0;
10410 ret = -EINVAL;
10411 break;
10412 }
10413
10414 exit:
10415 return ret;
10416 }
10417
10418 static int rtw_mp_sd_iwrite(struct net_device *dev
10419 , struct iw_request_info *info
10420 , struct iw_point *wrqu
10421 , char *extra)
10422 {
10423 char width;
10424 unsigned long addr, data;
10425 int ret = 0;
10426 PADAPTER padapter = rtw_netdev_priv(dev);
10427 char input[32];
10428
10429 if (wrqu->length > 32) {
10430 RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10431 ret = -EINVAL;
10432 goto exit;
10433 }
10434
10435 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10436 RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10437 ret = -EFAULT;
10438 goto exit;
10439 }
10440
10441 _rtw_memset(extra, 0, wrqu->length);
10442
10443 if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) {
10444 RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10445 ret = -EINVAL;
10446 goto exit;
10447 }
10448
10449 if (addr > 0x3FFF) {
10450 RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10451 ret = -EINVAL;
10452 goto exit;
10453 }
10454
10455 if (DBG_MP_SDIO_INDIRECT_ACCESS)
10456 RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data);
10457
10458 switch (width) {
10459 case 1:
10460 if (data > 0xFF) {
10461 ret = -EINVAL;
10462 break;
10463 }
10464 rtw_sd_iwrite8(padapter, addr, data);
10465 break;
10466 case 2:
10467 if (data > 0xFFFF) {
10468 ret = -EINVAL;
10469 break;
10470 }
10471 rtw_sd_iwrite16(padapter, addr, data);
10472 break;
10473 case 4:
10474 rtw_sd_iwrite32(padapter, addr, data);
10475 break;
10476 default:
10477 wrqu->length = 0;
10478 ret = -EINVAL;
10479 break;
10480 }
10481
10482 exit:
10483 return ret;
10484 }
10485 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
10486
10487 static int rtw_priv_set(struct net_device *dev,
10488 struct iw_request_info *info,
10489 union iwreq_data *wdata, char *extra)
10490 {
10491 struct iw_point *wrqu = (struct iw_point *)wdata;
10492 u32 subcmd = wrqu->flags;
10493 PADAPTER padapter = rtw_netdev_priv(dev);
10494
10495 if (padapter == NULL)
10496 return -ENETDOWN;
10497
10498 if (padapter->bup == _FALSE) {
10499 RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10500 return -ENETDOWN;
10501 }
10502
10503 if (RTW_CANNOT_RUN(padapter)) {
10504 RTW_INFO("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__);
10505 return -ENETDOWN;
10506 }
10507
10508 if (extra == NULL) {
10509 wrqu->length = 0;
10510 return -EIO;
10511 }
10512
10513 if (subcmd < MP_NULL) {
10514 #ifdef CONFIG_MP_INCLUDED
10515 rtw_priv_mp_set(dev, info, wdata, extra);
10516 #endif
10517 return 0;
10518 }
10519
10520 switch (subcmd) {
10521 #ifdef CONFIG_WOWLAN
10522 case MP_WOW_ENABLE:
10523 RTW_INFO("set case MP_WOW_ENABLE: %s\n", extra);
10524
10525 rtw_wowlan_ctrl(dev, info, wdata, extra);
10526 break;
10527 case MP_WOW_SET_PATTERN:
10528 RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra);
10529 rtw_wowlan_set_pattern(dev, info, wdata, extra);
10530 break;
10531 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
10532 case MP_WOW_SET_KEEP_ALIVE_PATTERN:
10533 RTW_INFO("set case MP_WOW_SET_KEEP_ALIVE_PATTERN: %s\n", extra);
10534 rtw_wowlan_set_keep_alive_pattern(dev, info, wdata, extra);
10535 break;
10536 #endif /*CONFIG_WOW_KEEP_ALIVE_PATTERN*/
10537
10538 #endif
10539 #ifdef CONFIG_AP_WOWLAN
10540 case MP_AP_WOW_ENABLE:
10541 RTW_INFO("set case MP_AP_WOW_ENABLE: %s\n", extra);
10542 rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
10543 break;
10544 #endif
10545 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10546 case VENDOR_IE_SET:
10547 RTW_INFO("set case VENDOR_IE_SET\n");
10548 rtw_vendor_ie_set(dev , info , wdata , extra);
10549 break;
10550 #endif
10551 default:
10552 return -EIO;
10553 }
10554
10555 return 0;
10556 }
10557
10558
10559 static int rtw_priv_get(struct net_device *dev,
10560 struct iw_request_info *info,
10561 union iwreq_data *wdata, char *extra)
10562 {
10563 struct iw_point *wrqu = (struct iw_point *)wdata;
10564 u32 subcmd = wrqu->flags;
10565 PADAPTER padapter = rtw_netdev_priv(dev);
10566 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10567 struct dm_struct *p_dm = &pHalData->odmpriv;
10568 struct dm_rf_calibration_struct *p_rf_calibrate_info = &(p_dm->rf_calibrate_info);
10569 struct dm_iqk_info *p_iqk_info = &p_dm->IQK_info;
10570 u32 i = 100;
10571
10572
10573 if (padapter->bup == _FALSE) {
10574 RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10575 return -ENETDOWN;
10576 }
10577
10578 if (RTW_CANNOT_RUN(padapter)) {
10579 RTW_INFO("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__);
10580 return -ENETDOWN;
10581 }
10582
10583 if (extra == NULL) {
10584 wrqu->length = 0;
10585 return -EIO;
10586 }
10587
10588 if (subcmd < MP_NULL) {
10589 #ifdef CONFIG_MP_INCLUDED
10590 while (i > 1) {
10591 if (p_rf_calibrate_info->is_iqk_in_progress) {
10592 rtw_msleep_os(10);
10593 } else {
10594 p_iqk_info->rfk_forbidden = _TRUE;
10595 break;
10596 }
10597 i--;
10598 }
10599 if (subcmd == MP_CHANNEL || subcmd == MP_BANDWIDTH || subcmd == MP_START || subcmd == MP_DPK)
10600 p_iqk_info->rfk_forbidden = _FALSE;
10601 rtw_priv_mp_get(dev, info, wdata, extra);
10602 rtw_msleep_os(10); /* delay 5ms for sending pkt before exit adb shell operation */
10603 p_iqk_info->rfk_forbidden = _FALSE;
10604 #endif
10605 } else {
10606 switch (subcmd) {
10607 #if defined(CONFIG_RTL8723B)
10608 case MP_SetBT:
10609 RTW_INFO("set MP_SetBT\n");
10610 rtw_mp_SetBT(dev, info, wdata, extra);
10611 break;
10612 #endif
10613 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
10614 case MP_SD_IREAD:
10615 rtw_mp_sd_iread(dev, info, wrqu, extra);
10616 break;
10617 case MP_SD_IWRITE:
10618 rtw_mp_sd_iwrite(dev, info, wrqu, extra);
10619 break;
10620 #endif
10621 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10622 case VENDOR_IE_GET:
10623 RTW_INFO("get case VENDOR_IE_GET\n");
10624 rtw_vendor_ie_get(dev , info , wdata , extra);
10625 break;
10626 #endif
10627 case GET_IC_TYPE:
10628 RTW_INFO("get IC Type\n");
10629 rtw_get_ic_type(dev , info , wdata , extra);
10630 break;
10631 default:
10632 return -EIO;
10633 }
10634 }
10635
10636 return 0;
10637 }
10638
10639
10640 #ifdef CONFIG_TDLS
10641 static int rtw_wx_tdls_wfd_enable(struct net_device *dev,
10642 struct iw_request_info *info,
10643 union iwreq_data *wrqu, char *extra)
10644 {
10645 int ret = 0;
10646
10647 #ifdef CONFIG_WFD
10648
10649 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10650
10651 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10652
10653 if (extra[0] == '0')
10654 rtw_tdls_wfd_enable(padapter, 0);
10655 else
10656 rtw_tdls_wfd_enable(padapter, 1);
10657
10658 #endif /* CONFIG_WFD */
10659
10660 return ret;
10661 }
10662
10663 static int rtw_tdls_weaksec(struct net_device *dev,
10664 struct iw_request_info *info,
10665 union iwreq_data *wrqu, char *extra)
10666 {
10667 int ret = 0;
10668
10669 #ifdef CONFIG_TDLS
10670
10671 u8 i, j;
10672 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10673
10674 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10675
10676 if (extra[0] == '0')
10677 padapter->wdinfo.wfd_tdls_weaksec = 0;
10678 else
10679 padapter->wdinfo.wfd_tdls_weaksec = 1;
10680
10681 #endif /* CONFIG_TDLS */
10682
10683 return ret;
10684 }
10685
10686
10687 static int rtw_tdls_enable(struct net_device *dev,
10688 struct iw_request_info *info,
10689 union iwreq_data *wrqu, char *extra)
10690 {
10691 int ret = 0;
10692
10693 #ifdef CONFIG_TDLS
10694 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10695
10696 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10697
10698 if (extra[0] == '0')
10699 rtw_disable_tdls_func(padapter, _TRUE);
10700 else if (extra[0] == '1')
10701 rtw_enable_tdls_func(padapter);
10702 #endif /* CONFIG_TDLS */
10703
10704 return ret;
10705 }
10706
10707 static int rtw_tdls_setup(struct net_device *dev,
10708 struct iw_request_info *info,
10709 union iwreq_data *wrqu, char *extra)
10710 {
10711 int ret = 0;
10712 #ifdef CONFIG_TDLS
10713 u8 i, j;
10714 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10715 struct tdls_txmgmt txmgmt;
10716 #ifdef CONFIG_WFD
10717 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
10718 #endif /* CONFIG_WFD */
10719
10720 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10721
10722 if (wrqu->data.length - 1 != 17) {
10723 RTW_INFO("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length - 1));
10724 return ret;
10725 }
10726
10727 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10728 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10729 txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10730
10731 #ifdef CONFIG_WFD
10732 if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
10733 /* Weak Security situation with AP. */
10734 if (0 == pwdinfo->wfd_tdls_weaksec) {
10735 /* Can't send the tdls setup request out!! */
10736 RTW_INFO("[%s] Current link is not AES, "
10737 "SKIP sending the tdls setup request!!\n", __FUNCTION__);
10738 } else
10739 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10740 } else
10741 #endif /* CONFIG_WFD */
10742 {
10743 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10744 }
10745 #endif /* CONFIG_TDLS */
10746
10747 return ret;
10748 }
10749
10750 static int rtw_tdls_teardown(struct net_device *dev,
10751 struct iw_request_info *info,
10752 union iwreq_data *wrqu, char *extra)
10753 {
10754 int ret = 0;
10755
10756 #ifdef CONFIG_TDLS
10757
10758 u8 i, j;
10759 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10760 struct sta_info *ptdls_sta = NULL;
10761 struct tdls_txmgmt txmgmt;
10762
10763 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10764
10765 if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) {
10766 RTW_INFO("[%s] length:%d != 17 or 19\n",
10767 __FUNCTION__, (wrqu->data.length - 1));
10768 return ret;
10769 }
10770
10771 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10772 for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
10773 txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10774
10775 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
10776
10777 if (ptdls_sta != NULL) {
10778 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
10779 if (wrqu->data.length - 1 == 19)
10780 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
10781 else
10782 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
10783 } else
10784 RTW_INFO("TDLS peer not found\n");
10785 #endif /* CONFIG_TDLS */
10786
10787 return ret;
10788 }
10789
10790 static int rtw_tdls_discovery(struct net_device *dev,
10791 struct iw_request_info *info,
10792 union iwreq_data *wrqu, char *extra)
10793 {
10794 int ret = 0;
10795
10796 #ifdef CONFIG_TDLS
10797
10798 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10799 struct tdls_txmgmt txmgmt;
10800 int i = 0, j = 0;
10801
10802 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10803
10804 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10805 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10806 txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10807
10808 issue_tdls_dis_req(padapter, &txmgmt);
10809
10810 #endif /* CONFIG_TDLS */
10811
10812 return ret;
10813 }
10814
10815 static int rtw_tdls_ch_switch(struct net_device *dev,
10816 struct iw_request_info *info,
10817 union iwreq_data *wrqu, char *extra)
10818 {
10819 int ret = 0;
10820
10821 #ifdef CONFIG_TDLS
10822 #ifdef CONFIG_TDLS_CH_SW
10823 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10824 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
10825 u8 i, j;
10826 struct sta_info *ptdls_sta = NULL;
10827 u8 take_care_iqk;
10828
10829 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10830
10831 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
10832 RTW_INFO("TDLS channel switch is not allowed\n");
10833 return ret;
10834 }
10835
10836 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10837 pchsw_info->addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10838
10839 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr);
10840 if (ptdls_sta == NULL)
10841 return ret;
10842
10843 pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE;
10844
10845 if (ptdls_sta != NULL) {
10846 if (pchsw_info->off_ch_num == 0)
10847 pchsw_info->off_ch_num = 11;
10848 } else
10849 RTW_INFO("TDLS peer not found\n");
10850
10851 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
10852
10853 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
10854 if (take_care_iqk == _TRUE) {
10855 #ifdef CONFIG_TDLS_CH_SW_V2
10856 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE);
10857 #else
10858 u8 central_chnl;
10859 u8 bw_mode;
10860
10861 bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
10862 central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
10863 if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) >= 0)
10864 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
10865 else
10866 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE);
10867 #endif
10868 } else
10869 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
10870
10871 /* issue_tdls_ch_switch_req(padapter, ptdls_sta); */
10872 /* RTW_INFO("issue tdls ch switch req\n"); */
10873
10874 #endif /* CONFIG_TDLS_CH_SW */
10875 #endif /* CONFIG_TDLS */
10876
10877 return ret;
10878 }
10879
10880 static int rtw_tdls_ch_switch_off(struct net_device *dev,
10881 struct iw_request_info *info,
10882 union iwreq_data *wrqu, char *extra)
10883 {
10884 int ret = 0;
10885
10886 #ifdef CONFIG_TDLS
10887 #ifdef CONFIG_TDLS_CH_SW
10888
10889 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10890 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
10891 u8 i, j, mac_addr[ETH_ALEN];
10892 struct sta_info *ptdls_sta = NULL;
10893 struct tdls_txmgmt txmgmt;
10894
10895 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10896
10897 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10898
10899 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
10900 RTW_INFO("TDLS channel switch is not allowed\n");
10901 return ret;
10902 }
10903
10904 if (wrqu->data.length >= 17) {
10905 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10906 mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10907 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
10908 }
10909
10910 if (ptdls_sta == NULL)
10911 return ret;
10912
10913 rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
10914
10915 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
10916 TDLS_CH_SWITCH_ON_STATE |
10917 TDLS_PEER_AT_OFF_STATE);
10918 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
10919
10920 ptdls_sta->ch_switch_time = 0;
10921 ptdls_sta->ch_switch_timeout = 0;
10922 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
10923 _cancel_timer_ex(&ptdls_sta->delay_timer);
10924 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
10925 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
10926
10927 rtw_pm_set_lps(padapter, PS_MODE_MAX);
10928 #endif /* CONFIG_TDLS_CH_SW */
10929 #endif /* CONFIG_TDLS */
10930
10931 return ret;
10932 }
10933
10934 static int rtw_tdls_dump_ch(struct net_device *dev,
10935 struct iw_request_info *info,
10936 union iwreq_data *wrqu, char *extra)
10937 {
10938 int ret = 0;
10939
10940 #ifdef CONFIG_TDLS
10941 #ifdef CONFIG_TDLS_CH_SW
10942 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10943 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10944
10945 RTW_INFO("[%s] dump_stack:%s\n", __FUNCTION__, extra);
10946
10947 extra[wrqu->data.length] = 0x00;
10948 ptdlsinfo->chsw_info.dump_stack = rtw_atoi(extra);
10949
10950 return ret;
10951
10952 #endif
10953 #endif /* CONFIG_TDLS */
10954
10955 return ret;
10956 }
10957
10958 static int rtw_tdls_off_ch_num(struct net_device *dev,
10959 struct iw_request_info *info,
10960 union iwreq_data *wrqu, char *extra)
10961 {
10962 int ret = 0;
10963
10964 #ifdef CONFIG_TDLS
10965 #ifdef CONFIG_TDLS_CH_SW
10966 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10967 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10968
10969 RTW_INFO("[%s] off_ch_num:%s\n", __FUNCTION__, extra);
10970
10971 extra[wrqu->data.length] = 0x00;
10972 ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra);
10973
10974 return ret;
10975
10976 #endif
10977 #endif /* CONFIG_TDLS */
10978
10979 return ret;
10980 }
10981
10982 static int rtw_tdls_ch_offset(struct net_device *dev,
10983 struct iw_request_info *info,
10984 union iwreq_data *wrqu, char *extra)
10985 {
10986 int ret = 0;
10987
10988 #ifdef CONFIG_TDLS
10989 #ifdef CONFIG_TDLS_CH_SW
10990 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10991 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10992
10993 RTW_INFO("[%s] ch_offset:%s\n", __FUNCTION__, extra);
10994
10995 extra[wrqu->data.length] = 0x00;
10996 switch (rtw_atoi(extra)) {
10997 case SCA:
10998 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
10999 break;
11000
11001 case SCB:
11002 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11003 break;
11004
11005 default:
11006 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11007 break;
11008 }
11009
11010 return ret;
11011
11012 #endif
11013 #endif /* CONFIG_TDLS */
11014
11015 return ret;
11016 }
11017
11018 static int rtw_tdls_pson(struct net_device *dev,
11019 struct iw_request_info *info,
11020 union iwreq_data *wrqu, char *extra)
11021 {
11022 int ret = 0;
11023
11024 #ifdef CONFIG_TDLS
11025
11026 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11027 u8 i, j, mac_addr[ETH_ALEN];
11028 struct sta_info *ptdls_sta = NULL;
11029
11030 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11031
11032 for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
11033 mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11034
11035 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11036
11037 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 1, 3, 500);
11038
11039 #endif /* CONFIG_TDLS */
11040
11041 return ret;
11042 }
11043
11044 static int rtw_tdls_psoff(struct net_device *dev,
11045 struct iw_request_info *info,
11046 union iwreq_data *wrqu, char *extra)
11047 {
11048 int ret = 0;
11049
11050 #ifdef CONFIG_TDLS
11051
11052 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11053 u8 i, j, mac_addr[ETH_ALEN];
11054 struct sta_info *ptdls_sta = NULL;
11055
11056 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11057
11058 for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
11059 mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11060
11061 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11062
11063 if (ptdls_sta)
11064 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 0, 3, 500);
11065
11066 #endif /* CONFIG_TDLS */
11067
11068 return ret;
11069 }
11070
11071 static int rtw_tdls_setip(struct net_device *dev,
11072 struct iw_request_info *info,
11073 union iwreq_data *wrqu, char *extra)
11074 {
11075 int ret = 0;
11076
11077 #ifdef CONFIG_TDLS
11078 #ifdef CONFIG_WFD
11079
11080 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11081 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11082 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11083 u8 i = 0, j = 0, k = 0, tag = 0;
11084
11085 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11086
11087 while (i < 4) {
11088 for (j = 0; j < 4; j++) {
11089 if (*(extra + j + tag) == '.' || *(extra + j + tag) == '\0') {
11090 if (j == 1)
11091 pwfd_info->ip_address[i] = convert_ip_addr('0', '0', *(extra + (j - 1) + tag));
11092 if (j == 2)
11093 pwfd_info->ip_address[i] = convert_ip_addr('0', *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
11094 if (j == 3)
11095 pwfd_info->ip_address[i] = convert_ip_addr(*(extra + (j - 3) + tag), *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
11096
11097 tag += j + 1;
11098 break;
11099 }
11100 }
11101 i++;
11102 }
11103
11104 RTW_INFO("[%s] Set IP = %u.%u.%u.%u\n", __FUNCTION__,
11105 ptdlsinfo->wfd_info->ip_address[0],
11106 ptdlsinfo->wfd_info->ip_address[1],
11107 ptdlsinfo->wfd_info->ip_address[2],
11108 ptdlsinfo->wfd_info->ip_address[3]);
11109
11110 #endif /* CONFIG_WFD */
11111 #endif /* CONFIG_TDLS */
11112
11113 return ret;
11114 }
11115
11116 static int rtw_tdls_getip(struct net_device *dev,
11117 struct iw_request_info *info,
11118 union iwreq_data *wrqu, char *extra)
11119 {
11120 int ret = 0;
11121
11122 #ifdef CONFIG_TDLS
11123 #ifdef CONFIG_WFD
11124
11125 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11126 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11127 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11128
11129 RTW_INFO("[%s]\n", __FUNCTION__);
11130
11131 sprintf(extra, "\n\n%u.%u.%u.%u\n",
11132 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11133 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11134
11135 RTW_INFO("[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
11136 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11137 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11138
11139 wrqu->data.length = strlen(extra);
11140
11141 #endif /* CONFIG_WFD */
11142 #endif /* CONFIG_TDLS */
11143
11144 return ret;
11145 }
11146
11147 static int rtw_tdls_getport(struct net_device *dev,
11148 struct iw_request_info *info,
11149 union iwreq_data *wrqu, char *extra)
11150 {
11151
11152 int ret = 0;
11153
11154 #ifdef CONFIG_TDLS
11155 #ifdef CONFIG_WFD
11156
11157 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11158 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11159 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11160
11161 RTW_INFO("[%s]\n", __FUNCTION__);
11162
11163 sprintf(extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport);
11164 RTW_INFO("[%s] remote port = %d\n",
11165 __FUNCTION__, pwfd_info->peer_rtsp_ctrlport);
11166
11167 wrqu->data.length = strlen(extra);
11168
11169 #endif /* CONFIG_WFD */
11170 #endif /* CONFIG_TDLS */
11171
11172 return ret;
11173
11174 }
11175
11176 /* WFDTDLS, for sigma test */
11177 static int rtw_tdls_dis_result(struct net_device *dev,
11178 struct iw_request_info *info,
11179 union iwreq_data *wrqu, char *extra)
11180 {
11181
11182 int ret = 0;
11183
11184 #ifdef CONFIG_TDLS
11185 #ifdef CONFIG_WFD
11186
11187 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11188 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11189
11190 RTW_INFO("[%s]\n", __FUNCTION__);
11191
11192 if (ptdlsinfo->dev_discovered == _TRUE) {
11193 sprintf(extra, "\n\nDis=1\n");
11194 ptdlsinfo->dev_discovered = _FALSE;
11195 }
11196
11197 wrqu->data.length = strlen(extra);
11198
11199 #endif /* CONFIG_WFD */
11200 #endif /* CONFIG_TDLS */
11201
11202 return ret;
11203
11204 }
11205
11206 /* WFDTDLS, for sigma test */
11207 static int rtw_wfd_tdls_status(struct net_device *dev,
11208 struct iw_request_info *info,
11209 union iwreq_data *wrqu, char *extra)
11210 {
11211
11212 int ret = 0;
11213
11214 #ifdef CONFIG_TDLS
11215
11216 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11217 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11218
11219 RTW_INFO("[%s]\n", __FUNCTION__);
11220
11221 sprintf(extra, "\nlink_established:%d\n"
11222 "sta_cnt:%d\n"
11223 "sta_maximum:%d\n"
11224 "cur_channel:%d\n"
11225 "tdls_enable:%d"
11226 #ifdef CONFIG_TDLS_CH_SW
11227 "ch_sw_state:%08x\n"
11228 "chsw_on:%d\n"
11229 "off_ch_num:%d\n"
11230 "cur_time:%d\n"
11231 "ch_offset:%d\n"
11232 "delay_swtich_back:%d"
11233 #endif
11234 ,
11235 ptdlsinfo->link_established, ptdlsinfo->sta_cnt,
11236 ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel,
11237 rtw_is_tdls_enabled(padapter)
11238 #ifdef CONFIG_TDLS_CH_SW
11239 ,
11240 ptdlsinfo->chsw_info.ch_sw_state,
11241 ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on),
11242 ptdlsinfo->chsw_info.off_ch_num,
11243 ptdlsinfo->chsw_info.cur_time,
11244 ptdlsinfo->chsw_info.ch_offset,
11245 ptdlsinfo->chsw_info.delay_switch_back
11246 #endif
11247 );
11248
11249 wrqu->data.length = strlen(extra);
11250
11251 #endif /* CONFIG_TDLS */
11252
11253 return ret;
11254
11255 }
11256
11257 static int rtw_tdls_getsta(struct net_device *dev,
11258 struct iw_request_info *info,
11259 union iwreq_data *wrqu, char *extra)
11260 {
11261
11262 int ret = 0;
11263 #ifdef CONFIG_TDLS
11264 u8 i, j;
11265 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11266 u8 addr[ETH_ALEN] = {0};
11267 char charmac[17];
11268 struct sta_info *ptdls_sta = NULL;
11269
11270 RTW_INFO("[%s] %s %d\n", __FUNCTION__,
11271 (char *)wrqu->data.pointer, wrqu->data.length - 1);
11272
11273 if (copy_from_user(charmac, wrqu->data.pointer + 9, 17)) {
11274 ret = -EFAULT;
11275 goto exit;
11276 }
11277
11278 RTW_INFO("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
11279 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
11280 addr[i] = key_2char2num(*(charmac + j), *(charmac + j + 1));
11281
11282 RTW_INFO("[%s] %d, charmac:%s, addr:"MAC_FMT"\n",
11283 __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
11284 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);
11285 if (ptdls_sta) {
11286 sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state);
11287 RTW_INFO("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
11288 } else {
11289 sprintf(extra, "\n\nNot found this sta\n");
11290 RTW_INFO("\n\nNot found this sta\n");
11291 }
11292 wrqu->data.length = strlen(extra);
11293
11294 exit:
11295 #endif /* CONFIG_TDLS */
11296 return ret;
11297
11298 }
11299
11300 static int rtw_tdls_get_best_ch(struct net_device *dev,
11301 struct iw_request_info *info,
11302 union iwreq_data *wrqu, char *extra)
11303 {
11304 #ifdef CONFIG_FIND_BEST_CHANNEL
11305 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11306 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
11307 u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
11308
11309 for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {
11310 if (rfctl->channel_set[i].ChannelNum == 1)
11311 index_24G = i;
11312 if (rfctl->channel_set[i].ChannelNum == 36)
11313 index_5G = i;
11314 }
11315
11316 for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {
11317 /* 2.4G */
11318 if (rfctl->channel_set[i].ChannelNum == 6 || rfctl->channel_set[i].ChannelNum == 11) {
11319 if (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_24G].rx_count) {
11320 index_24G = i;
11321 best_channel_24G = rfctl->channel_set[i].ChannelNum;
11322 }
11323 }
11324
11325 /* 5G */
11326 if (rfctl->channel_set[i].ChannelNum >= 36
11327 && rfctl->channel_set[i].ChannelNum < 140) {
11328 /* Find primary channel */
11329 if (((rfctl->channel_set[i].ChannelNum - 36) % 8 == 0)
11330 && (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {
11331 index_5G = i;
11332 best_channel_5G = rfctl->channel_set[i].ChannelNum;
11333 }
11334 }
11335
11336 if (rfctl->channel_set[i].ChannelNum >= 149
11337 && rfctl->channel_set[i].ChannelNum < 165) {
11338 /* Find primary channel */
11339 if (((rfctl->channel_set[i].ChannelNum - 149) % 8 == 0)
11340 && (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {
11341 index_5G = i;
11342 best_channel_5G = rfctl->channel_set[i].ChannelNum;
11343 }
11344 }
11345 #if 1 /* debug */
11346 RTW_INFO("The rx cnt of channel %3d = %d\n",
11347 rfctl->channel_set[i].ChannelNum,
11348 rfctl->channel_set[i].rx_count);
11349 #endif
11350 }
11351
11352 sprintf(extra, "\nbest_channel_24G = %d\n", best_channel_24G);
11353 RTW_INFO("best_channel_24G = %d\n", best_channel_24G);
11354
11355 if (index_5G != 0) {
11356 sprintf(extra, "best_channel_5G = %d\n", best_channel_5G);
11357 RTW_INFO("best_channel_5G = %d\n", best_channel_5G);
11358 }
11359
11360 wrqu->data.length = strlen(extra);
11361
11362 #endif
11363
11364 return 0;
11365
11366 }
11367 #endif /*#ifdef CONFIG_TDLS*/
11368 static int rtw_tdls(struct net_device *dev,
11369 struct iw_request_info *info,
11370 union iwreq_data *wrqu, char *extra)
11371 {
11372 int ret = 0;
11373
11374 #ifdef CONFIG_TDLS
11375
11376 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11377
11378 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
11379
11380 if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
11381 RTW_INFO("Discard tdls oper since hal doesn't support tdls\n");
11382 return 0;
11383 }
11384
11385 if (rtw_is_tdls_enabled(padapter) == _FALSE) {
11386 RTW_INFO("TDLS is not enabled\n");
11387 return 0;
11388 }
11389
11390 /* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */
11391
11392 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11393 if (_rtw_memcmp(extra, "wfdenable=", 10)) {
11394 wrqu->data.length -= 10;
11395 rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]);
11396 return ret;
11397 }
11398 }
11399
11400 if (_rtw_memcmp(extra, "weaksec=", 8)) {
11401 wrqu->data.length -= 8;
11402 rtw_tdls_weaksec(dev, info, wrqu, &extra[8]);
11403 return ret;
11404 } else if (_rtw_memcmp(extra, "tdlsenable=", 11)) {
11405 wrqu->data.length -= 11;
11406 rtw_tdls_enable(dev, info, wrqu, &extra[11]);
11407 return ret;
11408 }
11409
11410 if (_rtw_memcmp(extra, "setup=", 6)) {
11411 wrqu->data.length -= 6;
11412 rtw_tdls_setup(dev, info, wrqu, &extra[6]);
11413 } else if (_rtw_memcmp(extra, "tear=", 5)) {
11414 wrqu->data.length -= 5;
11415 rtw_tdls_teardown(dev, info, wrqu, &extra[5]);
11416 } else if (_rtw_memcmp(extra, "dis=", 4)) {
11417 wrqu->data.length -= 4;
11418 rtw_tdls_discovery(dev, info, wrqu, &extra[4]);
11419 } else if (_rtw_memcmp(extra, "swoff=", 6)) {
11420 wrqu->data.length -= 6;
11421 rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]);
11422 } else if (_rtw_memcmp(extra, "sw=", 3)) {
11423 wrqu->data.length -= 3;
11424 rtw_tdls_ch_switch(dev, info, wrqu, &extra[3]);
11425 } else if (_rtw_memcmp(extra, "dumpstack=", 10)) {
11426 wrqu->data.length -= 10;
11427 rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]);
11428 } else if (_rtw_memcmp(extra, "offchnum=", 9)) {
11429 wrqu->data.length -= 9;
11430 rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]);
11431 } else if (_rtw_memcmp(extra, "choffset=", 9)) {
11432 wrqu->data.length -= 9;
11433 rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]);
11434 } else if (_rtw_memcmp(extra, "pson=", 5)) {
11435 wrqu->data.length -= 5;
11436 rtw_tdls_pson(dev, info, wrqu, &extra[5]);
11437 } else if (_rtw_memcmp(extra, "psoff=", 6)) {
11438 wrqu->data.length -= 6;
11439 rtw_tdls_psoff(dev, info, wrqu, &extra[6]);
11440 }
11441
11442 #ifdef CONFIG_WFD
11443 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11444 if (_rtw_memcmp(extra, "setip=", 6)) {
11445 wrqu->data.length -= 6;
11446 rtw_tdls_setip(dev, info, wrqu, &extra[6]);
11447 } else if (_rtw_memcmp(extra, "tprobe=", 6))
11448 issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
11449 }
11450 #endif /* CONFIG_WFD */
11451
11452 #endif /* CONFIG_TDLS */
11453
11454 return ret;
11455 }
11456
11457
11458 static int rtw_tdls_get(struct net_device *dev,
11459 struct iw_request_info *info,
11460 union iwreq_data *wrqu, char *extra)
11461 {
11462 int ret = 0;
11463
11464 #ifdef CONFIG_TDLS
11465
11466 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
11467
11468 if (_rtw_memcmp(wrqu->data.pointer, "ip", 2))
11469 rtw_tdls_getip(dev, info, wrqu, extra);
11470 else if (_rtw_memcmp(wrqu->data.pointer, "port", 4))
11471 rtw_tdls_getport(dev, info, wrqu, extra);
11472 /* WFDTDLS, for sigma test */
11473 else if (_rtw_memcmp(wrqu->data.pointer, "dis", 3))
11474 rtw_tdls_dis_result(dev, info, wrqu, extra);
11475 else if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
11476 rtw_wfd_tdls_status(dev, info, wrqu, extra);
11477 else if (_rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9))
11478 rtw_tdls_getsta(dev, info, wrqu, extra);
11479 else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7))
11480 rtw_tdls_get_best_ch(dev, info, wrqu, extra);
11481 #endif /* CONFIG_TDLS */
11482
11483 return ret;
11484 }
11485
11486 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
11487
11488 #if defined(CONFIG_RTL8188E)
11489 #include <rtl8188e_hal.h>
11490 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11491 #define cal_txdesc_chksum(padapter, desc) rtl8188e_cal_txdesc_chksum(desc)
11492 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11493 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11494 #define fill_default_txdesc rtl8188es_fill_default_txdesc
11495 #endif /* CONFIG_SDIO_HCI */
11496 #endif /* CONFIG_RTL8188E */
11497 #if defined(CONFIG_RTL8723B)
11498 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11499 #define cal_txdesc_chksum(padapter, desc) rtl8723b_cal_txdesc_chksum(desc)
11500 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11501 #define fill_default_txdesc rtl8723b_fill_default_txdesc
11502 #endif /* CONFIG_RTL8723B */
11503
11504 #if defined(CONFIG_RTL8703B)
11505 /* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11506 #define cal_txdesc_chksum(padapter, desc) rtl8703b_cal_txdesc_chksum(desc)
11507 /* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11508 #define fill_default_txdesc rtl8703b_fill_default_txdesc
11509 #endif /* CONFIG_RTL8703B */
11510
11511 #if defined(CONFIG_RTL8723D)
11512 /* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11513 #define cal_txdesc_chksum(padapter, desc) rtl8723d_cal_txdesc_chksum(desc)
11514 /* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11515 #define fill_default_txdesc rtl8723d_fill_default_txdesc
11516 #endif /* CONFIG_RTL8723D */
11517
11518 #if defined(CONFIG_RTL8710B)
11519 #define cal_txdesc_chksum(padapter, desc) rtl8710b_cal_txdesc_chksum(desc)
11520 #define fill_default_txdesc rtl8710b_fill_default_txdesc
11521 #endif /* CONFIG_RTL8710B */
11522
11523 #if defined(CONFIG_RTL8192E)
11524 extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11525 #define cal_txdesc_chksum(padapter, desc) rtl8192e_cal_txdesc_chksum(desc)
11526 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11527 extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11528 #define fill_default_txdesc rtl8192es_fill_default_txdesc
11529 #endif /* CONFIG_SDIO_HCI */
11530 #endif /* CONFIG_RTL8192E */
11531
11532 #if defined(CONFIG_RTL8192F)
11533 /* extern void rtl8192f_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11534 #define cal_txdesc_chksum(padapter, desc) rtl8192f_cal_txdesc_chksum(desc)
11535 /* extern void rtl8192f_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11536 #define fill_default_txdesc rtl8192f_fill_default_txdesc
11537 #endif /* CONFIG_RTL8192F */
11538
11539 #ifdef CONFIG_RTL8723F
11540 #include <../../hal/rtl8723f/rtl8723f.h>
11541
11542 #define REG_LOOPBACK_ENABLE 0x0103
11543 #define LOOKBACK_ENABLE_VALUE 0x0b
11544 #define cal_txdesc_chksum(padapter, desc) rtl8723f_cal_txdesc_chksum(padapter, desc)
11545 #define dump_txdesc_data(padapter, desc) rtl8723f_dbg_dump_tx_desc(padapter, DATA_FRAMETAG, desc);
11546 #define get_rx_desc(rx_desc, rxbuf) rtl8723f_rxdesc2attribute(rx_desc, rxbuf)
11547 #define hal_init rtl8723f_hal_init
11548 #endif /* CONFIG_RTL8723F */
11549
11550 void dbg_dump_pkt(char *s, u8 *buf, u8 len)
11551 {
11552 u8 i, j = 1;
11553
11554 RTW_INFO("%s size = %u\n", s, len);
11555
11556 for (i = 0; (i + 4) < len; i += 4) {
11557 if (j % 4 == 1)
11558 RTW_PRINT("idx:%u:", i);
11559 _RTW_PRINT(" 0x%02x 0x%02x 0x%02x 0x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
11560 if ((j++) % 4 == 0)
11561 _RTW_PRINT("\n");
11562 }
11563
11564 for (; i < len ; i++) {
11565 _RTW_PRINT(" 0x%02x", buf[i]);
11566 }
11567 _RTW_PRINT("\n ================================\n");
11568 }
11569
11570 static s32 initLoopback(PADAPTER padapter)
11571 {
11572 PLOOPBACKDATA ploopback;
11573
11574 if (padapter->ploopback == NULL) {
11575 ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
11576 if (ploopback == NULL)
11577 return -ENOMEM;
11578
11579 _rtw_init_sema(&ploopback->sema, 0);
11580 ploopback->bstop = _TRUE;
11581 ploopback->cnt = 0;
11582 ploopback->size = 300;
11583 _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
11584
11585 padapter->ploopback = ploopback;
11586 }
11587
11588 return 0;
11589 }
11590
11591 static void freeLoopback(PADAPTER padapter)
11592 {
11593 PLOOPBACKDATA ploopback;
11594
11595 ploopback = padapter->ploopback;
11596 if (ploopback) {
11597 rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA));
11598 padapter->ploopback = NULL;
11599 }
11600 }
11601
11602 static s32 initpseudoadhoc(PADAPTER padapter)
11603 {
11604 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
11605 s32 err;
11606
11607 networkType = Ndis802_11IBSS;
11608 err = rtw_set_802_11_infrastructure_mode(padapter, networkType, 0);
11609 if (err == _FALSE)
11610 return _FAIL;
11611
11612 err = rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
11613 if (err == _FAIL)
11614 return _FAIL;
11615
11616 return _SUCCESS;
11617 }
11618
11619 static s32 createpseudoadhoc(PADAPTER padapter)
11620 {
11621 NDIS_802_11_AUTHENTICATION_MODE authmode;
11622 struct mlme_priv *pmlmepriv;
11623 NDIS_802_11_SSID *passoc_ssid;
11624 WLAN_BSSID_EX *pdev_network;
11625 u8 *pibss;
11626 u8 ssid[] = "pseduo_ad-hoc";
11627 s32 err;
11628 _irqL irqL;
11629
11630 pmlmepriv = &padapter->mlmepriv;
11631
11632 authmode = Ndis802_11AuthModeOpen;
11633 err = rtw_set_802_11_authentication_mode(padapter, authmode);
11634 if (err == _FALSE)
11635 return _FAIL;
11636
11637 passoc_ssid = &pmlmepriv->assoc_ssid;
11638 _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
11639 passoc_ssid->SsidLength = sizeof(ssid) - 1;
11640 _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
11641
11642 pdev_network = &padapter->registrypriv.dev_network;
11643 pibss = padapter->registrypriv.dev_network.MacAddress;
11644 _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
11645
11646 rtw_update_registrypriv_dev_network(padapter);
11647 rtw_generate_random_ibss(pibss);
11648
11649 _enter_critical_bh(&pmlmepriv->lock, &irqL);
11650 /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
11651 init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
11652
11653 _exit_critical_bh(&pmlmepriv->lock, &irqL);
11654
11655 #if 0
11656 err = rtw_create_ibss_cmd(padapter, 0);
11657 if (err == _FAIL)
11658 return _FAIL;
11659 #else
11660 {
11661 struct wlan_network *pcur_network;
11662 struct sta_info *psta;
11663
11664 /* 3 create a new psta */
11665 pcur_network = &pmlmepriv->cur_network;
11666
11667 /* clear psta in the cur_network, if any */
11668 psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
11669 if (psta)
11670 rtw_free_stainfo(padapter, psta);
11671
11672 psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
11673 if (psta == NULL)
11674 return _FAIL;
11675
11676 /* 3 join psudo AdHoc */
11677 pcur_network->join_res = 1;
11678 pcur_network->aid = psta->cmn.aid = 1;
11679 _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
11680
11681 /* set msr to WIFI_FW_ADHOC_STATE */
11682 padapter->hw_port = HW_PORT0;
11683 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11684
11685 }
11686 #endif
11687
11688 return _SUCCESS;
11689 }
11690
11691 static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size)
11692 {
11693 struct xmit_priv *pxmitpriv;
11694 struct xmit_frame *pframe;
11695 struct xmit_buf *pxmitbuf;
11696 struct pkt_attrib *pattrib;
11697 struct tx_desc *desc;
11698 u8 *pkt_start, *pkt_end, *ptr;
11699 struct rtw_ieee80211_hdr *hdr;
11700 s32 bmcast;
11701 _irqL irqL;
11702
11703
11704 if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ)
11705 return NULL;
11706
11707 pxmitpriv = &padapter->xmitpriv;
11708 pframe = NULL;
11709
11710 /* 2 1. allocate xmit frame */
11711 pframe = rtw_alloc_xmitframe(pxmitpriv, 0);
11712 if (pframe == NULL)
11713 return NULL;
11714 pframe->padapter = padapter;
11715
11716 /* 2 2. allocate xmit buffer */
11717 _enter_critical_bh(&pxmitpriv->lock, &irqL);
11718 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
11719 _exit_critical_bh(&pxmitpriv->lock, &irqL);
11720 if (pxmitbuf == NULL) {
11721 rtw_free_xmitframe(pxmitpriv, pframe);
11722 return NULL;
11723 }
11724
11725 pframe->pxmitbuf = pxmitbuf;
11726 pframe->buf_addr = pxmitbuf->pbuf;
11727 pxmitbuf->priv_data = pframe;
11728
11729 /* 2 3. update_attrib() */
11730 pattrib = &pframe->attrib;
11731
11732 /* init xmitframe attribute */
11733 _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
11734
11735 pattrib->ether_type = 0x8723;
11736 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
11737 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
11738 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11739 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
11740
11741 /* pattrib->dhcp_pkt = 0;
11742 * pattrib->pktlen = 0; */
11743 pattrib->ack_policy = 0;
11744 /* pattrib->pkt_hdrlen = ETH_HLEN; */
11745 pattrib->hdrlen = WLAN_HDR_A3_LEN;
11746 pattrib->subtype = WIFI_DATA;
11747 pattrib->priority = 0;
11748 pattrib->qsel = pattrib->priority;
11749 /* do_queue_select(padapter, pattrib); */
11750 pattrib->nr_frags = 1;
11751 pattrib->encrypt = 0;
11752 pattrib->bswenc = _FALSE;
11753 pattrib->qos_en = _FALSE;
11754
11755 bmcast = IS_MCAST(pattrib->ra);
11756 if (bmcast)
11757 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
11758 else
11759 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
11760
11761 pattrib->mac_id = pattrib->psta->cmn.mac_id;
11762 pattrib->pktlen = size;
11763 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
11764
11765 /* 2 4. fill TX descriptor */
11766 desc = (struct tx_desc *)pframe->buf_addr;
11767 _rtw_memset(desc, 0, TXDESC_SIZE);
11768
11769 fill_default_txdesc(pframe, (u8 *)desc);
11770
11771 #if 0
11772 /* Hw set sequence number */
11773 ((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable
11774 * ((PTXDESC)desc)->hwseq_sel = 0; */ /* HWSEQ_SEL */
11775
11776 ((PTXDESC)desc)->disdatafb = 1;
11777
11778 /* convert to little endian */
11779 desc->txdw0 = cpu_to_le32(desc->txdw0);
11780 desc->txdw1 = cpu_to_le32(desc->txdw1);
11781 desc->txdw2 = cpu_to_le32(desc->txdw2);
11782 desc->txdw3 = cpu_to_le32(desc->txdw3);
11783 desc->txdw4 = cpu_to_le32(desc->txdw4);
11784 desc->txdw5 = cpu_to_le32(desc->txdw5);
11785 desc->txdw6 = cpu_to_le32(desc->txdw6);
11786 desc->txdw7 = cpu_to_le32(desc->txdw7);
11787 #ifdef CONFIG_PCI_HCI
11788 desc->txdw8 = cpu_to_le32(desc->txdw8);
11789 desc->txdw9 = cpu_to_le32(desc->txdw9);
11790 desc->txdw10 = cpu_to_le32(desc->txdw10);
11791 desc->txdw11 = cpu_to_le32(desc->txdw11);
11792 desc->txdw12 = cpu_to_le32(desc->txdw12);
11793 desc->txdw13 = cpu_to_le32(desc->txdw13);
11794 desc->txdw14 = cpu_to_le32(desc->txdw14);
11795 desc->txdw15 = cpu_to_le32(desc->txdw15);
11796 #endif
11797 #endif
11798
11799 cal_txdesc_chksum(padapter, (u8*)desc);
11800 /* dump_txdesc_data(padapter, (u8*)desc); */
11801
11802 /* 2 5. coalesce */
11803 pkt_start = pframe->buf_addr + TXDESC_SIZE;
11804 pkt_end = pkt_start + pattrib->last_txcmdsz;
11805
11806 /* 3 5.1. make wlan header, make_wlanhdr() */
11807 hdr = (struct rtw_ieee80211_hdr *)pkt_start;
11808 set_frame_sub_type(&hdr->frame_ctl, pattrib->subtype);
11809 _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */
11810 _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */
11811 _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */
11812
11813 /* 3 5.2. make payload */
11814 ptr = pkt_start + pattrib->hdrlen;
11815 get_random_bytes(ptr, pkt_end - ptr);
11816
11817 pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
11818 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
11819 pxmitbuf->ptail += pxmitbuf->len;
11820 #endif
11821
11822 dbg_dump_pkt("TX packet", pxmitbuf->pbuf, pxmitbuf->len);
11823
11824 return pframe;
11825 }
11826
11827 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
11828 {
11829 struct xmit_priv *pxmitpriv;
11830 struct xmit_buf *pxmitbuf;
11831
11832 pxmitpriv = &padapter->xmitpriv;
11833 pxmitbuf = pframe->pxmitbuf;
11834
11835 rtw_free_xmitframe(pxmitpriv, pframe);
11836 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
11837 }
11838
11839 static void printdata(u8 *pbuf, u32 len)
11840 {
11841 u32 i, val;
11842
11843 for (i = 0; (i + 4) <= len; i += 4) {
11844 printk("%08X", *(u32 *)(pbuf + i));
11845 if ((i + 4) & 0x1F)
11846 printk(" ");
11847 else
11848 printk("\n");
11849 }
11850
11851 if (i < len) {
11852 #ifdef CONFIG_BIG_ENDIAN
11853 for (; i < len, i++)
11854 printk("%02X", pbuf + i);
11855 #else /* CONFIG_LITTLE_ENDIAN */
11856 #if 0
11857 val = 0;
11858 _rtw_memcpy(&val, pbuf + i, len - i);
11859 printk("%8X", val);
11860 #else
11861 u8 str[9];
11862 u8 n;
11863 val = 0;
11864 n = len - i;
11865 _rtw_memcpy(&val, pbuf + i, n);
11866 sprintf(str, "%08X", val);
11867 n = (4 - n) * 2;
11868 printk("%8s", str + n);
11869 #endif
11870 #endif /* CONFIG_LITTLE_ENDIAN */
11871 }
11872 printk("\n");
11873 }
11874
11875 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
11876 {
11877 struct rx_pkt_attrib rx_desc;
11878 #if 0
11879 struct recv_stat *prxstat;
11880 struct recv_stat report;
11881 PRXREPORT prxreport;
11882 #endif
11883 u32 rxpktsize;
11884 u8 drvinfosize;
11885 u8 shiftsize;
11886 u8 ret = _FALSE;
11887 u8 skip_len = 4; /* Don't compare the frame control and duration field */
11888 get_rx_desc(&rx_desc, rxbuf);
11889 rxpktsize = rx_desc.pkt_len;
11890 drvinfosize = rx_desc.drvinfo_sz;
11891 shiftsize = rx_desc.shift_sz;
11892
11893 #if 0
11894 prxstat = (struct recv_stat *)rxbuf;
11895 report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
11896 report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
11897 report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
11898 report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
11899 report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
11900 report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
11901
11902 prxreport = (PRXREPORT)&report;
11903 drvinfosize = prxreport->drvinfosize << 3;
11904 rxpktsize = prxreport->pktlen;
11905 #endif
11906
11907 if (rtw_hal_rcr_check(padapter, RCR_APPFCS))
11908 rxpktsize -= IEEE80211_FCS_LEN;
11909
11910 if ((txsz - TXDESC_SIZE) != rxpktsize) {
11911 RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n",
11912 __func__, txsz - TXDESC_SIZE, rxpktsize);
11913 ret = _FALSE;
11914 } else {
11915 ret = _rtw_memcmp(txbuf + TXDESC_SIZE + skip_len, \
11916 rxbuf + RXDESC_SIZE + skip_len + drvinfosize, \
11917 txsz - TXDESC_SIZE - skip_len);
11918 if (ret == _FALSE)
11919 RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__);
11920 }
11921
11922 if (ret == _FALSE) {
11923 RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
11924 __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
11925 dbg_dump_pkt("TX DESC", txbuf, TXDESC_SIZE);
11926 dbg_dump_pkt("TX content", txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
11927
11928 RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
11929 __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
11930 if (rxpktsize != 0) {
11931 dbg_dump_pkt("RX DESC", rxbuf, RXDESC_SIZE);
11932 dbg_dump_pkt("RX drvinfo", rxbuf + RXDESC_SIZE, drvinfosize);
11933 dbg_dump_pkt("RX packet content", rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
11934 } else {
11935 RTW_INFO("%s: RX data size=%d\n", __func__, rxsz);
11936 }
11937 }
11938
11939 return ret;
11940 }
11941
11942 thread_return lbk_thread(thread_context context)
11943 {
11944 s32 err;
11945 PADAPTER padapter;
11946 PLOOPBACKDATA ploopback;
11947 struct xmit_frame *pxmitframe;
11948 u32 cnt, ok, fail, headerlen;
11949 u32 pktsize;
11950 u32 ff_hwaddr;
11951
11952 padapter = (PADAPTER)context;
11953 ploopback = padapter->ploopback;
11954 if (ploopback == NULL)
11955 return -1;
11956 cnt = 0;
11957 ok = 0;
11958 fail = 0;
11959
11960 thread_enter("RTW_LBK_THREAD");
11961 /* daemonize("%s", "RTW_LBK_THREAD"); */
11962 allow_signal(SIGTERM);
11963
11964 do {
11965 if (ploopback->size == 0) {
11966 get_random_bytes(&pktsize, 4);
11967 pktsize = (pktsize % 1535) + 1; /* 1~1535 */
11968 } else
11969 pktsize = ploopback->size;
11970
11971 pxmitframe = createloopbackpkt(padapter, pktsize);
11972 if (pxmitframe == NULL) {
11973 sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
11974 break;
11975 }
11976
11977 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
11978 _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
11979 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
11980 cnt++;
11981 RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
11982 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
11983 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
11984 #endif
11985 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
11986
11987 /* wait for rx pkt */
11988 RTW_INFO("%s: wait for rx packet\n", __func__);
11989 _rtw_down_sema(&ploopback->sema);
11990
11991 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
11992 if (err == _TRUE)
11993 ok++;
11994 else
11995 fail++;
11996
11997 ploopback->txsize = 0;
11998 _rtw_memset(ploopback->txbuf, 0, 0x8000);
11999 ploopback->rxsize = 0;
12000 _rtw_memset(ploopback->rxbuf, 0, 0x8000);
12001
12002 freeloopbackpkt(padapter, pxmitframe);
12003 pxmitframe = NULL;
12004
12005 flush_signals_thread();
12006
12007 if ((ploopback->bstop == _TRUE) ||
12008 ((ploopback->cnt != 0) && (ploopback->cnt == cnt))) {
12009 u32 ok_rate, fail_rate, all;
12010 all = cnt;
12011 ok_rate = (ok * 100) / all;
12012 fail_rate = (fail * 100) / all;
12013 sprintf(ploopback->msg, \
12014 "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)", \
12015 ok_rate, ok, all, fail_rate, fail, all);
12016 break;
12017 }
12018 } while (1);
12019
12020 ploopback->bstop = _TRUE;
12021
12022 thread_exit(NULL);
12023 return 0;
12024 }
12025
12026 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg)
12027 {
12028 PLOOPBACKDATA ploopback;
12029 u32 len;
12030 s32 err;
12031
12032 ploopback = padapter->ploopback;
12033
12034 if (ploopback) {
12035 if (ploopback->bstop == _FALSE) {
12036 ploopback->bstop = _TRUE;
12037 _rtw_up_sema(&ploopback->sema);
12038 }
12039 len = 0;
12040 do {
12041 len = strlen(ploopback->msg);
12042 if (len)
12043 break;
12044 rtw_msleep_os(1);
12045 } while (1);
12046 RTW_INFO("Free loopback, end the test.\n");
12047 _rtw_memcpy(pmsg, ploopback->msg, len + 1);
12048 freeLoopback(padapter);
12049
12050 return;
12051 }
12052
12053 /* disable dynamic algorithm */
12054 #ifndef CONFIG_NO_PHYDM
12055 rtw_phydm_ability_backup(padapter);
12056 rtw_phydm_func_disable_all(padapter);
12057 #endif
12058
12059 /* create pseudo ad-hoc connection */
12060 err = initpseudoadhoc(padapter);
12061 if (err == _FAIL) {
12062 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
12063 return;
12064 }
12065
12066 err = createpseudoadhoc(padapter);
12067 if (err == _FAIL) {
12068 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
12069 return;
12070 }
12071
12072 err = initLoopback(padapter);
12073 if (err) {
12074 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
12075 return;
12076 }
12077
12078 ploopback = padapter->ploopback;
12079
12080 ploopback->bstop = _FALSE;
12081 ploopback->cnt = cnt;
12082 ploopback->size = size;
12083 ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
12084 if (IS_ERR(ploopback->lbkthread)) {
12085 freeLoopback(padapter);
12086 ploopback->lbkthread = NULL;
12087 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
12088 return;
12089 }
12090
12091 sprintf(pmsg, "loopback start! cnt=%d", cnt);
12092 }
12093 #endif /* CONFIG_MAC_LOOPBACK_DRIVER */
12094
12095 static int rtw_test(
12096 struct net_device *dev,
12097 struct iw_request_info *info,
12098 union iwreq_data *wrqu, char *extra)
12099 {
12100 u32 len;
12101 u8 *pbuf, *pch;
12102 char *ptmp;
12103 u8 *delim = ",";
12104 PADAPTER padapter = rtw_netdev_priv(dev);
12105
12106
12107 RTW_INFO("+%s\n", __func__);
12108 len = wrqu->data.length;
12109
12110 pbuf = (u8 *)rtw_zmalloc(len + 1);
12111 if (pbuf == NULL) {
12112 RTW_INFO("%s: no memory!\n", __func__);
12113 return -ENOMEM;
12114 }
12115
12116 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
12117 rtw_mfree(pbuf, len + 1);
12118 RTW_INFO("%s: copy from user fail!\n", __func__);
12119 return -EFAULT;
12120 }
12121
12122 pbuf[len] = '\0';
12123
12124 RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
12125
12126 ptmp = (char *)pbuf;
12127 pch = strsep(&ptmp, delim);
12128 if ((pch == NULL) || (strlen(pch) == 0)) {
12129 rtw_mfree(pbuf, len);
12130 RTW_INFO("%s: parameter error(level 1)!\n", __func__);
12131 return -EFAULT;
12132 }
12133
12134 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
12135 if (strcmp(pch, "init") == 0) {
12136 u8 status;
12137
12138 rtw_clr_drv_stopped(padapter); /* should clear drv_stopped, otherwise driver can't trx */
12139
12140 status = hal_init(padapter);
12141 RTW_INFO("HAL_INIT %s\n", status ? "SUCCESS" : "FAIL");
12142
12143 rtw_write8(padapter, REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE);
12144 RTW_INFO("Write 0x%03x to 0x%02x, enable loopback\n",
12145 REG_LOOPBACK_ENABLE, LOOKBACK_ENABLE_VALUE);
12146
12147 } else if (strcmp(pch, "loopback") == 0) {
12148 s32 cnt = 0;
12149 u32 size = 64;
12150
12151 pch = strsep(&ptmp, delim);
12152 if ((pch == NULL) || (strlen(pch) == 0)) {
12153 rtw_mfree(pbuf, len);
12154 RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12155 return -EFAULT;
12156 }
12157
12158 sscanf(pch, "%d", &cnt);
12159 RTW_INFO("%s: loopback cnt=%d\n", __func__, cnt);
12160
12161 pch = strsep(&ptmp, delim);
12162 if ((pch == NULL) || (strlen(pch) == 0)) {
12163 rtw_mfree(pbuf, len);
12164 RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12165 return -EFAULT;
12166 }
12167
12168 sscanf(pch, "%d", &size);
12169 RTW_INFO("%s: loopback size=%d\n", __func__, size);
12170
12171 loopbackTest(padapter, cnt, size, extra);
12172 wrqu->data.length = strlen(extra) + 1;
12173
12174 goto free_buf;
12175 }
12176 #endif
12177
12178
12179 #ifdef CONFIG_BT_COEXIST
12180 if (strcmp(pch, "bton") == 0) {
12181 rtw_btcoex_SetManualControl(padapter, _FALSE);
12182 goto free_buf;
12183 } else if (strcmp(pch, "btoff") == 0) {
12184 rtw_btcoex_SetManualControl(padapter, _TRUE);
12185 goto free_buf;
12186 } else if (strcmp(pch, "coex_auto") == 0) {
12187 rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_AUTO);
12188 goto free_buf;
12189 } else if (strcmp(pch, "coex_force_freerun") == 0) {
12190 rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_FREERUN);
12191 goto free_buf;
12192 } else if (strcmp(pch, "coex_force_tdma") == 0) {
12193 rtw_btcoex_set_policy_control(padapter, BTCOEX_POLICY_CONTROL_FORCE_TDMA);
12194 goto free_buf;
12195 }
12196 #endif
12197
12198 if (strcmp(pch, "h2c") == 0) {
12199 u8 param[8];
12200 u8 count = 0;
12201 u32 tmp;
12202 u8 i;
12203 u32 pos;
12204 u8 ret;
12205
12206 do {
12207 pch = strsep(&ptmp, delim);
12208 if ((pch == NULL) || (strlen(pch) == 0))
12209 break;
12210
12211 sscanf(pch, "%x", &tmp);
12212 param[count++] = (u8)tmp;
12213 } while (count < 8);
12214
12215 if (count == 0) {
12216 rtw_mfree(pbuf, len);
12217 RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12218 return -EFAULT;
12219 }
12220
12221 ret = rtw_test_h2c_cmd(padapter, param, count);
12222
12223 pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
12224 for (i = 1; i < count; i++)
12225 pos += sprintf(extra + pos, "%02x,", param[i]);
12226 extra[pos] = 0;
12227 pos--;
12228 pos += sprintf(extra + pos, " %s", ret == _FAIL ? "FAIL" : "OK");
12229
12230 wrqu->data.length = strlen(extra) + 1;
12231
12232 goto free_buf;
12233 }
12234
12235 if (strcmp(pch, "dump_mac_reg") == 0) {
12236 mac_reg_dump(RTW_DBGDUMP, padapter);
12237 goto free_buf;
12238 }
12239
12240 free_buf:
12241 rtw_mfree(pbuf, len);
12242 return 0;
12243 }
12244
12245 static iw_handler rtw_handlers[] = {
12246 #ifdef CONFIG_IOCTL_WEXT
12247 NULL, /* SIOCSIWCOMMIT */
12248 rtw_wx_get_name, /* SIOCGIWNAME */
12249 dummy, /* SIOCSIWNWID */
12250 dummy, /* SIOCGIWNWID */
12251 rtw_wx_set_freq, /* SIOCSIWFREQ */
12252 rtw_wx_get_freq, /* SIOCGIWFREQ */
12253 rtw_wx_set_mode, /* SIOCSIWMODE */
12254 rtw_wx_get_mode, /* SIOCGIWMODE */
12255 dummy, /* SIOCSIWSENS */
12256 rtw_wx_get_sens, /* SIOCGIWSENS */
12257 NULL, /* SIOCSIWRANGE */
12258 rtw_wx_get_range, /* SIOCGIWRANGE */
12259 rtw_wx_set_priv, /* SIOCSIWPRIV */
12260 NULL, /* SIOCGIWPRIV */
12261 NULL, /* SIOCSIWSTATS */
12262 NULL, /* SIOCGIWSTATS */
12263 dummy, /* SIOCSIWSPY */
12264 dummy, /* SIOCGIWSPY */
12265 NULL, /* SIOCGIWTHRSPY */
12266 NULL, /* SIOCWIWTHRSPY */
12267 rtw_wx_set_wap, /* SIOCSIWAP */
12268 rtw_wx_get_wap, /* SIOCGIWAP */
12269 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */
12270 dummy, /* SIOCGIWAPLIST -- depricated */
12271 rtw_wx_set_scan, /* SIOCSIWSCAN */
12272 rtw_wx_get_scan, /* SIOCGIWSCAN */
12273 rtw_wx_set_essid, /* SIOCSIWESSID */
12274 rtw_wx_get_essid, /* SIOCGIWESSID */
12275 dummy, /* SIOCSIWNICKN */
12276 rtw_wx_get_nick, /* SIOCGIWNICKN */
12277 NULL, /* -- hole -- */
12278 NULL, /* -- hole -- */
12279 rtw_wx_set_rate, /* SIOCSIWRATE */
12280 rtw_wx_get_rate, /* SIOCGIWRATE */
12281 rtw_wx_set_rts, /* SIOCSIWRTS */
12282 rtw_wx_get_rts, /* SIOCGIWRTS */
12283 rtw_wx_set_frag, /* SIOCSIWFRAG */
12284 rtw_wx_get_frag, /* SIOCGIWFRAG */
12285 dummy, /* SIOCSIWTXPOW */
12286 dummy, /* SIOCGIWTXPOW */
12287 dummy, /* SIOCSIWRETRY */
12288 rtw_wx_get_retry, /* SIOCGIWRETRY */
12289 rtw_wx_set_enc, /* SIOCSIWENCODE */
12290 rtw_wx_get_enc, /* SIOCGIWENCODE */
12291 dummy, /* SIOCSIWPOWER */
12292 rtw_wx_get_power, /* SIOCGIWPOWER */
12293 NULL, /*---hole---*/
12294 NULL, /*---hole---*/
12295 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */
12296 NULL, /* SIOCGWGENIE */
12297 rtw_wx_set_auth, /* SIOCSIWAUTH */
12298 NULL, /* SIOCGIWAUTH */
12299 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
12300 NULL, /* SIOCGIWENCODEEXT */
12301 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */
12302 NULL, /*---hole---*/
12303 #endif
12304 };
12305
12306
12307 static const struct iw_priv_args rtw_private_args[] = {
12308 {
12309 SIOCIWFIRSTPRIV + 0x0,
12310 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
12311 },
12312 {
12313 SIOCIWFIRSTPRIV + 0x1,
12314 IW_PRIV_TYPE_CHAR | 0x7FF,
12315 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
12316 },
12317 {
12318 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
12319 },
12320 {
12321 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
12322 },
12323 {
12324 SIOCIWFIRSTPRIV + 0x4,
12325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
12326 },
12327 {
12328 SIOCIWFIRSTPRIV + 0x5,
12329 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
12330 },
12331 {
12332 SIOCIWFIRSTPRIV + 0x6,
12333 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
12334 },
12335 /* for PLATFORM_MT53XX */
12336 {
12337 SIOCIWFIRSTPRIV + 0x7,
12338 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
12339 },
12340 {
12341 SIOCIWFIRSTPRIV + 0x8,
12342 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
12343 },
12344 {
12345 SIOCIWFIRSTPRIV + 0x9,
12346 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
12347 },
12348
12349 /* for RTK_DMP_PLATFORM */
12350 {
12351 SIOCIWFIRSTPRIV + 0xA,
12352 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
12353 },
12354
12355 {
12356 SIOCIWFIRSTPRIV + 0xB,
12357 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
12358 },
12359 {
12360 SIOCIWFIRSTPRIV + 0xC,
12361 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
12362 },
12363 {
12364 SIOCIWFIRSTPRIV + 0xD,
12365 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
12366 },
12367 #if 0
12368 {
12369 SIOCIWFIRSTPRIV + 0xE, 0, 0, "wowlan_ctrl"
12370 },
12371 #endif
12372 {
12373 SIOCIWFIRSTPRIV + 0x10,
12374 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
12375 },
12376 {
12377 SIOCIWFIRSTPRIV + 0x11,
12378 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
12379 },
12380 {
12381 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
12382 },
12383 {
12384 SIOCIWFIRSTPRIV + 0x13,
12385 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
12386 },
12387 {
12388 SIOCIWFIRSTPRIV + 0x14,
12389 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
12390 },
12391 {
12392 SIOCIWFIRSTPRIV + 0x15,
12393 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
12394 },
12395 {
12396 SIOCIWFIRSTPRIV + 0x16,
12397 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
12398 },
12399 #ifdef CONFIG_RTW_80211K
12400 {
12401 SIOCIWFIRSTPRIV + 0x17,
12402 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "rrm"
12403 },
12404 #else
12405 {SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 1024 , 0 , "NULL"},
12406 #endif
12407
12408 #ifdef CONFIG_PLATFORM_CMAP_INTFS
12409 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | 1024 , 0 , "cmap_intfs"},
12410 #else
12411 {SIOCIWFIRSTPRIV + 0x18, 0, 0, "NULL"},
12412 #endif
12413
12414 #ifdef CONFIG_MP_INCLUDED
12415 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
12416 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
12417 #else
12418 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
12419 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
12420 #endif
12421 {
12422 SIOCIWFIRSTPRIV + 0x1D,
12423 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
12424 },
12425
12426 { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, /* set */
12427 { SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},/* get
12428 * --- sub-ioctls definitions --- */
12429
12430 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
12431 { VENDOR_IE_SET, IW_PRIV_TYPE_CHAR | 1024 , 0 , "vendor_ie_set" },
12432 { VENDOR_IE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "vendor_ie_get" },
12433 #endif
12434 #if defined(CONFIG_RTL8723B)
12435 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
12436 { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
12437 #endif
12438 #ifdef CONFIG_WOWLAN
12439 { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
12440 { MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },
12441 #ifdef CONFIG_WOW_KEEP_ALIVE_PATTERN
12442 { MP_WOW_SET_KEEP_ALIVE_PATTERN ,IW_PRIV_TYPE_CHAR | 1024 , 0 , "wow_keep_alive"},
12443 #endif /* defined (CONFIG_KEEP_ALIVE_PATTERN)*/
12444 #endif
12445
12446 #ifdef CONFIG_AP_WOWLAN
12447 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */
12448 #endif
12449 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
12450 { MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },
12451 { MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },
12452 #endif
12453 { GET_IC_TYPE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "ic_type" },
12454 };
12455
12456
12457 static const struct iw_priv_args rtw_mp_private_args[] = {
12458 /* --- sub-ioctls definitions --- */
12459 #ifdef CONFIG_MP_INCLUDED
12460 { MP_START , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_start" },
12461 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },
12462 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_stop" },
12463 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },
12464 { MP_CHL_OFFSET , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ch_offset" },
12465 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_bandwidth"},
12466 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12467 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_reset_stats"},
12468 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"},
12469 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
12470 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12471 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
12472 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
12473 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
12474 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
12475 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
12476 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
12477 { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
12478 { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
12479 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
12480 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
12481 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
12482 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
12483 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
12484 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrtrk"},
12485 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
12486 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},
12487 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setrfpath" },
12488 { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
12489 { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
12490 { MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },
12491 { MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },
12492 { EFUSE_BT_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_bt_mask" },
12493 { EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },
12494 { EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },
12495 { EFUSE_FILE_STORE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_store" },
12496 { MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },
12497 { MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },
12498 { MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },
12499 { MP_PWRLMT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrlmt" },
12500 { MP_PWRBYRATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrbyrate" },
12501 { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
12502 { MP_IQK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_iqk"},
12503 { MP_LCK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_lck"},
12504 { BT_EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bt_efuse_file" },
12505 { MP_SWRFPath, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_swrfpath" },
12506 { MP_LINK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_link" },
12507 { MP_DPK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk"},
12508 { MP_DPK_TRK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk_trk" },
12509 { MP_GET_TSSIDE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_tsside" },
12510 { MP_SET_TSSIDE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_set_tsside" },
12511 #ifdef CONFIG_RTW_CUSTOMER_STR
12512 { MP_CUSTOMER_STR, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "customer_str" },
12513 #endif
12514
12515 #endif /* CONFIG_MP_INCLUDED */
12516 };
12517
12518 static iw_handler rtw_private_handler[] = {
12519 rtw_wx_write32, /* 0x00 */
12520 rtw_wx_read32, /* 0x01 */
12521 NULL, /* 0x02 */
12522 #ifdef MP_IOCTL_HDL
12523 rtw_mp_ioctl_hdl, /* 0x03 */
12524 #else
12525 rtw_wx_priv_null,
12526 #endif
12527 /* for MM DTV platform */
12528 rtw_get_ap_info, /* 0x04 */
12529
12530 rtw_set_pid, /* 0x05 */
12531 rtw_wps_start, /* 0x06 */
12532
12533 /* for PLATFORM_MT53XX */
12534 rtw_wx_get_sensitivity, /* 0x07 */
12535 rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */
12536 rtw_wx_set_mtk_wps_ie, /* 0x09 */
12537
12538 /* for RTK_DMP_PLATFORM
12539 * Set Channel depend on the country code */
12540 rtw_wx_set_channel_plan, /* 0x0A */
12541
12542 rtw_dbg_port, /* 0x0B */
12543 rtw_wx_write_rf, /* 0x0C */
12544 rtw_wx_read_rf, /* 0x0D */
12545
12546 rtw_priv_set, /*0x0E*/
12547 rtw_priv_get, /*0x0F*/
12548
12549 rtw_p2p_set, /* 0x10 */
12550 rtw_p2p_get, /* 0x11 */
12551 NULL, /* 0x12 */
12552 rtw_p2p_get2, /* 0x13 */
12553
12554 rtw_tdls, /* 0x14 */
12555 rtw_tdls_get, /* 0x15 */
12556
12557 rtw_pm_set, /* 0x16 */
12558 #ifdef CONFIG_RTW_80211K
12559 rtw_wx_priv_rrm, /* 0x17 */
12560 #else
12561 rtw_wx_priv_null, /* 0x17 */
12562 #endif
12563 #ifdef CONFIG_PLATFORM_CMAP_INTFS
12564 cmap_intfs_ioctl, /* 0x18 */
12565 #else
12566 NULL, /* 0x18 */
12567 #endif
12568 rtw_wx_priv_null, /* 0x19 */
12569 #ifdef CONFIG_MP_INCLUDED
12570 rtw_wx_priv_null, /* 0x1A */
12571 rtw_wx_priv_null, /* 0x1B */
12572 #else
12573 rtw_wx_priv_null, /* 0x1A */
12574 rtw_mp_efuse_get, /* 0x1B */
12575 #endif
12576 NULL, /* 0x1C is reserved for hostapd */
12577 rtw_test, /* 0x1D */
12578 };
12579
12580 #ifdef CONFIG_WIRELESS_EXT
12581 #if WIRELESS_EXT >= 17
12582 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
12583 {
12584 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12585 struct iw_statistics *piwstats = &padapter->iwstats;
12586 int tmp_level = 0;
12587 int tmp_qual = 0;
12588 int tmp_noise = 0;
12589
12590 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) != _TRUE) {
12591 piwstats->qual.qual = 0;
12592 piwstats->qual.level = 0;
12593 piwstats->qual.noise = 0;
12594 /* RTW_INFO("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */
12595 } else {
12596 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
12597 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
12598 #else
12599 tmp_level = padapter->recvpriv.signal_strength;
12600 #endif
12601
12602 tmp_qual = padapter->recvpriv.signal_qual;
12603 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
12604 if (IS_NM_ENABLE(padapter)) {
12605 tmp_noise = rtw_noise_measure_curchan(padapter);
12606 #ifndef CONFIG_SIGNAL_DISPLAY_DBM
12607 tmp_noise = translate_dbm_to_percentage(tmp_noise);/*percentage*/
12608 #endif
12609 }
12610 #endif
12611 /* RTW_INFO("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); */
12612
12613 piwstats->qual.level = tmp_level;
12614 piwstats->qual.qual = tmp_qual;
12615 piwstats->qual.noise = tmp_noise;
12616 }
12617 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14))
12618 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* |IW_QUAL_DBM; */
12619 #else
12620 #ifdef RTK_DMP_PLATFORM
12621 /* IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. */
12622 /* remove this flag for show percentage 0~100 */
12623 piwstats->qual.updated = 0x07;
12624 #else
12625 piwstats->qual.updated = 0x0f;
12626 #endif
12627 #endif
12628
12629 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
12630 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
12631 #endif
12632
12633 return &padapter->iwstats;
12634 }
12635 #endif
12636
12637 struct iw_handler_def rtw_handlers_def = {
12638 .standard = rtw_handlers,
12639 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
12640 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) || defined(CONFIG_WEXT_PRIV)
12641 .private = rtw_private_handler,
12642 .private_args = (struct iw_priv_args *)rtw_private_args,
12643 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
12644 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
12645 #endif
12646 #if WIRELESS_EXT >= 17
12647 .get_wireless_stats = rtw_get_wireless_stats,
12648 #endif
12649 };
12650 #endif
12651
12652 /* copy from net/wireless/wext.c start
12653 * ----------------------------------------------------------------
12654 *
12655 * Calculate size of private arguments
12656 */
12657 static const char iw_priv_type_size[] = {
12658 0, /* IW_PRIV_TYPE_NONE */
12659 1, /* IW_PRIV_TYPE_BYTE */
12660 1, /* IW_PRIV_TYPE_CHAR */
12661 0, /* Not defined */
12662 sizeof(__u32), /* IW_PRIV_TYPE_INT */
12663 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
12664 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
12665 0, /* Not defined */
12666 };
12667
12668 static int get_priv_size(__u16 args)
12669 {
12670 int num = args & IW_PRIV_SIZE_MASK;
12671 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
12672
12673 return num * iw_priv_type_size[type];
12674 }
12675 /* copy from net/wireless/wext.c end */
12676
12677
12678 static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
12679 {
12680 int err = 0;
12681 u8 *input = NULL;
12682 u32 input_len = 0;
12683 const char delim[] = " ";
12684 u8 *output = NULL;
12685 u32 output_len = 0;
12686 u32 count = 0;
12687 u8 *buffer = NULL;
12688 u32 buffer_len = 0;
12689 char *ptr = NULL;
12690 u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */
12691 u32 cmdlen;
12692 s32 len;
12693 u8 *extra = NULL;
12694 u32 extra_size = 0;
12695
12696 s32 k;
12697 const iw_handler *priv; /* Private ioctl */
12698 const struct iw_priv_args *priv_args; /* Private ioctl description */
12699 const struct iw_priv_args *mp_priv_args; /*MP Private ioctl description */
12700 const struct iw_priv_args *sel_priv_args; /*Selected Private ioctl description */
12701 u32 num_priv; /* Number of ioctl */
12702 u32 num_priv_args; /* Number of descriptions */
12703 u32 num_mp_priv_args; /*Number of MP descriptions */
12704 u32 num_sel_priv_args; /*Number of Selected descriptions */
12705 iw_handler handler;
12706 int temp;
12707 int subcmd = 0; /* sub-ioctl index */
12708 int offset = 0; /* Space for sub-ioctl index */
12709
12710 union iwreq_data wdata;
12711
12712 _rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
12713
12714 input_len = wdata.data.length;
12715 if (!input_len)
12716 return -EINVAL;
12717 input = rtw_zmalloc(input_len);
12718
12719 if (input == NULL) {
12720 err = -EOPNOTSUPP;
12721 goto exit;
12722 }
12723
12724 if (copy_from_user(input, wdata.data.pointer, input_len)) {
12725 err = -EFAULT;
12726 goto exit;
12727 }
12728 input[input_len - 1] = '\0';
12729 ptr = input;
12730 len = input_len;
12731
12732 sscanf(ptr, "%16s", cmdname);
12733 cmdlen = strlen(cmdname);
12734 RTW_DBG("%s: cmd=%s\n", __func__, cmdname);
12735
12736 /* skip command string */
12737 if (cmdlen > 0)
12738 cmdlen += 1; /* skip one space */
12739 ptr += cmdlen;
12740 len -= cmdlen;
12741 RTW_DBG("%s: parameters=%s\n", __func__, ptr);
12742
12743 priv = rtw_private_handler;
12744 priv_args = rtw_private_args;
12745 mp_priv_args = rtw_mp_private_args;
12746 num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
12747 num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
12748 num_mp_priv_args = sizeof(rtw_mp_private_args) / sizeof(struct iw_priv_args);
12749
12750 if (num_priv_args == 0) {
12751 err = -EOPNOTSUPP;
12752 goto exit;
12753 }
12754
12755 /* Search the correct ioctl */
12756 k = -1;
12757 sel_priv_args = priv_args;
12758 num_sel_priv_args = num_priv_args;
12759 while
12760 ((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12761 ;
12762
12763 /* If not found... */
12764 if (k == num_sel_priv_args) {
12765 k = -1;
12766 sel_priv_args = mp_priv_args;
12767 num_sel_priv_args = num_mp_priv_args;
12768 while
12769 ((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12770 ;
12771
12772 if (k == num_sel_priv_args) {
12773 err = -EOPNOTSUPP;
12774 goto exit;
12775 }
12776 }
12777
12778 /* Watch out for sub-ioctls ! */
12779 if (sel_priv_args[k].cmd < SIOCDEVPRIVATE) {
12780 int j = -1;
12781
12782 /* Find the matching *real* ioctl */
12783 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
12784 (priv_args[j].set_args != sel_priv_args[k].set_args) ||
12785 (priv_args[j].get_args != sel_priv_args[k].get_args)))
12786 ;
12787
12788 /* If not found... */
12789 if (j == num_priv_args) {
12790 err = -EINVAL;
12791 goto exit;
12792 }
12793
12794 /* Save sub-ioctl number */
12795 subcmd = sel_priv_args[k].cmd;
12796 /* Reserve one int (simplify alignment issues) */
12797 offset = sizeof(__u32);
12798 /* Use real ioctl definition from now on */
12799 k = j;
12800 }
12801
12802 buffer = rtw_zmalloc(4096);
12803 if (NULL == buffer) {
12804 err = -ENOMEM;
12805 goto exit;
12806 }
12807
12808 if (k >= num_priv_args) {
12809 err = -EINVAL;
12810 goto exit;
12811 }
12812
12813 /* If we have to set some data */
12814 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
12815 (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
12816 u8 *str;
12817
12818 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
12819 case IW_PRIV_TYPE_BYTE:
12820 /* Fetch args */
12821 count = 0;
12822 do {
12823 str = strsep(&ptr, delim);
12824 if (NULL == str || count >= 4096)
12825 break;
12826 sscanf(str, "%i", &temp);
12827 buffer[count++] = (u8)temp;
12828 } while (1);
12829 buffer_len = count;
12830
12831 /* Number of args to fetch */
12832 wdata.data.length = count;
12833 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12834 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12835
12836 break;
12837
12838 case IW_PRIV_TYPE_INT:
12839 /* Fetch args */
12840 count = 0;
12841 do {
12842 str = strsep(&ptr, delim);
12843 if (NULL == str || count >= 1024)
12844 break;
12845 sscanf(str, "%i", &temp);
12846 ((s32 *)buffer)[count++] = (s32)temp;
12847 } while (1);
12848 buffer_len = count * sizeof(s32);
12849
12850 /* Number of args to fetch */
12851 wdata.data.length = count;
12852 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12853 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12854
12855 break;
12856
12857 case IW_PRIV_TYPE_CHAR:
12858 if (len > 0) {
12859 /* Size of the string to fetch */
12860 wdata.data.length = len;
12861 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12862 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12863
12864 /* Fetch string */
12865 _rtw_memcpy(buffer, ptr, wdata.data.length);
12866 } else {
12867 wdata.data.length = 1;
12868 buffer[0] = '\0';
12869 }
12870 buffer_len = wdata.data.length;
12871 break;
12872
12873 default:
12874 RTW_INFO("%s: Not yet implemented...\n", __func__);
12875 err = -1;
12876 goto exit;
12877 }
12878
12879 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12880 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
12881 RTW_INFO("%s: The command %s needs exactly %d argument(s)...\n",
12882 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
12883 err = -EINVAL;
12884 goto exit;
12885 }
12886 } /* if args to set */
12887 else
12888 wdata.data.length = 0L;
12889
12890 /* Those two tests are important. They define how the driver
12891 * will have to handle the data */
12892 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12893 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
12894 /* First case : all SET args fit within wrq */
12895 if (offset)
12896 wdata.mode = subcmd;
12897 _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
12898 } else {
12899 if ((priv_args[k].set_args == 0) &&
12900 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12901 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
12902 /* Second case : no SET args, GET args fit within wrq */
12903 if (offset)
12904 wdata.mode = subcmd;
12905 } else {
12906 /* Third case : args won't fit in wrq, or variable number of args */
12907 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
12908 err = -EFAULT;
12909 goto exit;
12910 }
12911 wdata.data.flags = subcmd;
12912 }
12913 }
12914
12915 rtw_mfree(input, input_len);
12916 input = NULL;
12917
12918 extra_size = 0;
12919 if (IW_IS_SET(priv_args[k].cmd)) {
12920 /* Size of set arguments */
12921 extra_size = get_priv_size(priv_args[k].set_args);
12922
12923 /* Does it fits in iwr ? */
12924 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12925 ((extra_size + offset) <= IFNAMSIZ))
12926 extra_size = 0;
12927 } else {
12928 /* Size of get arguments */
12929 extra_size = get_priv_size(priv_args[k].get_args);
12930
12931 /* Does it fits in iwr ? */
12932 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12933 (extra_size <= IFNAMSIZ))
12934 extra_size = 0;
12935 }
12936
12937 if (extra_size == 0) {
12938 extra = (u8 *)&wdata;
12939 rtw_mfree(buffer, 4096);
12940 buffer = NULL;
12941 } else
12942 extra = buffer;
12943
12944 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
12945 err = handler(dev, NULL, &wdata, extra);
12946
12947 /* If we have to get some data */
12948 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
12949 (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
12950 int j;
12951 int n = 0; /* number of args */
12952 u8 str[20] = {0};
12953
12954 /* Check where is the returned data */
12955 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12956 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
12957 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
12958 else
12959 n = wdata.data.length;
12960
12961 output = rtw_zmalloc(4096);
12962 if (NULL == output) {
12963 err = -ENOMEM;
12964 goto exit;
12965 }
12966
12967 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
12968 case IW_PRIV_TYPE_BYTE:
12969 /* Display args */
12970 for (j = 0; j < n; j++) {
12971 sprintf(str, "%d ", extra[j]);
12972 len = strlen(str);
12973 output_len = strlen(output);
12974 if ((output_len + len + 1) > 4096) {
12975 err = -E2BIG;
12976 goto exit;
12977 }
12978 _rtw_memcpy(output + output_len, str, len);
12979 }
12980 break;
12981
12982 case IW_PRIV_TYPE_INT:
12983 /* Display args */
12984 for (j = 0; j < n; j++) {
12985 sprintf(str, "%d ", ((__s32 *)extra)[j]);
12986 len = strlen(str);
12987 output_len = strlen(output);
12988 if ((output_len + len + 1) > 4096) {
12989 err = -E2BIG;
12990 goto exit;
12991 }
12992 _rtw_memcpy(output + output_len, str, len);
12993 }
12994 break;
12995
12996 case IW_PRIV_TYPE_CHAR:
12997 /* Display args */
12998 _rtw_memcpy(output, extra, n);
12999 break;
13000
13001 default:
13002 RTW_INFO("%s: Not yet implemented...\n", __func__);
13003 err = -1;
13004 goto exit;
13005 }
13006
13007 output_len = strlen(output) + 1;
13008 wrq_data->data.length = output_len;
13009 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
13010 err = -EFAULT;
13011 goto exit;
13012 }
13013 } /* if args to set */
13014 else
13015 wrq_data->data.length = 0;
13016
13017 exit:
13018 if (input)
13019 rtw_mfree(input, input_len);
13020 if (buffer)
13021 rtw_mfree(buffer, 4096);
13022 if (output)
13023 rtw_mfree(output, 4096);
13024
13025 return err;
13026 }
13027
13028 #ifdef CONFIG_COMPAT
13029 static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)
13030 {
13031 struct compat_iw_point iwp_compat;
13032 union iwreq_data wrq_data;
13033 int err = 0;
13034 RTW_DBG("%s:...\n", __func__);
13035 if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))
13036 return -EFAULT;
13037
13038 wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);
13039 wrq_data.data.length = iwp_compat.length;
13040 wrq_data.data.flags = iwp_compat.flags;
13041
13042 err = _rtw_ioctl_wext_private(dev, &wrq_data);
13043
13044 iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);
13045 iwp_compat.length = wrq_data.data.length;
13046 iwp_compat.flags = wrq_data.data.flags;
13047 if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))
13048 return -EFAULT;
13049
13050 return err;
13051 }
13052 #endif /* CONFIG_COMPAT */
13053
13054 static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)
13055 {
13056 struct iw_point *iwp;
13057 union iwreq_data wrq_data;
13058 int err = 0;
13059 iwp = &wrq_data.data;
13060 RTW_DBG("%s:...\n", __func__);
13061 if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))
13062 return -EFAULT;
13063
13064 err = _rtw_ioctl_wext_private(dev, &wrq_data);
13065
13066 if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))
13067 return -EFAULT;
13068
13069 return err;
13070 }
13071
13072 static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq)
13073 {
13074 #ifdef CONFIG_COMPAT
13075 #if (KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE)
13076 if (is_compat_task())
13077 #else
13078 if (in_compat_syscall())
13079 #endif
13080 return rtw_ioctl_compat_wext_private(dev, rq);
13081 else
13082 #endif /* CONFIG_COMPAT */
13083 return rtw_ioctl_standard_wext_private(dev, rq);
13084 }
13085
13086 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
13087 {
13088 struct iwreq *wrq = (struct iwreq *)rq;
13089 int ret = 0;
13090
13091 switch (cmd) {
13092 #ifdef CONFIG_IOCTL_WEXT
13093 case RTL_IOCTL_WPA_SUPPLICANT:
13094 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
13095 break;
13096 #ifdef CONFIG_AP_MODE
13097 case RTL_IOCTL_HOSTAPD:
13098 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
13099 break;
13100 #ifdef CONFIG_WIRELESS_EXT
13101 case SIOCSIWMODE:
13102 ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
13103 break;
13104 #endif
13105 #endif /* CONFIG_AP_MODE */
13106 #endif /* CONFIG_IOCTL_WEXT */
13107 case SIOCDEVPRIVATE:
13108 ret = rtw_ioctl_wext_private(dev, rq);
13109 break;
13110 case (SIOCDEVPRIVATE+1):
13111 ret = rtw_android_priv_cmd(dev, rq, cmd);
13112 break;
13113 default:
13114 ret = -EOPNOTSUPP;
13115 break;
13116 }
13117
13118 return ret;
13119 }
13120