1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _IOCTL_LINUX_C_
22 #include <drv_types.h>
24 #include <rtw_mp_ioctl.h>
25 #include "../../hal/phydm/phydm_precomp.h"
27 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
28 #define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e)
29 #define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e)
32 #ifdef CONFIG_80211N_HT
33 extern int rtw_ht_enable;
37 #define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)
39 #define SCAN_ITEM_SIZE 768
40 #define MAX_CUSTOM_LEN 64
43 #ifdef CONFIG_GLOBAL_UI_PID
48 #define WEXT_CSCAN_AMOUNT 9
49 #define WEXT_CSCAN_BUF_LEN 360
50 #define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
51 #define WEXT_CSCAN_HEADER_SIZE 12
52 #define WEXT_CSCAN_SSID_SECTION 'S'
53 #define WEXT_CSCAN_CHANNEL_SECTION 'C'
54 #define WEXT_CSCAN_NPROBE_SECTION 'N'
55 #define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
56 #define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
57 #define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
58 #define WEXT_CSCAN_TYPE_SECTION 'T'
61 extern u8 key_2char2num(u8 hch, u8 lch);
62 extern u8 str_2char2num(u8 hch, u8 lch);
63 extern void macstr2num(u8 *dst, u8 *src);
64 extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
66 u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
67 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000
70 static const char *const iw_operation_mode[] = {
71 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor"
74 static int hex2num_i(char c)
76 if (c >= '0' && c <= '9')
78 if (c >= 'a' && c <= 'f')
80 if (c >= 'A' && c <= 'F')
85 static int hex2byte_i(const char *hex)
88 a = hex2num_i(*hex++);
91 b = hex2num_i(*hex++);
98 * hwaddr_aton - Convert ASCII string to MAC address
99 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
100 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
101 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
103 static int hwaddr_aton_i(const char *txt, u8 *addr)
107 for (i = 0; i < 6; i++) {
110 a = hex2num_i(*txt++);
113 b = hex2num_i(*txt++);
116 *addr++ = (a << 4) | b;
117 if (i < 5 && *txt++ != ':')
124 static void indicate_wx_custom_event(_adapter *padapter, char *msg)
127 union iwreq_data wrqu;
129 if (strlen(msg) > IW_CUSTOM_MAX) {
130 RTW_INFO("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);
134 buff = rtw_zmalloc(IW_CUSTOM_MAX + 1);
138 _rtw_memcpy(buff, msg, strlen(msg));
140 _rtw_memset(&wrqu, 0, sizeof(wrqu));
141 wrqu.data.length = strlen(msg);
143 RTW_INFO("%s %s\n", __FUNCTION__, buff);
144 #ifndef CONFIG_IOCTL_CFG80211
145 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
148 rtw_mfree(buff, IW_CUSTOM_MAX + 1);
153 static void request_wps_pbc_event(_adapter *padapter)
156 union iwreq_data wrqu;
159 buff = rtw_malloc(IW_CUSTOM_MAX);
163 _rtw_memset(buff, 0, IW_CUSTOM_MAX);
167 p += sprintf(p, "WPS_PBC_START.request=TRUE");
169 _rtw_memset(&wrqu, 0, sizeof(wrqu));
171 wrqu.data.length = p - buff;
173 wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX;
175 RTW_INFO("%s\n", __FUNCTION__);
177 #ifndef CONFIG_IOCTL_CFG80211
178 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
182 rtw_mfree(buff, IW_CUSTOM_MAX);
186 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
187 void rtw_request_wps_pbc_event(_adapter *padapter)
189 #ifdef RTK_DMP_PLATFORM
190 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
191 kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
193 kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
197 if (padapter->pid[0] == 0) {
198 /* 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. */
202 rtw_signal_process(padapter->pid[0], SIGUSR1);
206 rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
208 #endif/* #ifdef CONFIG_SUPPORT_HW_WPS_PBC */
210 void indicate_wx_scan_complete_event(_adapter *padapter)
212 union iwreq_data wrqu;
213 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
215 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
217 /* RTW_INFO("+rtw_indicate_wx_scan_complete_event\n"); */
218 #ifndef CONFIG_IOCTL_CFG80211
219 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
224 void rtw_indicate_wx_assoc_event(_adapter *padapter)
226 union iwreq_data wrqu;
227 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
228 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
229 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
230 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
232 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
234 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
236 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
237 _rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
239 _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
241 RTW_PRINT("assoc success\n");
242 #ifndef CONFIG_IOCTL_CFG80211
243 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
247 void rtw_indicate_wx_disassoc_event(_adapter *padapter)
249 union iwreq_data wrqu;
251 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
253 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
254 _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
256 #ifndef CONFIG_IOCTL_CFG80211
257 RTW_PRINT("indicate disassoc\n");
258 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
263 uint rtw_is_cckrates_included(u8 *rate)
269 if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
270 (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )
278 uint rtw_is_cckratesonly_included(u8 *rate)
284 if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
285 (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )
294 static int search_p2p_wfd_ie(_adapter *padapter,
295 struct iw_request_info *info, struct wlan_network *pnetwork,
296 char *start, char *stop)
299 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
301 if (SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type) {
303 } else if ((SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type) ||
304 (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type))
305 #endif /* CONFIG_WFD */
307 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
308 u32 blnGotP2PIE = _FALSE;
310 /* User is doing the P2P device discovery */
311 /* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
312 /* If not, the driver should ignore this AP and go to the next AP. */
314 /* Verifying the SSID */
315 if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
318 /* Verifying the P2P IE */
319 if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen))
323 if (blnGotP2PIE == _FALSE)
330 if (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type) {
331 u32 blnGotWFD = _FALSE;
335 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
340 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
342 if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK) {
343 /* the first two bits will indicate the WFD device type */
344 if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_SOURCE) {
345 /* If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. */
348 } else if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE) {
349 /* the first two bits will indicate the WFD device type */
350 if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_PSINK) {
351 /* If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. */
352 /* Todo: How about the SSink?! */
359 if (blnGotWFD == _FALSE)
362 #endif /* CONFIG_WFD */
364 #endif /* CONFIG_P2P */
367 static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,
368 struct iw_request_info *info, struct wlan_network *pnetwork,
369 char *start, char *stop, struct iw_event *iwe)
372 iwe->cmd = SIOCGIWAP;
373 iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
375 _rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
376 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);
379 static inline char *iwe_stream_essid_proess(_adapter *padapter,
380 struct iw_request_info *info, struct wlan_network *pnetwork,
381 char *start, char *stop, struct iw_event *iwe)
385 iwe->cmd = SIOCGIWESSID;
386 iwe->u.data.flags = 1;
387 iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
388 start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
392 static inline char *iwe_stream_chan_process(_adapter *padapter,
393 struct iw_request_info *info, struct wlan_network *pnetwork,
394 char *start, char *stop, struct iw_event *iwe)
396 if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
397 pnetwork->network.Configuration.DSConfig = 1;
399 /* Add frequency/channel */
400 iwe->cmd = SIOCGIWFREQ;
401 iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
403 iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;
404 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);
407 static inline char *iwe_stream_mode_process(_adapter *padapter,
408 struct iw_request_info *info, struct wlan_network *pnetwork,
409 char *start, char *stop, struct iw_event *iwe, u16 cap)
412 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
413 iwe->cmd = SIOCGIWMODE;
414 if (cap & WLAN_CAPABILITY_BSS)
415 iwe->u.mode = IW_MODE_MASTER;
417 iwe->u.mode = IW_MODE_ADHOC;
419 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);
423 static inline char *iwe_stream_encryption_process(_adapter *padapter,
424 struct iw_request_info *info, struct wlan_network *pnetwork,
425 char *start, char *stop, struct iw_event *iwe, u16 cap)
428 /* Add encryption capability */
429 iwe->cmd = SIOCGIWENCODE;
430 if (cap & WLAN_CAPABILITY_PRIVACY)
431 iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
433 iwe->u.data.flags = IW_ENCODE_DISABLED;
434 iwe->u.data.length = 0;
435 start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
440 static inline char *iwe_stream_protocol_process(_adapter *padapter,
441 struct iw_request_info *info, struct wlan_network *pnetwork,
442 char *start, char *stop, struct iw_event *iwe)
444 u16 ht_cap = _FALSE, vht_cap = _FALSE;
445 u32 ht_ielen = 0, vht_ielen = 0;
447 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0 : 12); /* Probe Request */
449 /* parsing HT_CAP_IE */
450 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
451 if (p && ht_ielen > 0)
454 #ifdef CONFIG_80211AC_VHT
455 /* parsing VHT_CAP_IE */
456 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
457 if (p && vht_ielen > 0)
460 /* Add the protocol name */
461 iwe->cmd = SIOCGIWNAME;
462 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
464 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");
466 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");
467 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
469 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");
471 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");
473 if (pnetwork->network.Configuration.DSConfig > 14) {
474 #ifdef CONFIG_80211AC_VHT
475 if (vht_cap == _TRUE)
476 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");
481 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");
483 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");
487 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");
489 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");
492 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);
496 static inline char *iwe_stream_rate_process(_adapter *padapter,
497 struct iw_request_info *info, struct wlan_network *pnetwork,
498 char *start, char *stop, struct iw_event *iwe)
500 u32 ht_ielen = 0, vht_ielen = 0;
502 u16 max_rate = 0, rate, ht_cap = _FALSE, vht_cap = _FALSE;
504 u8 bw_40MHz = 0, short_GI = 0, bw_160MHz = 0, vht_highest_rate = 0;
505 u16 mcs_rate = 0, vht_data_rate = 0;
506 char custom[MAX_CUSTOM_LEN] = {0};
507 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0 : 12); /* Probe Request */
509 /* parsing HT_CAP_IE */
510 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
511 if (p && ht_ielen > 0) {
512 struct rtw_ieee80211_ht_cap *pht_capie;
514 pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
515 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
516 bw_40MHz = (pht_capie->cap_info & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
517 short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
520 #ifdef CONFIG_80211AC_VHT
521 /* parsing VHT_CAP_IE */
522 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
523 if (p && vht_ielen > 0) {
527 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p + 2);
529 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p + 2);
531 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p + 2);
533 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p + 2), 2);
535 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
536 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
540 /*Add basic and extended rates */
542 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
543 while (pnetwork->network.SupportedRates[i] != 0) {
544 rate = pnetwork->network.SupportedRates[i] & 0x7F;
547 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
548 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
551 #ifdef CONFIG_80211AC_VHT
552 if (vht_cap == _TRUE)
553 max_rate = vht_data_rate;
556 if (ht_cap == _TRUE) {
557 if (mcs_rate & 0x8000) /* MCS15 */
558 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
560 else if (mcs_rate & 0x0080) /* MCS7 */
561 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
562 else { /* default MCS7 */
563 /* RTW_INFO("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); */
564 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
567 max_rate = max_rate * 2; /* Mbps/2; */
570 iwe->cmd = SIOCGIWRATE;
571 iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
572 iwe->u.bitrate.value = max_rate * 500000;
573 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);
577 static inline char *iwe_stream_wpa_wpa2_process(_adapter *padapter,
578 struct iw_request_info *info, struct wlan_network *pnetwork,
579 char *start, char *stop, struct iw_event *iwe)
581 int buf_size = MAX_WPA_IE_LEN * 2;
582 /* u8 pbuf[buf_size]={0}; */
583 u8 *pbuf = rtw_zmalloc(buf_size);
585 u8 wpa_ie[255] = {0}, rsn_ie[255] = {0};
586 u16 i, wpa_len = 0, rsn_len = 0;
594 /* parsing WPA/WPA2 IE */
595 if (pnetwork->network.Reserved[0] != 2) { /* Probe Request */
596 out_len = rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
597 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid=%s\n", pnetwork->network.Ssid.Ssid));
598 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n", wpa_len, rsn_len));
602 _rtw_memset(pbuf, 0, buf_size);
603 p += sprintf(p, "wpa_ie=");
604 for (i = 0; i < wpa_len; i++)
605 p += sprintf(p, "%02x", wpa_ie[i]);
608 printk("-----------------Len %d----------------\n", wpa_len);
609 for (i = 0; i < wpa_len; i++)
610 printk("%02x ", wpa_ie[i]);
612 printk("-----------------Len %d----------------\n", wpa_len);
615 _rtw_memset(iwe, 0, sizeof(*iwe));
616 iwe->cmd = IWEVCUSTOM;
617 iwe->u.data.length = strlen(pbuf);
618 start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
620 _rtw_memset(iwe, 0, sizeof(*iwe));
621 iwe->cmd = IWEVGENIE;
622 iwe->u.data.length = wpa_len;
623 start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
627 _rtw_memset(pbuf, 0, buf_size);
628 p += sprintf(p, "rsn_ie=");
629 for (i = 0; i < rsn_len; i++)
630 p += sprintf(p, "%02x", rsn_ie[i]);
631 _rtw_memset(iwe, 0, sizeof(*iwe));
632 iwe->cmd = IWEVCUSTOM;
633 iwe->u.data.length = strlen(pbuf);
634 start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
636 _rtw_memset(iwe, 0, sizeof(*iwe));
637 iwe->cmd = IWEVGENIE;
638 iwe->u.data.length = rsn_len;
639 start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
643 rtw_mfree(pbuf, buf_size);
648 static inline char *iwe_stream_wps_process(_adapter *padapter,
649 struct iw_request_info *info, struct wlan_network *pnetwork,
650 char *start, char *stop, struct iw_event *iwe)
653 uint cnt = 0, total_ielen;
654 u8 *wpsie_ptr = NULL;
656 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0 : 12);
658 u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
659 total_ielen = pnetwork->network.IELength - ie_offset;
661 if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */
662 ie_ptr = pnetwork->network.IEs;
663 total_ielen = pnetwork->network.IELength;
664 } else { /* Beacon or Probe Respones */
665 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
666 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
668 while (cnt < total_ielen) {
669 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
670 wpsie_ptr = &ie_ptr[cnt];
671 iwe->cmd = IWEVGENIE;
672 iwe->u.data.length = (u16)wps_ielen;
673 start = iwe_stream_add_point(info, start, stop, iwe, wpsie_ptr);
675 cnt += ie_ptr[cnt + 1] + 2; /* goto next */
680 static inline char *iwe_stream_wapi_process(_adapter *padapter,
681 struct iw_request_info *info, struct wlan_network *pnetwork,
682 char *start, char *stop, struct iw_event *iwe)
684 #ifdef CONFIG_WAPI_SUPPORT
687 if (pnetwork->network.Reserved[0] != 2) { /* Probe Request */
688 sint out_len_wapi = 0;
689 /* here use static for stack size */
690 static u8 buf_wapi[MAX_WAPI_IE_LEN * 2] = {0};
691 static u8 wapi_ie[MAX_WAPI_IE_LEN] = {0};
695 out_len_wapi = rtw_get_wapi_ie(pnetwork->network.IEs , pnetwork->network.IELength, wapi_ie, &wapi_len);
696 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid=%s\n", pnetwork->network.Ssid.Ssid));
697 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wapi_len=%d\n", wapi_len));
699 RTW_INFO("rtw_wx_get_scan: %s ", pnetwork->network.Ssid.Ssid);
700 RTW_INFO("rtw_wx_get_scan: ssid = %d ", wapi_len);
705 /* _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2); */
706 p += sprintf(p, "wapi_ie=");
707 for (i = 0; i < wapi_len; i++)
708 p += sprintf(p, "%02x", wapi_ie[i]);
710 _rtw_memset(iwe, 0, sizeof(*iwe));
711 iwe->cmd = IWEVCUSTOM;
712 iwe->u.data.length = strlen(buf_wapi);
713 start = iwe_stream_add_point(info, start, stop, iwe, buf_wapi);
715 _rtw_memset(iwe, 0, sizeof(*iwe));
716 iwe->cmd = IWEVGENIE;
717 iwe->u.data.length = wapi_len;
718 start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);
721 #endif/* #ifdef CONFIG_WAPI_SUPPORT */
725 static inline char *iwe_stream_rssi_process(_adapter *padapter,
726 struct iw_request_info *info, struct wlan_network *pnetwork,
727 char *start, char *stop, struct iw_event *iwe)
730 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
732 /* Add quality statistics */
734 iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
735 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
736 | IW_QUAL_NOISE_UPDATED
738 | IW_QUAL_NOISE_INVALID
740 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
745 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
746 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
747 ss = padapter->recvpriv.signal_strength;
748 sq = padapter->recvpriv.signal_qual;
750 ss = pnetwork->network.PhyInfo.SignalStrength;
751 sq = pnetwork->network.PhyInfo.SignalQuality;
755 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
756 iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
758 #ifdef CONFIG_SIGNAL_SCALE_MAPPING
759 iwe->u.qual.level = (u8)ss; /* % */
762 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
764 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
766 iwe->u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
771 iwe->u.qual.qual = (u8)sq; /* signal quality */
773 #ifdef CONFIG_PLATFORM_ROCKCHIPS
774 iwe->u.qual.noise = -100; /* noise level suggest by zhf@rockchips */
776 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
779 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
780 iwe->u.qual.noise = tmp_noise ;
783 iwe->u.qual.noise = 0; /* noise level */
785 #endif /* CONFIG_PLATFORM_ROCKCHIPS */
787 /* 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); */
789 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);
793 static inline char *iwe_stream_net_rsv_process(_adapter *padapter,
794 struct iw_request_info *info, struct wlan_network *pnetwork,
795 char *start, char *stop, struct iw_event *iwe)
801 pos = pnetwork->network.Reserved;
803 p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
804 _rtw_memset(iwe, 0, sizeof(*iwe));
805 iwe->cmd = IWEVCUSTOM;
806 iwe->u.data.length = strlen(buf);
807 start = iwe_stream_add_point(info, start, stop, iwe, buf);
812 static char *translate_scan(_adapter *padapter,
813 struct iw_request_info *info, struct wlan_network *pnetwork,
814 char *start, char *stop)
818 _rtw_memset(&iwe, 0, sizeof(iwe));
820 if (_FALSE == search_p2p_wfd_ie(padapter, info, pnetwork, start, stop))
823 start = iwe_stream_mac_addr_proess(padapter, info, pnetwork, start, stop, &iwe);
824 start = iwe_stream_essid_proess(padapter, info, pnetwork, start, stop, &iwe);
825 start = iwe_stream_protocol_process(padapter, info, pnetwork, start, stop, &iwe);
826 if (pnetwork->network.Reserved[0] == 2) /* Probe Request */
829 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
830 cap = le16_to_cpu(cap);
833 start = iwe_stream_mode_process(padapter, info, pnetwork, start, stop, &iwe, cap);
834 start = iwe_stream_chan_process(padapter, info, pnetwork, start, stop, &iwe);
835 start = iwe_stream_encryption_process(padapter, info, pnetwork, start, stop, &iwe, cap);
836 start = iwe_stream_rate_process(padapter, info, pnetwork, start, stop, &iwe);
837 start = iwe_stream_wpa_wpa2_process(padapter, info, pnetwork, start, stop, &iwe);
838 start = iwe_stream_wps_process(padapter, info, pnetwork, start, stop, &iwe);
839 start = iwe_stream_wapi_process(padapter, info, pnetwork, start, stop, &iwe);
840 start = iwe_stream_rssi_process(padapter, info, pnetwork, start, stop, &iwe);
841 start = iwe_stream_net_rsv_process(padapter, info, pnetwork, start, stop, &iwe);
846 static char *translate_scan(_adapter *padapter,
847 struct iw_request_info *info, struct wlan_network *pnetwork,
848 char *start, char *stop)
852 u32 ht_ielen = 0, vht_ielen = 0;
853 char custom[MAX_CUSTOM_LEN];
855 u16 max_rate = 0, rate, ht_cap = _FALSE, vht_cap = _FALSE;
859 u8 bw_40MHz = 0, short_GI = 0, bw_160MHz = 0, vht_highest_rate = 0;
860 u16 mcs_rate = 0, vht_data_rate = 0;
861 u8 ie_offset = (pnetwork->network.Reserved[0] == 2 ? 0 : 12);
862 struct registry_priv *pregpriv = &padapter->registrypriv;
864 if (_FALSE == search_p2p_wfd_ie(padapter, info, pnetwork, start, stop))
869 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
871 _rtw_memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
872 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
875 iwe.cmd = SIOCGIWESSID;
876 iwe.u.data.flags = 1;
877 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
878 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
880 /* parsing HT_CAP_IE */
881 if (pnetwork->network.Reserved[0] == 2) /* Probe Request */
882 p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength);
884 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - 12);
885 if (p && ht_ielen > 0) {
886 struct rtw_ieee80211_ht_cap *pht_capie;
888 pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
889 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
890 bw_40MHz = (pht_capie->cap_info & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
891 short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
894 #ifdef CONFIG_80211AC_VHT
895 /* parsing VHT_CAP_IE */
896 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
897 if (p && vht_ielen > 0) {
901 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p + 2);
903 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p + 2);
905 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p + 2);
907 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p + 2), 2);
909 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
910 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
914 /* Add the protocol name */
915 iwe.cmd = SIOCGIWNAME;
916 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
918 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
920 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
921 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
923 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
925 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
927 if (pnetwork->network.Configuration.DSConfig > 14) {
928 if (vht_cap == _TRUE)
929 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
930 else if (ht_cap == _TRUE)
931 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
933 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
936 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
938 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
942 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
945 if (pnetwork->network.Reserved[0] == 2) /* Probe Request */
948 iwe.cmd = SIOCGIWMODE;
949 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
950 cap = le16_to_cpu(cap);
953 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
954 if (cap & WLAN_CAPABILITY_BSS)
955 iwe.u.mode = IW_MODE_MASTER;
957 iwe.u.mode = IW_MODE_ADHOC;
959 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
962 if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
963 pnetwork->network.Configuration.DSConfig = 1;
965 /* Add frequency/channel */
966 iwe.cmd = SIOCGIWFREQ;
967 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
969 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
970 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
972 /* Add encryption capability */
973 iwe.cmd = SIOCGIWENCODE;
974 if (cap & WLAN_CAPABILITY_PRIVACY)
975 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
977 iwe.u.data.flags = IW_ENCODE_DISABLED;
978 iwe.u.data.length = 0;
979 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
981 /*Add basic and extended rates */
984 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
985 while (pnetwork->network.SupportedRates[i] != 0) {
986 rate = pnetwork->network.SupportedRates[i] & 0x7F;
989 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
990 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
994 if (vht_cap == _TRUE)
995 max_rate = vht_data_rate;
996 else if (ht_cap == _TRUE) {
997 if (mcs_rate & 0x8000) /* MCS15 */
998 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
1000 else if (mcs_rate & 0x0080) /* MCS7 */
1001 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
1002 else { /* default MCS7 */
1003 /* RTW_INFO("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); */
1004 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
1007 max_rate = max_rate * 2; /* Mbps/2; */
1010 iwe.cmd = SIOCGIWRATE;
1011 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1012 iwe.u.bitrate.value = max_rate * 500000;
1013 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
1015 /* parsing WPA/WPA2 IE */
1016 if (pnetwork->network.Reserved[0] != 2) { /* Probe Request */
1017 u8 buf[MAX_WPA_IE_LEN * 2];
1018 u8 wpa_ie[255], rsn_ie[255];
1019 u16 wpa_len = 0, rsn_len = 0;
1022 out_len = rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
1023 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid=%s\n", pnetwork->network.Ssid.Ssid));
1024 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n", wpa_len, rsn_len));
1028 _rtw_memset(buf, 0, MAX_WPA_IE_LEN * 2);
1029 p += sprintf(p, "wpa_ie=");
1030 for (i = 0; i < wpa_len; i++)
1031 p += sprintf(p, "%02x", wpa_ie[i]);
1033 if (wpa_len > 100) {
1034 printk("-----------------Len %d----------------\n", wpa_len);
1035 for (i = 0; i < wpa_len; i++)
1036 printk("%02x ", wpa_ie[i]);
1038 printk("-----------------Len %d----------------\n", wpa_len);
1041 _rtw_memset(&iwe, 0, sizeof(iwe));
1042 iwe.cmd = IWEVCUSTOM;
1043 iwe.u.data.length = strlen(buf);
1044 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
1046 _rtw_memset(&iwe, 0, sizeof(iwe));
1047 iwe.cmd = IWEVGENIE;
1048 iwe.u.data.length = wpa_len;
1049 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
1053 _rtw_memset(buf, 0, MAX_WPA_IE_LEN * 2);
1054 p += sprintf(p, "rsn_ie=");
1055 for (i = 0; i < rsn_len; i++)
1056 p += sprintf(p, "%02x", rsn_ie[i]);
1057 _rtw_memset(&iwe, 0, sizeof(iwe));
1058 iwe.cmd = IWEVCUSTOM;
1059 iwe.u.data.length = strlen(buf);
1060 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
1062 _rtw_memset(&iwe, 0, sizeof(iwe));
1063 iwe.cmd = IWEVGENIE;
1064 iwe.u.data.length = rsn_len;
1065 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
1069 { /* parsing WPS IE */
1070 uint cnt = 0, total_ielen;
1071 u8 *wpsie_ptr = NULL;
1074 u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
1075 total_ielen = pnetwork->network.IELength - ie_offset;
1077 if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */
1078 ie_ptr = pnetwork->network.IEs;
1079 total_ielen = pnetwork->network.IELength;
1080 } else { /* Beacon or Probe Respones */
1081 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
1082 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
1085 while (cnt < total_ielen) {
1086 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
1087 wpsie_ptr = &ie_ptr[cnt];
1088 iwe.cmd = IWEVGENIE;
1089 iwe.u.data.length = (u16)wps_ielen;
1090 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
1092 cnt += ie_ptr[cnt + 1] + 2; /* goto next */
1096 #ifdef CONFIG_WAPI_SUPPORT
1097 if (pnetwork->network.Reserved[0] != 2) { /* Probe Request */
1098 sint out_len_wapi = 0;
1099 /* here use static for stack size */
1100 static u8 buf_wapi[MAX_WAPI_IE_LEN * 2];
1101 static u8 wapi_ie[MAX_WAPI_IE_LEN];
1105 _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN);
1106 _rtw_memset(wapi_ie, 0, MAX_WAPI_IE_LEN);
1108 out_len_wapi = rtw_get_wapi_ie(pnetwork->network.IEs , pnetwork->network.IELength, wapi_ie, &wapi_len);
1109 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: ssid=%s\n", pnetwork->network.Ssid.Ssid));
1110 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan: wapi_len=%d\n", wapi_len));
1112 RTW_INFO("rtw_wx_get_scan: %s ", pnetwork->network.Ssid.Ssid);
1113 RTW_INFO("rtw_wx_get_scan: ssid = %d ", wapi_len);
1118 _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN * 2);
1119 p += sprintf(p, "wapi_ie=");
1120 for (i = 0; i < wapi_len; i++)
1121 p += sprintf(p, "%02x", wapi_ie[i]);
1123 _rtw_memset(&iwe, 0, sizeof(iwe));
1124 iwe.cmd = IWEVCUSTOM;
1125 iwe.u.data.length = strlen(buf_wapi);
1126 start = iwe_stream_add_point(info, start, stop, &iwe, buf_wapi);
1128 _rtw_memset(&iwe, 0, sizeof(iwe));
1129 iwe.cmd = IWEVGENIE;
1130 iwe.u.data.length = wapi_len;
1131 start = iwe_stream_add_point(info, start, stop, &iwe, wapi_ie);
1137 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1140 /* Add quality statistics */
1142 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
1143 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
1144 | IW_QUAL_NOISE_UPDATED
1146 | IW_QUAL_NOISE_INVALID
1148 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1153 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1154 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
1155 ss = padapter->recvpriv.signal_strength;
1156 sq = padapter->recvpriv.signal_qual;
1158 ss = pnetwork->network.PhyInfo.SignalStrength;
1159 sq = pnetwork->network.PhyInfo.SignalQuality;
1163 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1164 iwe.u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
1166 #ifdef CONFIG_SIGNAL_SCALE_MAPPING
1167 iwe.u.qual.level = (u8)ss; /* % */
1170 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
1172 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
1174 iwe.u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
1179 iwe.u.qual.qual = (u8)sq; /* signal quality */
1181 #ifdef CONFIG_PLATFORM_ROCKCHIPS
1182 iwe.u.qual.noise = -100; /* noise level suggest by zhf@rockchips */
1184 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
1187 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
1188 iwe.u.qual.noise = tmp_noise ;
1191 iwe.u.qual.noise = 0; /* noise level */
1193 #endif /* CONFIG_PLATFORM_ROCKCHIPS */
1195 /* 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); */
1197 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
1201 u8 buf[MAX_WPA_IE_LEN];
1205 pos = pnetwork->network.Reserved;
1206 _rtw_memset(buf, 0, MAX_WPA_IE_LEN);
1207 p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
1208 _rtw_memset(&iwe, 0, sizeof(iwe));
1209 iwe.cmd = IWEVCUSTOM;
1210 iwe.u.data.length = strlen(buf);
1211 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
1218 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
1220 _adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
1223 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
1224 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
1225 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1226 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
1227 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1228 } else if (value & AUTH_ALG_SHARED_KEY) {
1229 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);
1230 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1232 #ifdef CONFIG_PLATFORM_MT53XX
1233 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
1234 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1236 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
1237 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1239 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
1240 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
1241 /* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
1242 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
1243 #ifdef CONFIG_PLATFORM_MT53XX
1244 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
1245 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1247 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1248 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1252 } else if (value & AUTH_ALG_LEAP)
1253 RTW_INFO("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
1255 RTW_INFO("wpa_set_auth_algs, error!\n");
1263 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1266 u32 wep_key_idx, wep_key_len, wep_total_len;
1267 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1268 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1269 struct security_priv *psecuritypriv = &padapter->securitypriv;
1271 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1272 #endif /* CONFIG_P2P */
1276 param->u.crypt.err = 0;
1277 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1279 if (param_len < (u32)((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
1284 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1285 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1286 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
1288 if (param->u.crypt.idx >= WEP_KEYS
1289 #ifdef CONFIG_IEEE80211W
1290 && param->u.crypt.idx > BIP_MAX_KEYID
1291 #endif /* CONFIG_IEEE80211W */
1297 #ifdef CONFIG_WAPI_SUPPORT
1298 if (strcmp(param->u.crypt.alg, "SMS4"))
1306 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1307 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
1308 RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
1310 wep_key_idx = param->u.crypt.idx;
1311 wep_key_len = param->u.crypt.key_len;
1313 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) {
1318 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1319 /* wep default key has not been set, so use this key index as default key.*/
1321 wep_key_len = wep_key_len <= 5 ? 5 : 13;
1323 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1324 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1325 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1327 if (wep_key_len == 13) {
1328 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1329 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1332 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1335 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1337 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1339 psecuritypriv->key_mask |= BIT(wep_key_idx);
1344 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
1345 struct sta_info *psta, *pbcmc_sta;
1346 struct sta_priv *pstapriv = &padapter->stapriv;
1348 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
1349 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1351 /* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
1353 /* Jeff: don't disable ieee8021x_blocked while clearing key */
1354 if (strcmp(param->u.crypt.alg, "none") != 0)
1355 psta->ieee8021x_blocked = _FALSE;
1357 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1358 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1359 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1361 if (param->u.crypt.set_tx == 1) { /* pairwise key */
1362 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1364 if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
1365 /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); */
1366 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1367 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1369 padapter->securitypriv.busetkipkey = _FALSE;
1370 /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
1373 /* DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); */
1374 RTW_INFO(" ~~~~set sta key:unicastkey\n");
1376 rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
1378 psta->bpairwise_key_installed = _TRUE;
1380 } else { /* group key */
1381 if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
1382 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,
1383 (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1384 /* only TKIP group key need to install this */
1385 if (param->u.crypt.key_len > 16) {
1386 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1387 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1389 padapter->securitypriv.binstallGrpkey = _TRUE;
1390 /* DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); */
1391 RTW_INFO(" ~~~~set sta key:groupkey\n");
1393 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1395 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
1397 #ifdef CONFIG_IEEE80211W
1398 else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1400 /* printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
1401 /* save the IGTK key, length 16 bytes */
1402 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,
1403 (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1404 /*printk("IGTK key below:\n");
1405 for(no=0;no<16;no++)
1406 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1408 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1409 padapter->securitypriv.binstallBIPkey = _TRUE;
1410 RTW_INFO(" ~~~~set sta key:IGKT\n");
1412 #endif /* CONFIG_IEEE80211W */
1415 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1416 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1417 #endif /* CONFIG_P2P */
1422 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1423 if (pbcmc_sta == NULL) {
1424 /* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
1426 /* Jeff: don't disable ieee8021x_blocked while clearing key */
1427 if (strcmp(param->u.crypt.alg, "none") != 0)
1428 pbcmc_sta->ieee8021x_blocked = _FALSE;
1430 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1431 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1432 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1434 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1438 #ifdef CONFIG_WAPI_SUPPORT
1439 if (strcmp(param->u.crypt.alg, "SMS4") == 0) {
1440 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
1441 PRT_WAPI_STA_INFO pWapiSta;
1442 u8 WapiASUEPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1443 u8 WapiAEPNInitialValueSrc[16] = {0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1444 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1446 if (param->u.crypt.set_tx == 1) {
1447 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1448 if (_rtw_memcmp(pWapiSta->PeerMacAddr, param->sta_addr, 6)) {
1449 _rtw_memcpy(pWapiSta->lastTxUnicastPN, WapiASUEPNInitialValueSrc, 16);
1451 pWapiSta->wapiUsk.bSet = true;
1452 _rtw_memcpy(pWapiSta->wapiUsk.dataKey, param->u.crypt.key, 16);
1453 _rtw_memcpy(pWapiSta->wapiUsk.micKey, param->u.crypt.key + 16, 16);
1454 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1455 pWapiSta->wapiUsk.bTxEnable = true;
1457 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue, WapiAEPNInitialValueSrc, 16);
1458 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue, WapiAEPNInitialValueSrc, 16);
1459 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue, WapiAEPNInitialValueSrc, 16);
1460 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue, WapiAEPNInitialValueSrc, 16);
1461 _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16);
1462 pWapiSta->wapiUskUpdate.bTxEnable = false;
1463 pWapiSta->wapiUskUpdate.bSet = false;
1465 if (psecuritypriv->sw_encrypt == false || psecuritypriv->sw_decrypt == false) {
1466 /* set unicast key for ASUE */
1467 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1472 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1473 if (_rtw_memcmp(pWapiSta->PeerMacAddr, get_bssid(pmlmepriv), 6)) {
1474 pWapiSta->wapiMsk.bSet = true;
1475 _rtw_memcpy(pWapiSta->wapiMsk.dataKey, param->u.crypt.key, 16);
1476 _rtw_memcpy(pWapiSta->wapiMsk.micKey, param->u.crypt.key + 16, 16);
1477 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1478 pWapiSta->wapiMsk.bTxEnable = false;
1479 if (!pWapiSta->bSetkeyOk)
1480 pWapiSta->bSetkeyOk = true;
1481 pWapiSta->bAuthenticateInProgress = false;
1483 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1485 if (psecuritypriv->sw_decrypt == false) {
1486 /* set rx broadcast key for ASUE */
1487 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1503 static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1505 u8 *buf = NULL, *pos = NULL;
1507 int group_cipher = 0, pairwise_cipher = 0;
1509 u8 null_addr[] = {0, 0, 0, 0, 0, 0};
1511 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1512 #endif /* CONFIG_P2P */
1514 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
1515 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1523 buf = rtw_zmalloc(ielen);
1529 _rtw_memcpy(buf, pie , ielen);
1534 RTW_INFO("\n wpa_ie(length:%d):\n", ielen);
1535 for (i = 0; i < ielen; i = i + 8)
1536 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]);
1540 if (ielen < RSN_HEADER_LEN) {
1541 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
1547 pos += RSN_HEADER_LEN;
1548 left = ielen - RSN_HEADER_LEN;
1550 if (left >= RSN_SELECTOR_LEN) {
1551 pos += RSN_SELECTOR_LEN;
1552 left -= RSN_SELECTOR_LEN;
1553 } else if (left > 0) {
1554 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie length mismatch, %u too much\n", left));
1560 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1561 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1562 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
1563 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1566 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1567 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1568 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1569 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1572 if (group_cipher == 0)
1573 group_cipher = WPA_CIPHER_NONE;
1574 if (pairwise_cipher == 0)
1575 pairwise_cipher = WPA_CIPHER_NONE;
1577 switch (group_cipher) {
1578 case WPA_CIPHER_NONE:
1579 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1580 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1582 case WPA_CIPHER_WEP40:
1583 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1584 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1586 case WPA_CIPHER_TKIP:
1587 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1588 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1590 case WPA_CIPHER_CCMP:
1591 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1592 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1594 case WPA_CIPHER_WEP104:
1595 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1596 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1600 switch (pairwise_cipher) {
1601 case WPA_CIPHER_NONE:
1602 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1603 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1605 case WPA_CIPHER_WEP40:
1606 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1607 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1609 case WPA_CIPHER_TKIP:
1610 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1611 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1613 case WPA_CIPHER_CCMP:
1614 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
1615 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1617 case WPA_CIPHER_WEP104:
1618 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1619 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1623 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1626 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
1628 while (cnt < ielen) {
1631 if ((eid == _VENDOR_SPECIFIC_IE_) && (_rtw_memcmp(&buf[cnt + 2], wps_oui, 4) == _TRUE)) {
1632 RTW_INFO("SET WPS_IE\n");
1634 padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < MAX_WPS_IE_LEN) ? (buf[cnt + 1] + 2) : MAX_WPS_IE_LEN;
1636 _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1638 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1641 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1642 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1643 #endif /* CONFIG_P2P */
1644 cnt += buf[cnt + 1] + 2;
1648 cnt += buf[cnt + 1] + 2; /* goto next */
1654 /* TKIP and AES disallow multicast packets until installing group key */
1655 if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1656 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1657 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1658 /* WPS open need to enable multicast
1659 * || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
1660 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1662 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1663 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
1664 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
1669 rtw_mfree(buf, ielen);
1674 static int rtw_wx_get_name(struct net_device *dev,
1675 struct iw_request_info *info,
1676 union iwreq_data *wrqu, char *extra)
1678 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1682 u8 ht_cap = _FALSE, vht_cap = _FALSE;
1683 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1684 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1685 NDIS_802_11_RATES_EX *prates = NULL;
1687 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("cmd_code=%x\n", info->cmd));
1691 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
1692 /* parsing HT_CAP_IE */
1693 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
1694 if (p && ht_ielen > 0)
1697 #ifdef CONFIG_80211AC_VHT
1698 if (pmlmepriv->vhtpriv.vht_option == _TRUE)
1702 prates = &pcur_bss->SupportedRates;
1704 if (rtw_is_cckratesonly_included((u8 *)prates) == _TRUE) {
1705 if (ht_cap == _TRUE)
1706 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1708 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1709 } else if ((rtw_is_cckrates_included((u8 *)prates)) == _TRUE) {
1710 if (ht_cap == _TRUE)
1711 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1713 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1715 if (pcur_bss->Configuration.DSConfig > 14) {
1716 #ifdef CONFIG_80211AC_VHT
1717 if (vht_cap == _TRUE)
1718 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1722 if (ht_cap == _TRUE)
1723 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1725 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1728 if (ht_cap == _TRUE)
1729 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1731 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1735 /* prates = &padapter->registrypriv.dev_network.SupportedRates; */
1736 /* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */
1737 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1745 static int rtw_wx_set_freq(struct net_device *dev,
1746 struct iw_request_info *info,
1747 union iwreq_data *wrqu, char *extra)
1750 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1751 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
1752 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1753 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
1754 int exp = 1, freq = 0, div = 0;
1758 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
1760 if (wrqu->freq.m <= 1000) {
1761 if (wrqu->freq.flags == IW_FREQ_AUTO) {
1762 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, wrqu->freq.m) > 0) {
1763 padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1764 RTW_INFO("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m);
1766 padapter->mlmeextpriv.cur_channel = 1;
1767 RTW_INFO("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__);
1770 padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1771 RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1774 while (wrqu->freq.e) {
1779 freq = wrqu->freq.m;
1781 while (!(freq % 10)) {
1786 /* freq unit is MHz here */
1787 div = 1000000 / exp;
1792 div = exp / 1000000;
1796 /* If freq is invalid, rtw_freq2ch() will return channel 1 */
1797 padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);
1798 RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1801 set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
1808 static int rtw_wx_get_freq(struct net_device *dev,
1809 struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1812 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1813 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1814 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1816 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1818 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1820 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1823 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1825 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1831 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1832 union iwreq_data *wrqu, char *b)
1834 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1835 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1836 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1841 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1846 if (!rtw_is_hw_init_completed(padapter)) {
1851 /* initial default type */
1852 dev->type = ARPHRD_ETHER;
1854 switch (wrqu->mode) {
1855 case IW_MODE_MONITOR:
1856 networkType = Ndis802_11Monitor;
1858 dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
1860 dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
1861 RTW_INFO("set_mode = IW_MODE_MONITOR\n");
1865 networkType = Ndis802_11AutoUnknown;
1866 RTW_INFO("set_mode = IW_MODE_AUTO\n");
1869 networkType = Ndis802_11IBSS;
1870 RTW_INFO("set_mode = IW_MODE_ADHOC\n");
1872 case IW_MODE_MASTER:
1873 networkType = Ndis802_11APMode;
1874 RTW_INFO("set_mode = IW_MODE_MASTER\n");
1875 /* rtw_setopmode_cmd(padapter, networkType,_TRUE); */
1878 networkType = Ndis802_11Infrastructure;
1879 RTW_INFO("set_mode = IW_MODE_INFRA\n");
1884 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported\n", iw_operation_mode[wrqu->mode]));
1889 if(Ndis802_11APMode == networkType)
1891 rtw_setopmode_cmd(padapter, networkType,_TRUE);
1895 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE);
1899 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == _FALSE) {
1906 rtw_setopmode_cmd(padapter, networkType, _TRUE);
1908 if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1909 rtw_indicate_connect(padapter);
1919 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1920 union iwreq_data *wrqu, char *b)
1922 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1923 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1925 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_get_mode\n"));
1929 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1930 wrqu->mode = IW_MODE_INFRA;
1931 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1932 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1934 wrqu->mode = IW_MODE_ADHOC;
1935 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1936 wrqu->mode = IW_MODE_MASTER;
1937 else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1938 wrqu->mode = IW_MODE_MONITOR;
1940 wrqu->mode = IW_MODE_AUTO;
1949 static int rtw_wx_set_pmkid(struct net_device *dev,
1950 struct iw_request_info *a,
1951 union iwreq_data *wrqu, char *extra)
1953 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1954 u8 j, blInserted = _FALSE;
1955 int intReturn = _FALSE;
1956 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1957 struct security_priv *psecuritypriv = &padapter->securitypriv;
1958 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
1959 u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
1960 u8 strIssueBssid[ETH_ALEN] = { 0x00 };
1965 struct sockaddr bssid;
1966 __u8 pmkid[IW_PMKID_LEN]; /* IW_PMKID_LEN=16 */
1968 There are the BSSID information in the bssid.sa_data array.
1969 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1970 If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID / BSSID to driver.
1971 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID / BSSID from driver.
1974 _rtw_memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1975 if (pPMK->cmd == IW_PMKSA_ADD) {
1976 RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
1977 if (_rtw_memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
1981 blInserted = _FALSE;
1983 /* overwrite PMKID */
1984 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1985 if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1986 /* BSSID is matched, the same AP => rewrite with new PMKID. */
1988 RTW_INFO("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
1990 _rtw_memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1991 psecuritypriv->PMKIDList[j].bUsed = _TRUE;
1992 psecuritypriv->PMKIDIndex = j + 1;
1999 /* Find a new entry */
2000 RTW_INFO("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
2001 psecuritypriv->PMKIDIndex);
2003 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
2004 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
2006 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
2007 psecuritypriv->PMKIDIndex++ ;
2008 if (psecuritypriv->PMKIDIndex == 16)
2009 psecuritypriv->PMKIDIndex = 0;
2011 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
2012 RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
2014 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
2015 if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
2016 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
2017 _rtw_memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
2018 psecuritypriv->PMKIDList[j].bUsed = _FALSE;
2022 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
2023 RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
2024 _rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
2025 psecuritypriv->PMKIDIndex = 0;
2031 static int rtw_wx_get_sens(struct net_device *dev,
2032 struct iw_request_info *info,
2033 union iwreq_data *wrqu, char *extra)
2035 #ifdef CONFIG_PLATFORM_ROCKCHIPS
2036 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2037 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2040 * 20110311 Commented by Jeff
2041 * For rockchip platform's wpa_driver_wext_get_rssi
2043 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
2044 /* wrqu->sens.value=-padapter->recvpriv.signal_strength; */
2045 wrqu->sens.value = -padapter->recvpriv.rssi;
2046 /* RTW_INFO("%s: %d\n", __FUNCTION__, wrqu->sens.value); */
2047 wrqu->sens.fixed = 0; /* no auto select */
2051 wrqu->sens.value = 0;
2052 wrqu->sens.fixed = 0; /* no auto select */
2053 wrqu->sens.disabled = 1;
2058 static int rtw_wx_get_range(struct net_device *dev,
2059 struct iw_request_info *info,
2060 union iwreq_data *wrqu, char *extra)
2062 struct iw_range *range = (struct iw_range *)extra;
2063 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2064 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2071 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_range. cmd_code=%x\n", info->cmd));
2073 wrqu->data.length = sizeof(*range);
2074 _rtw_memset(range, 0, sizeof(*range));
2076 /* Let's try to keep this struct in the same order as in
2077 * linux/include/wireless.h
2080 /* TODO: See what values we can set, and remove the ones we can't
2081 * set, or fill them with some default data.
2084 /* ~5 Mb/s real (802.11b) */
2085 range->throughput = 5 * 1000 * 1000;
2087 /* TODO: Not used in 802.11b?
2088 * range->min_nwid; Minimal NWID we are able to set */
2089 /* TODO: Not used in 802.11b?
2090 * range->max_nwid; Maximal NWID we are able to set */
2092 /* Old Frequency (backward compat - moved lower ) */
2093 /* range->old_num_channels;
2094 * range->old_num_frequency;
2095 * range->old_freq[6]; Filler to keep "version" at the same offset */
2097 /* signal level threshold range */
2099 /* Quality of link & SNR stuff */
2100 /* Quality range (link, level, noise)
2101 * If the quality is absolute, it will be in the range [0 ; max_qual],
2102 * if the quality is dBm, it will be in the range [max_qual ; 0].
2103 * Don't forget that we use 8 bit arithmetics...
2105 * If percentage range is 0~100
2106 * Signal strength dbm range logical is -100 ~ 0
2107 * but usually value is -90 ~ -20
2108 * When CONFIG_SIGNAL_SCALE_MAPPING is defined, dbm range is -95 ~ -45
2110 range->max_qual.qual = 100;
2111 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
2112 range->max_qual.level = (u8)-100;
2113 range->max_qual.noise = (u8)-100;
2114 range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2115 range->max_qual.updated |= IW_QUAL_DBM;
2116 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
2117 /* percent values between 0 and 100. */
2118 range->max_qual.level = 100;
2119 range->max_qual.noise = 100;
2120 range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2121 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
2123 /* This should contain the average/typical values of the quality
2124 * indicator. This should be the threshold between a "good" and
2125 * a "bad" link (example : monitor going from green to orange).
2126 * Currently, user space apps like quality monitors don't have any
2127 * way to calibrate the measurement. With this, they can split
2128 * the range between 0 and max_qual in different quality level
2129 * (using a geometric subdivision centered on the average).
2130 * I expect that people doing the user space apps will feedback
2131 * us on which value we need to put in each driver... */
2132 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
2133 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
2134 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
2135 range->avg_qual.level = (u8)-70;
2136 range->avg_qual.noise = 0;
2137 range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2138 range->avg_qual.updated |= IW_QUAL_DBM;
2139 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
2140 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
2141 range->avg_qual.level = 30;
2142 range->avg_qual.noise = 100;
2143 range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2144 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
2146 range->num_bitrates = RATE_COUNT;
2148 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
2149 range->bitrate[i] = rtw_rates[i];
2151 range->min_frag = MIN_FRAG_THRESHOLD;
2152 range->max_frag = MAX_FRAG_THRESHOLD;
2156 range->we_version_compiled = WIRELESS_EXT;
2157 range->we_version_source = 16;
2159 /* range->retry_capa; What retry options are supported
2160 * range->retry_flags; How to decode max/min retry limit
2161 * range->r_time_flags; How to decode max/min retry life
2162 * range->min_retry; Minimal number of retries
2163 * range->max_retry; Maximal number of retries
2164 * range->min_r_time; Minimal retry lifetime
2165 * range->max_r_time; Maximal retry lifetime */
2167 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
2169 /* Include only legal frequencies for some countries */
2170 if (pmlmeext->channel_set[i].ChannelNum != 0) {
2171 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
2172 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
2173 range->freq[val].e = 1;
2177 if (val == IW_MAX_FREQUENCIES)
2181 range->num_channels = val;
2182 range->num_frequency = val;
2184 /* Commented by Albert 2009/10/13
2185 * The following code will proivde the security capability to network manager.
2186 * If the driver doesn't provide this capability to network manager,
2187 * the WPA/WPA2 routers can't be choosen in the network manager. */
2190 #define IW_SCAN_CAPA_NONE 0x00
2191 #define IW_SCAN_CAPA_ESSID 0x01
2192 #define IW_SCAN_CAPA_BSSID 0x02
2193 #define IW_SCAN_CAPA_CHANNEL 0x04
2194 #define IW_SCAN_CAPA_MODE 0x08
2195 #define IW_SCAN_CAPA_RATE 0x10
2196 #define IW_SCAN_CAPA_TYPE 0x20
2197 #define IW_SCAN_CAPA_TIME 0x40
2200 #if WIRELESS_EXT > 17
2201 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
2202 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
2205 #ifdef IW_SCAN_CAPA_ESSID /* WIRELESS_EXT > 21 */
2206 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID |
2207 IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
2218 * s1. rtw_set_802_11_infrastructure_mode()
2219 * s2. rtw_set_802_11_authentication_mode()
2220 * s3. set_802_11_encryption_mode()
2221 * s4. rtw_set_802_11_bssid() */
2222 static int rtw_wx_set_wap(struct net_device *dev,
2223 struct iw_request_info *info,
2224 union iwreq_data *awrq,
2229 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2230 struct sockaddr *temp = (struct sockaddr *)awrq;
2231 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2233 u8 *dst_bssid, *src_bssid;
2234 _queue *queue = &(pmlmepriv->scanned_queue);
2235 struct wlan_network *pnetwork = NULL;
2236 NDIS_802_11_AUTHENTICATION_MODE authmode;
2240 #ifdef CONFIG_CONCURRENT_MODE
2241 if(padapter->adapter_type > PRIMARY_IFACE)
2249 #ifdef CONFIG_CONCURRENT_MODE
2250 if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {
2251 RTW_INFO("set bssid, but buddy_intf is under scanning or linking\n");
2259 rtw_ps_deny(padapter, PS_DENY_JOIN);
2260 if (_FAIL == rtw_pwr_wakeup(padapter)) {
2265 if (!padapter->bup) {
2271 if (temp->sa_family != ARPHRD_ETHER) {
2276 authmode = padapter->securitypriv.ndisauthtype;
2277 _enter_critical_bh(&queue->lock, &irqL);
2278 phead = get_list_head(queue);
2279 pmlmepriv->pscanned = get_next(phead);
2283 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) {
2288 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2289 rtw_set_802_11_bssid(padapter, temp->sa_data);
2300 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2302 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2304 dst_bssid = pnetwork->network.MacAddress;
2306 src_bssid = temp->sa_data;
2308 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) {
2309 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
2311 _exit_critical_bh(&queue->lock, &irqL);
2319 _exit_critical_bh(&queue->lock, &irqL);
2321 rtw_set_802_11_authentication_mode(padapter, authmode);
2322 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
2323 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
2330 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2337 static int rtw_wx_get_wap(struct net_device *dev,
2338 struct iw_request_info *info,
2339 union iwreq_data *wrqu, char *extra)
2342 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2343 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2344 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2346 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
2348 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2350 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_wap\n"));
2354 if (((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) ||
2355 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
2356 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE))
2358 _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
2360 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2368 static int rtw_wx_set_mlme(struct net_device *dev,
2369 struct iw_request_info *info,
2370 union iwreq_data *wrqu, char *extra)
2373 /* SIOCSIWMLME data */
2375 __u16 cmd; /* IW_MLME_* */
2377 struct sockaddr addr;
2383 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2384 struct iw_mlme *mlme = (struct iw_mlme *) extra;
2390 RTW_INFO("%s\n", __FUNCTION__);
2392 reason = cpu_to_le16(mlme->reason_code);
2395 RTW_INFO("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
2398 switch (mlme->cmd) {
2399 case IW_MLME_DEAUTH:
2400 if (!rtw_set_802_11_disassociate(padapter))
2404 case IW_MLME_DISASSOC:
2405 if (!rtw_set_802_11_disassociate(padapter))
2417 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
2418 union iwreq_data *wrqu, char *extra)
2420 u8 _status = _FALSE;
2422 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2423 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2424 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
2427 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2428 #endif /* CONFIG_P2P */
2429 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
2434 RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2437 #ifdef CONFIG_MP_INCLUDED
2438 if (rtw_mi_mp_mode_check(padapter)) {
2439 RTW_INFO("MP mode block Scan request\n");
2444 if (rtw_is_scan_deny(padapter)) {
2445 indicate_wx_scan_complete_event(padapter);
2449 rtw_ps_deny(padapter, PS_DENY_SCAN);
2450 if (_FAIL == rtw_pwr_wakeup(padapter)) {
2455 if (!rtw_is_adapter_up(padapter)) {
2460 #ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC
2461 /* When Busy Traffic, driver do not site survey. So driver return success. */
2462 /* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
2463 /* modify by thomas 2011-02-22. */
2464 if (rtw_mi_busy_traffic_check(padapter, _FALSE)) {
2465 indicate_wx_scan_complete_event(padapter);
2470 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2471 RTW_INFO("AP mode process WPS\n");
2472 indicate_wx_scan_complete_event(padapter);
2476 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {
2477 indicate_wx_scan_complete_event(padapter);
2481 #ifdef CONFIG_CONCURRENT_MODE
2482 if (rtw_mi_buddy_check_fwstate(padapter,
2483 _FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS)) {
2485 indicate_wx_scan_complete_event(padapter);
2491 if (pwdinfo->p2p_state != P2P_STATE_NONE) {
2492 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2493 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2494 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2495 rtw_free_network_queue(padapter, _TRUE);
2497 #endif /* CONFIG_P2P */
2499 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID) * RTW_SSID_SCAN_AMOUNT);
2501 #if WIRELESS_EXT >= 17
2502 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
2503 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2505 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2506 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2508 _rtw_memcpy(ssid[0].Ssid, req->essid, len);
2509 ssid[0].SsidLength = len;
2511 RTW_INFO("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2513 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, 1, NULL, 0);
2515 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2516 RTW_INFO("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2521 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2522 && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2524 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
2525 char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
2530 /* RTW_INFO("%s COMBO_SCAN header is recognized\n", __FUNCTION__); */
2537 case WEXT_CSCAN_SSID_SECTION:
2538 /* RTW_INFO("WEXT_CSCAN_SSID_SECTION\n"); */
2547 if (sec_len > 0 && sec_len <= len) {
2548 ssid[ssid_index].SsidLength = sec_len;
2549 _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
2550 /* RTW_INFO("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__ */
2551 /* , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength); */
2560 case WEXT_CSCAN_CHANNEL_SECTION:
2561 /* RTW_INFO("WEXT_CSCAN_CHANNEL_SECTION\n"); */
2565 case WEXT_CSCAN_ACTV_DWELL_SECTION:
2566 /* RTW_INFO("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); */
2570 case WEXT_CSCAN_PASV_DWELL_SECTION:
2571 /* RTW_INFO("WEXT_CSCAN_PASV_DWELL_SECTION\n"); */
2575 case WEXT_CSCAN_HOME_DWELL_SECTION:
2576 /* RTW_INFO("WEXT_CSCAN_HOME_DWELL_SECTION\n"); */
2580 case WEXT_CSCAN_TYPE_SECTION:
2581 /* RTW_INFO("WEXT_CSCAN_TYPE_SECTION\n"); */
2586 case WEXT_CSCAN_NPROBE_SECTION:
2587 RTW_INFO("WEXT_CSCAN_NPROBE_SECTION\n");
2592 /* RTW_INFO("Unknown CSCAN section %c\n", section); */
2593 len = 0; /* stop parsing */
2595 /* RTW_INFO("len:%d\n", len); */
2599 /* jeff: it has still some scan paramater to parse, we only do this now... */
2600 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
2604 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0, NULL, 0);
2606 if (_status == _FALSE)
2611 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2614 RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2622 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2623 union iwreq_data *wrqu, char *extra)
2626 _list *plist, *phead;
2627 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2628 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2629 _queue *queue = &(pmlmepriv->scanned_queue);
2630 struct wlan_network *pnetwork = NULL;
2632 char *stop = ev + wrqu->data.length;
2635 u32 wait_for_surveydone;
2639 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2640 #endif /* CONFIG_P2P */
2641 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
2642 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
2647 RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2650 if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) {
2656 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2657 wait_for_surveydone = 200;
2659 /* P2P is disabled */
2660 wait_for_surveydone = 100;
2664 wait_for_surveydone = 100;
2666 #endif /* CONFIG_P2P */
2668 #if 1 /* Wireless Extension use EAGAIN to try */
2669 wait_status = _FW_UNDER_SURVEY
2670 #ifndef CONFIG_ANDROID
2675 while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2678 wait_status = _FW_UNDER_SURVEY
2679 #ifndef CONFIG_ANDROID
2684 while (check_fwstate(pmlmepriv, wait_status) == _TRUE) {
2687 if (cnt > wait_for_surveydone)
2691 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2693 phead = get_list_head(queue);
2694 plist = get_next(phead);
2697 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
2700 if ((stop - ev) < SCAN_ITEM_SIZE) {
2705 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2707 /* report network only if the current channel set contains the channel to which this network belongs */
2708 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2709 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
2710 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2712 ev = translate_scan(padapter, a, pnetwork, ev, stop);
2714 plist = get_next(plist);
2718 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2720 wrqu->data.length = ev - extra;
2721 wrqu->data.flags = 0;
2728 RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2736 * s1. rtw_set_802_11_infrastructure_mode()
2737 * s2. set_802_11_authenticaion_mode()
2738 * s3. set_802_11_encryption_mode()
2739 * s4. rtw_set_802_11_ssid() */
2740 static int rtw_wx_set_essid(struct net_device *dev,
2741 struct iw_request_info *a,
2742 union iwreq_data *wrqu, char *extra)
2745 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2746 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2747 _queue *queue = &pmlmepriv->scanned_queue;
2750 struct wlan_network *pnetwork = NULL;
2751 NDIS_802_11_AUTHENTICATION_MODE authmode;
2752 NDIS_802_11_SSID ndis_ssid;
2753 u8 *dst_ssid, *src_ssid;
2760 RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2762 #ifdef CONFIG_WEXT_DONT_JOIN_BYSSID
2763 RTW_INFO("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);
2767 #if WIRELESS_EXT <= 20
2768 if ((wrqu->essid.length - 1) > IW_ESSID_MAX_SIZE) {
2770 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
2777 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2778 ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
2780 rtw_ps_deny(padapter, PS_DENY_JOIN);
2781 if (_FAIL == rtw_pwr_wakeup(padapter)) {
2786 if (!padapter->bup) {
2791 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2796 #ifdef CONFIG_CONCURRENT_MODE
2797 if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
2798 RTW_INFO("set ssid, but buddy_intf is under scanning or linking\n");
2803 authmode = padapter->securitypriv.ndisauthtype;
2804 RTW_INFO("=>%s\n", __FUNCTION__);
2805 if (wrqu->essid.flags && wrqu->essid.length) {
2806 /* Commented by Albert 20100519 */
2807 /* We got the codes in "set_info" function of iwconfig source code. */
2808 /* ========================================= */
2809 /* wrq.u.essid.length = strlen(essid) + 1; */
2810 /* if(we_kernel_version > 20) */
2811 /* wrq.u.essid.length--; */
2812 /* ========================================= */
2813 /* That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. */
2814 #if WIRELESS_EXT <= 20
2815 len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE;
2817 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2820 if (wrqu->essid.length != 33)
2821 RTW_INFO("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2823 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2824 ndis_ssid.SsidLength = len;
2825 _rtw_memcpy(ndis_ssid.Ssid, extra, len);
2826 src_ssid = ndis_ssid.Ssid;
2828 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid));
2829 _enter_critical_bh(&queue->lock, &irqL);
2830 phead = get_list_head(queue);
2831 pmlmepriv->pscanned = get_next(phead);
2834 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) {
2836 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2837 rtw_set_802_11_ssid(padapter, &ndis_ssid);
2841 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_ssid(): scanned_queue is empty\n"));
2846 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
2847 ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
2852 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2854 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2856 dst_ssid = pnetwork->network.Ssid.Ssid;
2858 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2859 ("rtw_wx_set_essid: dst_ssid=%s\n",
2860 pnetwork->network.Ssid.Ssid));
2862 if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2863 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
2864 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2865 ("rtw_wx_set_essid: find match, set infra mode\n"));
2867 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2868 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2872 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE) {
2874 _exit_critical_bh(&queue->lock, &irqL);
2881 _exit_critical_bh(&queue->lock, &irqL);
2882 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2883 ("set ssid: set_802_11_auth. mode=%d\n", authmode));
2884 rtw_set_802_11_authentication_mode(padapter, authmode);
2885 /* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
2886 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2894 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2896 RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
2899 RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2907 static int rtw_wx_get_essid(struct net_device *dev,
2908 struct iw_request_info *a,
2909 union iwreq_data *wrqu, char *extra)
2912 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2913 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2914 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2916 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_essid\n"));
2920 if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
2921 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
2922 len = pcur_bss->Ssid.SsidLength;
2924 wrqu->essid.length = len;
2926 _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2928 wrqu->essid.flags = 1;
2942 static int rtw_wx_set_rate(struct net_device *dev,
2943 struct iw_request_info *a,
2944 union iwreq_data *wrqu, char *extra)
2947 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2948 u8 datarates[NumRates];
2949 u32 target_rate = wrqu->bitrate.value;
2950 u32 fixed = wrqu->bitrate.fixed;
2952 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2956 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, (" rtw_wx_set_rate\n"));
2957 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("target_rate = %d, fixed = %d\n", target_rate, fixed));
2959 if (target_rate == -1) {
2963 target_rate = target_rate / 100000;
2965 switch (target_rate) {
3009 for (i = 0; i < NumRates; i++) {
3010 if (ratevalue == mpdatarate[i]) {
3011 datarates[i] = mpdatarate[i];
3015 datarates[i] = 0xff;
3017 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("datarate_inx=%d\n", datarates[i]));
3020 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
3021 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("rtw_wx_set_rate Fail!!!\n"));
3030 static int rtw_wx_get_rate(struct net_device *dev,
3031 struct iw_request_info *info,
3032 union iwreq_data *wrqu, char *extra)
3036 max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
3041 wrqu->bitrate.fixed = 0; /* no auto select */
3042 wrqu->bitrate.value = max_rate * 100000;
3047 static int rtw_wx_set_rts(struct net_device *dev,
3048 struct iw_request_info *info,
3049 union iwreq_data *wrqu, char *extra)
3051 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3055 if (wrqu->rts.disabled)
3056 padapter->registrypriv.rts_thresh = 2347;
3058 if (wrqu->rts.value < 0 ||
3059 wrqu->rts.value > 2347)
3062 padapter->registrypriv.rts_thresh = wrqu->rts.value;
3065 RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
3073 static int rtw_wx_get_rts(struct net_device *dev,
3074 struct iw_request_info *info,
3075 union iwreq_data *wrqu, char *extra)
3077 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3081 RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
3083 wrqu->rts.value = padapter->registrypriv.rts_thresh;
3084 wrqu->rts.fixed = 0; /* no auto select */
3085 /* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
3092 static int rtw_wx_set_frag(struct net_device *dev,
3093 struct iw_request_info *info,
3094 union iwreq_data *wrqu, char *extra)
3096 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3100 if (wrqu->frag.disabled)
3101 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
3103 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
3104 wrqu->frag.value > MAX_FRAG_THRESHOLD)
3107 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
3110 RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
3118 static int rtw_wx_get_frag(struct net_device *dev,
3119 struct iw_request_info *info,
3120 union iwreq_data *wrqu, char *extra)
3122 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3126 RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
3128 wrqu->frag.value = padapter->xmitpriv.frag_len;
3129 wrqu->frag.fixed = 0; /* no auto select */
3130 /* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */
3137 static int rtw_wx_get_retry(struct net_device *dev,
3138 struct iw_request_info *info,
3139 union iwreq_data *wrqu, char *extra)
3141 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3144 wrqu->retry.value = 7;
3145 wrqu->retry.fixed = 0; /* no auto select */
3146 wrqu->retry.disabled = 1;
3153 #define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
3154 #define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
3155 #define IW_ENCODE_MODE 0xF000 /* Modes defined below */
3156 #define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
3157 #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
3158 #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
3159 #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
3160 #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
3161 #define IW_ENCODE_TEMP 0x0400 /* Temporary key */
3163 iwconfig wlan0 key on->flags = 0x6001->maybe it means auto
3164 iwconfig wlan0 key off->flags = 0x8800
3165 iwconfig wlan0 key open->flags = 0x2800
3166 iwconfig wlan0 key open 1234567890->flags = 0x2000
3167 iwconfig wlan0 key restricted->flags = 0x4800
3168 iwconfig wlan0 key open [3] 1234567890->flags = 0x2003
3169 iwconfig wlan0 key restricted [2] 1234567890->flags = 0x4002
3170 iwconfig wlan0 key open [3] -> flags = 0x2803
3171 iwconfig wlan0 key restricted [2] -> flags = 0x4802
3175 static int rtw_wx_set_enc(struct net_device *dev,
3176 struct iw_request_info *info,
3177 union iwreq_data *wrqu, char *keybuf)
3180 u32 keyindex_provided;
3181 NDIS_802_11_WEP wep;
3182 NDIS_802_11_AUTHENTICATION_MODE authmode;
3184 struct iw_point *erq = &(wrqu->encoding);
3185 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3186 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3187 RTW_INFO("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
3189 _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
3191 key = erq->flags & IW_ENCODE_INDEX;
3195 if (erq->flags & IW_ENCODE_DISABLED) {
3196 RTW_INFO("EncryptionDisabled\n");
3197 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3198 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3199 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3200 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3201 authmode = Ndis802_11AuthModeOpen;
3202 padapter->securitypriv.ndisauthtype = authmode;
3211 keyindex_provided = 1;
3213 keyindex_provided = 0;
3214 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3215 RTW_INFO("rtw_wx_set_enc, key=%d\n", key);
3218 /* set authentication mode */
3219 if (erq->flags & IW_ENCODE_OPEN) {
3220 RTW_INFO("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
3221 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
3223 #ifdef CONFIG_PLATFORM_MT53XX
3224 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3226 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3229 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3230 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3231 authmode = Ndis802_11AuthModeOpen;
3232 padapter->securitypriv.ndisauthtype = authmode;
3233 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
3234 RTW_INFO("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
3235 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3237 #ifdef CONFIG_PLATFORM_MT53XX
3238 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3240 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
3243 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
3244 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
3245 authmode = Ndis802_11AuthModeShared;
3246 padapter->securitypriv.ndisauthtype = authmode;
3248 RTW_INFO("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
3250 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
3251 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3252 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3253 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3254 authmode = Ndis802_11AuthModeOpen;
3255 padapter->securitypriv.ndisauthtype = authmode;
3259 if (erq->length > 0) {
3260 wep.KeyLength = erq->length <= 5 ? 5 : 13;
3262 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
3266 if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length==0). */
3267 padapter->securitypriv.dot11PrivacyKeyIndex = key;
3269 RTW_INFO("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
3271 switch (padapter->securitypriv.dot11DefKeylen[key]) {
3273 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
3276 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
3279 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3289 wep.KeyIndex |= 0x80000000;
3291 _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
3293 if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
3294 if (rf_on == pwrpriv->rf_pwrstate)
3307 static int rtw_wx_get_enc(struct net_device *dev,
3308 struct iw_request_info *info,
3309 union iwreq_data *wrqu, char *keybuf)
3312 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3313 struct iw_point *erq = &(wrqu->encoding);
3314 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3318 if (check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) {
3319 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) {
3321 erq->flags |= IW_ENCODE_DISABLED;
3327 key = erq->flags & IW_ENCODE_INDEX;
3334 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3336 erq->flags = key + 1;
3338 /* if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */
3340 /* erq->flags |= IW_ENCODE_OPEN; */
3343 switch (padapter->securitypriv.ndisencryptstatus) {
3344 case Ndis802_11EncryptionNotSupported:
3345 case Ndis802_11EncryptionDisabled:
3348 erq->flags |= IW_ENCODE_DISABLED;
3352 case Ndis802_11Encryption1Enabled:
3354 erq->length = padapter->securitypriv.dot11DefKeylen[key];
3357 _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
3359 erq->flags |= IW_ENCODE_ENABLED;
3361 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3362 erq->flags |= IW_ENCODE_OPEN;
3363 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
3364 erq->flags |= IW_ENCODE_RESTRICTED;
3367 erq->flags |= IW_ENCODE_DISABLED;
3372 case Ndis802_11Encryption2Enabled:
3373 case Ndis802_11Encryption3Enabled:
3376 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
3382 erq->flags |= IW_ENCODE_DISABLED;
3394 static int rtw_wx_get_power(struct net_device *dev,
3395 struct iw_request_info *info,
3396 union iwreq_data *wrqu, char *extra)
3398 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3400 wrqu->power.value = 0;
3401 wrqu->power.fixed = 0; /* no auto select */
3402 wrqu->power.disabled = 1;
3408 static int rtw_wx_set_gen_ie(struct net_device *dev,
3409 struct iw_request_info *info,
3410 union iwreq_data *wrqu, char *extra)
3413 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3415 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
3420 static int rtw_wx_set_auth(struct net_device *dev,
3421 struct iw_request_info *info,
3422 union iwreq_data *wrqu, char *extra)
3424 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3425 struct iw_param *param = (struct iw_param *)&(wrqu->param);
3426 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3427 struct security_priv *psecuritypriv = &padapter->securitypriv;
3428 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3429 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3430 u32 value = param->value;
3433 switch (param->flags & IW_AUTH_INDEX) {
3435 case IW_AUTH_WPA_VERSION:
3436 #ifdef CONFIG_WAPI_SUPPORT
3437 #ifndef CONFIG_IOCTL_CFG80211
3438 padapter->wapiInfo.bWapiEnable = false;
3439 if (value == IW_AUTH_WAPI_VERSION_1) {
3440 padapter->wapiInfo.bWapiEnable = true;
3441 psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
3442 psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
3443 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3444 pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
3445 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3446 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3451 case IW_AUTH_CIPHER_PAIRWISE:
3454 case IW_AUTH_CIPHER_GROUP:
3457 case IW_AUTH_KEY_MGMT:
3458 #ifdef CONFIG_WAPI_SUPPORT
3459 #ifndef CONFIG_IOCTL_CFG80211
3460 RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case\n");
3461 if (value == IW_AUTH_KEY_MGMT_WAPI_PSK)
3462 padapter->wapiInfo.bWapiPSK = true;
3464 padapter->wapiInfo.bWapiPSK = false;
3465 RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d\n", padapter->wapiInfo.bWapiPSK);
3469 * ??? does not use these parameters
3473 case IW_AUTH_TKIP_COUNTERMEASURES: {
3475 /* wpa_supplicant is enabling the tkip countermeasure. */
3476 padapter->securitypriv.btkip_countermeasure = _TRUE;
3478 /* wpa_supplicant is disabling the tkip countermeasure. */
3479 padapter->securitypriv.btkip_countermeasure = _FALSE;
3483 case IW_AUTH_DROP_UNENCRYPTED: {
3486 * wpa_supplicant calls set_wpa_enabled when the driver
3487 * is loaded and unloaded, regardless of if WPA is being
3488 * used. No other calls are made which can be used to
3489 * determine if encryption will be used or not prior to
3490 * association being expected. If encryption is not being
3491 * used, drop_unencrypted is set to false, else true -- we
3492 * can use this to determine if the CAP_PRIVACY_ON bit should
3496 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) {
3497 break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
3498 /* then it needn't reset it; */
3502 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3503 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3504 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3505 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3506 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
3512 case IW_AUTH_80211_AUTH_ALG:
3514 #if defined(CONFIG_ANDROID) || 1
3516 * It's the starting point of a link layer connection using wpa_supplicant
3518 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3519 LeaveAllPowerSaveMode(padapter);
3520 rtw_disassoc_cmd(padapter, 500, _FALSE);
3521 RTW_INFO("%s...call rtw_indicate_disconnect\n ", __FUNCTION__);
3522 rtw_indicate_disconnect(padapter, 0, _FALSE);
3523 rtw_free_assoc_resources(padapter, 1);
3528 ret = wpa_set_auth_algs(dev, (u32)param->value);
3532 case IW_AUTH_WPA_ENABLED:
3534 /* if(param->value) */
3535 /* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; */ /* 802.1x */
3537 /* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; */ /* open system */
3539 /* _disassociate(priv); */
3543 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3544 /* ieee->ieee802_1x = param->value; */
3547 case IW_AUTH_PRIVACY_INVOKED:
3548 /* ieee->privacy_invoked = param->value; */
3551 #ifdef CONFIG_WAPI_SUPPORT
3552 #ifndef CONFIG_IOCTL_CFG80211
3553 case IW_AUTH_WAPI_ENABLED:
3567 static int rtw_wx_set_enc_ext(struct net_device *dev,
3568 struct iw_request_info *info,
3569 union iwreq_data *wrqu, char *extra)
3573 struct ieee_param *param = NULL;
3574 struct iw_point *pencoding = &wrqu->encoding;
3575 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3578 param_len = sizeof(struct ieee_param) + pext->key_len;
3579 param = (struct ieee_param *)rtw_malloc(param_len);
3583 _rtw_memset(param, 0, param_len);
3585 param->cmd = IEEE_CMD_SET_ENCRYPTION;
3586 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3589 switch (pext->alg) {
3590 case IW_ENCODE_ALG_NONE:
3591 /* todo: remove key */
3595 case IW_ENCODE_ALG_WEP:
3598 case IW_ENCODE_ALG_TKIP:
3601 case IW_ENCODE_ALG_CCMP:
3604 #ifdef CONFIG_IEEE80211W
3605 case IW_ENCODE_ALG_AES_CMAC:
3608 #endif /* CONFIG_IEEE80211W */
3609 #ifdef CONFIG_WAPI_SUPPORT
3610 #ifndef CONFIG_IOCTL_CFG80211
3611 case IW_ENCODE_ALG_SM4:
3613 _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3614 RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
3623 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3625 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3626 param->u.crypt.set_tx = 1;
3628 /* cliW: WEP does not have group key
3629 * just not checking GROUP key setting
3631 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3632 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3633 #ifdef CONFIG_IEEE80211W
3634 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3635 #endif /* CONFIG_IEEE80211W */
3637 param->u.crypt.set_tx = 0;
3639 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1 ;
3641 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3642 #ifdef CONFIG_WAPI_SUPPORT
3643 #ifndef CONFIG_IOCTL_CFG80211
3644 if (pext->alg == IW_ENCODE_ALG_SM4)
3645 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3647 #endif /* CONFIG_IOCTL_CFG80211 */
3648 #endif /* CONFIG_WAPI_SUPPORT */
3649 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3652 if (pext->key_len) {
3653 param->u.crypt.key_len = pext->key_len;
3654 /* _rtw_memcpy(param + 1, pext + 1, pext->key_len); */
3655 _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3658 if (pencoding->flags & IW_ENCODE_DISABLED) {
3659 /* todo: remove key */
3663 ret = wpa_set_encryption(dev, param, param_len);
3667 rtw_mfree((u8 *)param, param_len);
3673 static int rtw_wx_get_nick(struct net_device *dev,
3674 struct iw_request_info *info,
3675 union iwreq_data *wrqu, char *extra)
3677 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3678 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3679 /* struct security_priv *psecuritypriv = &padapter->securitypriv; */
3682 wrqu->data.length = 14;
3683 wrqu->data.flags = 1;
3684 _rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
3687 /* rtw_signal_process(pid, SIGUSR1); */ /* for test */
3689 /* dump debug info here */
3691 u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, shared, and 8021x */
3692 u32 dot11PrivacyAlgrthm; /* This specify the privacy for shared auth. algorithm. */
3693 u32 dot118021XGrpPrivacy; /* This specify the privacy algthm. used for Grp key */
3695 u32 ndisencryptstatus;
3698 /* RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", */
3699 /* psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, */
3700 /* psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); */
3702 /* RTW_INFO("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); */
3703 /* RTW_INFO("auth_type=0x%x\n", psecuritypriv->ndisauthtype); */
3704 /* RTW_INFO("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); */
3707 RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3708 RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3709 RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3710 RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3711 RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3713 RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3718 RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3719 RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3721 RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3723 RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3725 RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3726 RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3728 RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3729 RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3730 RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3731 RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3738 static int rtw_wx_read32(struct net_device *dev,
3739 struct iw_request_info *info,
3740 union iwreq_data *wrqu, char *extra)
3753 padapter = (PADAPTER)rtw_netdev_priv(dev);
3759 ptmp = (u8 *)rtw_malloc(len);
3763 if (copy_from_user(ptmp, p->pointer, len)) {
3770 sscanf(ptmp, "%d,%x", &bytes, &addr);
3774 data32 = rtw_read8(padapter, addr);
3775 sprintf(extra, "0x%02X", data32);
3778 data32 = rtw_read16(padapter, addr);
3779 sprintf(extra, "0x%04X", data32);
3782 data32 = rtw_read32(padapter, addr);
3783 sprintf(extra, "0x%08X", data32);
3786 RTW_INFO("%s: usage> read [bytes],[address(hex)]\n", __func__);
3790 RTW_INFO("%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3793 rtw_mfree(ptmp, len);
3798 static int rtw_wx_write32(struct net_device *dev,
3799 struct iw_request_info *info,
3800 union iwreq_data *wrqu, char *extra)
3802 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3812 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3816 rtw_write8(padapter, addr, (u8)data32);
3817 RTW_INFO("%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3820 rtw_write16(padapter, addr, (u16)data32);
3821 RTW_INFO("%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3824 rtw_write32(padapter, addr, data32);
3825 RTW_INFO("%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3828 RTW_INFO("%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3835 static int rtw_wx_read_rf(struct net_device *dev,
3836 struct iw_request_info *info,
3837 union iwreq_data *wrqu, char *extra)
3839 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3840 u32 path, addr, data32;
3843 path = *(u32 *)extra;
3844 addr = *((u32 *)extra + 1);
3845 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3846 /* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3849 * Only when wireless private ioctl is at odd order,
3850 * "extra" would be copied to user space.
3852 sprintf(extra, "0x%05x", data32);
3857 static int rtw_wx_write_rf(struct net_device *dev,
3858 struct iw_request_info *info,
3859 union iwreq_data *wrqu, char *extra)
3861 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3862 u32 path, addr, data32;
3865 path = *(u32 *)extra;
3866 addr = *((u32 *)extra + 1);
3867 data32 = *((u32 *)extra + 2);
3868 /* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3869 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3874 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3875 union iwreq_data *wrqu, char *b)
3880 static int dummy(struct net_device *dev, struct iw_request_info *a,
3881 union iwreq_data *wrqu, char *b)
3883 /* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3884 /* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3886 /* RTW_INFO("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); */
3892 static int rtw_wx_set_channel_plan(struct net_device *dev,
3893 struct iw_request_info *info,
3894 union iwreq_data *wrqu, char *extra)
3896 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3897 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3898 u8 channel_plan_req = (u8)(*((int *)wrqu));
3900 if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req))
3906 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3907 struct iw_request_info *a,
3908 union iwreq_data *wrqu, char *b)
3910 #ifdef CONFIG_PLATFORM_MT53XX
3911 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3912 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3914 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
3915 ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n",
3916 a->cmd, get_fwstate(pmlmepriv)));
3921 static int rtw_wx_get_sensitivity(struct net_device *dev,
3922 struct iw_request_info *info,
3923 union iwreq_data *wrqu, char *buf)
3925 #ifdef CONFIG_PLATFORM_MT53XX
3926 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3928 /* Modified by Albert 20110914 */
3929 /* This is in dbm format for MTK platform. */
3930 wrqu->qual.level = padapter->recvpriv.rssi;
3931 RTW_INFO(" level = %u\n", wrqu->qual.level);
3936 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3937 struct iw_request_info *info,
3938 union iwreq_data *wrqu, char *extra)
3940 #ifdef CONFIG_PLATFORM_MT53XX
3941 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3943 return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3950 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
3951 union iwreq_data *wrqu, char *extra);
3954 * For all data larger than 16 octets, we need to use a
3955 * pointer to memory allocated in user space.
3957 static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
3958 union iwreq_data *wrqu, char *extra)
3963 void __user *pointer; /* Pointer to the data (in user space) */
3964 __u16 length; /* number of fields or size in bytes */
3965 __u16 flags; /* Optional params */
3969 #ifdef CONFIG_DRVEXT_MODULE
3971 struct drvext_handler *phandler;
3972 struct drvext_oidparam *poidparam;
3976 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3977 struct iw_point *p = &wrqu->data;
3979 if ((!p->length) || (!p->pointer)) {
3981 goto _rtw_drvext_hdl_exit;
3985 bset = (u8)(p->flags & 0xFFFF);
3987 pparmbuf = (u8 *)rtw_malloc(len);
3988 if (pparmbuf == NULL) {
3990 goto _rtw_drvext_hdl_exit;
3993 if (bset) { /* set info */
3994 if (copy_from_user(pparmbuf, p->pointer, len)) {
3995 rtw_mfree(pparmbuf, len);
3997 goto _rtw_drvext_hdl_exit;
3999 } else { /* query info */
4005 poidparam = (struct drvext_oidparam *)pparmbuf;
4007 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n",
4008 poidparam->subcode, poidparam->len, len));
4012 if (poidparam->subcode >= MAX_DRVEXT_HANDLERS) {
4013 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext handlers\r\n"));
4015 goto _rtw_drvext_hdl_exit;
4019 if (poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES) {
4020 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
4022 goto _rtw_drvext_hdl_exit;
4026 phandler = drvextoidhandlers + poidparam->subcode;
4028 if (poidparam->len != phandler->parmsize) {
4029 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext param size %d vs %d\r\n",
4030 poidparam->len , phandler->parmsize));
4032 goto _rtw_drvext_hdl_exit;
4036 res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data);
4041 if (bset == 0x00) {/* query info */
4042 /* _rtw_memcpy(p->pointer, pparmbuf, len); */
4043 if (copy_to_user(p->pointer, pparmbuf, len))
4050 _rtw_drvext_hdl_exit:
4060 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
4062 pRW_Reg RegRWStruct;
4063 struct rf_reg_param *prfreg;
4068 RTW_INFO("%s\n", __FUNCTION__);
4071 case GEN_MP_IOCTL_SUBCODE(MP_START):
4072 RTW_INFO("871x_driver is only for normal mode, can't enter mp mode\n");
4074 case GEN_MP_IOCTL_SUBCODE(READ_REG):
4075 RegRWStruct = (pRW_Reg)pdata;
4076 switch (RegRWStruct->width) {
4078 RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
4081 RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
4084 RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
4091 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
4092 RegRWStruct = (pRW_Reg)pdata;
4093 switch (RegRWStruct->width) {
4095 rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
4098 rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
4101 rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
4108 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
4110 prfreg = (struct rf_reg_param *)pdata;
4112 path = (u8)prfreg->path;
4113 offset = (u8)prfreg->offset;
4115 value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
4117 prfreg->value = value;
4120 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
4122 prfreg = (struct rf_reg_param *)pdata;
4124 path = (u8)prfreg->path;
4125 offset = (u8)prfreg->offset;
4126 value = prfreg->value;
4128 rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
4131 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
4132 RTW_INFO("==> trigger gpio 0\n");
4133 rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
4135 #ifdef CONFIG_BT_COEXIST
4136 case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):
4137 RTW_INFO("==> set dm_bt_coexist:%x\n", *(u8 *)pdata);
4138 rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
4140 case GEN_MP_IOCTL_SUBCODE(DEL_BA):
4141 RTW_INFO("==> delete ba:%x\n", *(u8 *)pdata);
4142 rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
4145 #ifdef DBG_CONFIG_ERROR_DETECT
4146 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
4147 *pdata = rtw_hal_sreset_get_wifi_status(padapter);
4157 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
4158 union iwreq_data *wrqu, char *extra)
4161 u32 BytesRead, BytesWritten, BytesNeeded;
4162 struct oid_par_priv oid_par;
4163 struct mp_ioctl_handler *phandler;
4164 struct mp_ioctl_param *poidparam;
4167 u8 *pparmbuf = NULL, bset;
4168 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
4169 struct iw_point *p = &wrqu->data;
4171 /* RTW_INFO("+rtw_mp_ioctl_hdl\n"); */
4173 /* mutex_lock(&ioctl_mutex); */
4175 if ((!p->length) || (!p->pointer)) {
4177 goto _rtw_mp_ioctl_hdl_exit;
4181 bset = (u8)(p->flags & 0xFFFF);
4183 pparmbuf = (u8 *)rtw_malloc(len);
4184 if (pparmbuf == NULL) {
4186 goto _rtw_mp_ioctl_hdl_exit;
4189 if (copy_from_user(pparmbuf, p->pointer, len)) {
4191 goto _rtw_mp_ioctl_hdl_exit;
4194 poidparam = (struct mp_ioctl_param *)pparmbuf;
4195 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
4196 ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n",
4197 poidparam->subcode, poidparam->len, len));
4199 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
4200 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
4202 goto _rtw_mp_ioctl_hdl_exit;
4205 /* RTW_INFO("%s: %d\n", __func__, poidparam->subcode); */
4206 #ifdef CONFIG_MP_INCLUDED
4207 if (padapter->registrypriv.mp_mode == 1) {
4208 phandler = mp_ioctl_hdl + poidparam->subcode;
4210 if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {
4211 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
4212 ("no matching drvext param size %d vs %d\r\n",
4213 poidparam->len, phandler->paramsize));
4215 goto _rtw_mp_ioctl_hdl_exit;
4218 if (phandler->handler) {
4219 oid_par.adapter_context = padapter;
4220 oid_par.oid = phandler->oid;
4221 oid_par.information_buf = poidparam->data;
4222 oid_par.information_buf_len = poidparam->len;
4229 oid_par.bytes_rw = &BytesRead;
4230 oid_par.bytes_needed = &BytesNeeded;
4231 oid_par.type_of_oid = SET_OID;
4233 oid_par.bytes_rw = &BytesWritten;
4234 oid_par.bytes_needed = &BytesNeeded;
4235 oid_par.type_of_oid = QUERY_OID;
4238 status = phandler->handler(&oid_par);
4240 /* todo:check status, BytesNeeded, etc. */
4242 RTW_INFO("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",
4243 poidparam->subcode, phandler->oid, phandler->handler);
4245 goto _rtw_mp_ioctl_hdl_exit;
4250 rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
4253 if (bset == 0x00) {/* query info */
4254 if (copy_to_user(p->pointer, pparmbuf, len))
4260 goto _rtw_mp_ioctl_hdl_exit;
4263 _rtw_mp_ioctl_hdl_exit:
4266 rtw_mfree(pparmbuf, len);
4268 /* mutex_unlock(&ioctl_mutex); */
4273 static int rtw_get_ap_info(struct net_device *dev,
4274 struct iw_request_info *info,
4275 union iwreq_data *wrqu, char *extra)
4277 int bssid_match, ret = 0;
4278 u32 cnt = 0, wpa_ielen;
4280 _list *plist, *phead;
4281 unsigned char *pbuf;
4284 struct wlan_network *pnetwork = NULL;
4285 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4286 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4287 _queue *queue = &(pmlmepriv->scanned_queue);
4288 struct iw_point *pdata = &wrqu->data;
4290 RTW_INFO("+rtw_get_aplist_info\n");
4292 if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
4297 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING))) == _TRUE) {
4305 /* pdata->length = 0; */ /* ? */
4307 if (pdata->length >= 32) {
4308 if (copy_from_user(data, pdata->pointer, 32)) {
4317 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4319 phead = get_list_head(queue);
4320 plist = get_next(phead);
4323 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4327 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4329 /* if(hwaddr_aton_i(pdata->pointer, bssid)) */
4330 if (hwaddr_aton_i(data, bssid)) {
4331 RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data);
4332 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4337 if (_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) { /* BSSID match, then check if supporting wpa/wpa2 */
4338 RTW_INFO("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
4340 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
4341 if (pbuf && (wpa_ielen > 0)) {
4346 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
4347 if (pbuf && (wpa_ielen > 0)) {
4354 plist = get_next(plist);
4358 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4360 if (pdata->length >= 34) {
4361 if (copy_to_user((u8 *)pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
4373 static int rtw_set_pid(struct net_device *dev,
4374 struct iw_request_info *info,
4375 union iwreq_data *wrqu, char *extra)
4379 _adapter *padapter = rtw_netdev_priv(dev);
4380 int *pdata = (int *)wrqu;
4383 if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
4389 if (selector < 3 && selector >= 0) {
4390 padapter->pid[selector] = *(pdata + 1);
4391 #ifdef CONFIG_GLOBAL_UI_PID
4392 ui_pid[selector] = *(pdata + 1);
4394 RTW_INFO("%s set pid[%d]=%d\n", __FUNCTION__, selector , padapter->pid[selector]);
4396 RTW_INFO("%s selector %d error\n", __FUNCTION__, selector);
4404 static int rtw_wps_start(struct net_device *dev,
4405 struct iw_request_info *info,
4406 union iwreq_data *wrqu, char *extra)
4410 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4411 struct iw_point *pdata = &wrqu->data;
4412 u32 u32wps_start = 0;
4413 unsigned int uintRet = 0;
4415 if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) {
4420 uintRet = copy_from_user((void *) &u32wps_start, pdata->pointer, 4);
4421 if (u32wps_start == 0)
4422 u32wps_start = *extra;
4424 RTW_INFO("[%s] wps_start = %d\n", __FUNCTION__, u32wps_start);
4426 if (u32wps_start == 1) /* WPS Start */
4427 rtw_led_control(padapter, LED_CTL_START_WPS);
4428 else if (u32wps_start == 2) /* WPS Stop because of wps success */
4429 rtw_led_control(padapter, LED_CTL_STOP_WPS);
4430 else if (u32wps_start == 3) /* WPS Stop because of wps fail */
4431 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
4433 #ifdef CONFIG_INTEL_WIDI
4434 process_intel_widi_wps_status(padapter, u32wps_start);
4435 #endif /* CONFIG_INTEL_WIDI */
4444 static int rtw_wext_p2p_enable(struct net_device *dev,
4445 struct iw_request_info *info,
4446 union iwreq_data *wrqu, char *extra)
4450 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4451 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4452 struct iw_point *pdata = &wrqu->data;
4453 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4454 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4455 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
4458 init_role = P2P_ROLE_DISABLE;
4459 else if (*extra == '1')
4460 init_role = P2P_ROLE_DEVICE;
4461 else if (*extra == '2')
4462 init_role = P2P_ROLE_CLIENT;
4463 else if (*extra == '3')
4464 init_role = P2P_ROLE_GO;
4466 if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
4471 /* set channel/bandwidth */
4472 if (init_role != P2P_ROLE_DISABLE) {
4473 u8 channel, ch_offset;
4476 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
4477 /* Stay at the listen state and wait for discovery. */
4478 channel = pwdinfo->listen_channel;
4479 pwdinfo->operating_channel = pwdinfo->listen_channel;
4480 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4481 bwmode = CHANNEL_WIDTH_20;
4483 #ifdef CONFIG_CONCURRENT_MODE
4484 else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
4486 _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval);
4488 channel = rtw_mi_get_union_chan(padapter);
4489 ch_offset = rtw_mi_get_union_offset(padapter);
4490 bwmode = rtw_mi_get_union_bw(padapter);
4492 pwdinfo->operating_channel = channel;
4496 pwdinfo->operating_channel = pmlmeext->cur_channel;
4498 channel = pwdinfo->operating_channel;
4499 ch_offset = pmlmeext->cur_ch_offset;
4500 bwmode = pmlmeext->cur_bwmode;
4503 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
4511 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
4512 struct iw_request_info *info,
4513 union iwreq_data *wrqu, char *extra)
4517 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4518 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4519 struct iw_point *pdata = &wrqu->data;
4520 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4522 RTW_INFO("[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen(extra));
4523 _rtw_memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
4524 pwdinfo->nego_ssidlen = strlen(extra);
4531 static int rtw_p2p_set_intent(struct net_device *dev,
4532 struct iw_request_info *info,
4533 union iwreq_data *wrqu, char *extra)
4536 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4537 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4538 u8 intent = pwdinfo->intent;
4540 extra[wrqu->data.length] = 0x00;
4542 intent = rtw_atoi(extra);
4545 pwdinfo->intent = intent;
4549 RTW_INFO("[%s] intent = %d\n", __FUNCTION__, intent);
4555 static int rtw_p2p_set_listen_ch(struct net_device *dev,
4556 struct iw_request_info *info,
4557 union iwreq_data *wrqu, char *extra)
4561 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4562 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4563 u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */
4565 extra[wrqu->data.length] = 0x00;
4566 listen_ch = rtw_atoi(extra);
4568 if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
4569 pwdinfo->listen_channel = listen_ch;
4570 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4574 RTW_INFO("[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel);
4580 static int rtw_p2p_set_op_ch(struct net_device *dev,
4581 struct iw_request_info *info,
4582 union iwreq_data *wrqu, char *extra)
4584 /* Commented by Albert 20110524
4585 * This function is used to set the operating channel if the driver will become the group owner */
4588 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4589 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4590 u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */
4592 extra[wrqu->data.length] = 0x00;
4594 op_ch = (u8) rtw_atoi(extra);
4596 pwdinfo->operating_channel = op_ch;
4600 RTW_INFO("[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel);
4607 static int rtw_p2p_profilefound(struct net_device *dev,
4608 struct iw_request_info *info,
4609 union iwreq_data *wrqu, char *extra)
4613 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4614 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4616 /* Comment by Albert 2010/10/13 */
4617 /* Input data format: */
4619 /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
4620 /* 0 => Reflush the profile record list. */
4621 /* 1 => Add the profile list */
4622 /* XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) */
4623 /* YY => SSID Length */
4624 /* SSID => SSID for persistence group */
4626 RTW_INFO("[%s] In value = %s, len = %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4629 /* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
4630 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4631 if (extra[0] == '0') {
4632 /* Remove all the profile information of wifidirect_info structure. */
4633 _rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
4634 pwdinfo->profileindex = 0;
4636 if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM)
4641 /* Add this profile information into pwdinfo->profileinfo */
4642 /* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
4643 for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
4644 pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4646 /* pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[19] - '0' ); */
4647 /* _rtw_memcpy( pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen ); */
4648 pwdinfo->profileindex++;
4657 static int rtw_p2p_setDN(struct net_device *dev,
4658 struct iw_request_info *info,
4659 union iwreq_data *wrqu, char *extra)
4663 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4664 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4667 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4668 _rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
4669 _rtw_memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
4670 pwdinfo->device_name_len = wrqu->data.length - 1;
4677 static int rtw_p2p_get_status(struct net_device *dev,
4678 struct iw_request_info *info,
4679 union iwreq_data *wrqu, char *extra)
4683 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4684 struct iw_point *pdata = &wrqu->data;
4685 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4687 if (padapter->bShowGetP2PState) {
4688 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),
4689 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4690 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4693 /* Commented by Albert 2010/10/12 */
4694 /* Because of the output size limitation, I had removed the "Role" information. */
4695 /* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
4696 sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
4697 wrqu->data.length = strlen(extra);
4703 /* Commented by Albert 20110520
4704 * This function will return the config method description
4705 * This config method description will show us which config method the remote P2P device is intented to use
4706 * by sending the provisioning discovery request frame. */
4708 static int rtw_p2p_get_req_cm(struct net_device *dev,
4709 struct iw_request_info *info,
4710 union iwreq_data *wrqu, char *extra)
4714 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4715 struct iw_point *pdata = &wrqu->data;
4716 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4718 sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
4719 wrqu->data.length = strlen(extra);
4725 static int rtw_p2p_get_role(struct net_device *dev,
4726 struct iw_request_info *info,
4727 union iwreq_data *wrqu, char *extra)
4731 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4732 struct iw_point *pdata = &wrqu->data;
4733 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4736 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),
4737 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4738 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4740 sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
4741 wrqu->data.length = strlen(extra);
4747 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4748 struct iw_request_info *info,
4749 union iwreq_data *wrqu, char *extra)
4753 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4754 struct iw_point *pdata = &wrqu->data;
4755 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4758 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),
4759 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4760 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4762 sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4763 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4764 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4765 wrqu->data.length = strlen(extra);
4770 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4771 struct iw_request_info *info,
4772 union iwreq_data *wrqu, char *extra)
4777 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4778 struct iw_point *pdata = &wrqu->data;
4779 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4781 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),
4782 pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4783 pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4784 pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4785 sprintf(extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4786 pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4787 pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4788 pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4789 wrqu->data.length = strlen(extra);
4794 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4795 struct iw_request_info *info,
4796 union iwreq_data *wrqu, char *extra)
4801 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4802 struct iw_point *pdata = &wrqu->data;
4803 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4805 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),
4806 pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4807 pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4808 pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4809 sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4810 pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4811 pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4812 pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4813 wrqu->data.length = strlen(extra);
4818 static int rtw_p2p_get_groupid(struct net_device *dev,
4819 struct iw_request_info *info,
4820 union iwreq_data *wrqu, char *extra)
4825 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4826 struct iw_point *pdata = &wrqu->data;
4827 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4829 sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4830 pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
4831 pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
4832 pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
4833 pwdinfo->groupid_info.ssid);
4834 wrqu->data.length = strlen(extra);
4839 static int rtw_p2p_get_op_ch(struct net_device *dev,
4840 struct iw_request_info *info,
4841 union iwreq_data *wrqu, char *extra)
4846 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4847 struct iw_point *pdata = &wrqu->data;
4848 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4851 RTW_INFO("[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4853 sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
4854 wrqu->data.length = strlen(extra);
4859 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4860 struct iw_request_info *info,
4861 union iwreq_data *wrqu, char *extra, char *subcmd)
4865 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4866 u8 peerMAC[ETH_ALEN] = { 0x00 };
4867 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4869 _list *plist, *phead;
4870 _queue *queue = &(pmlmepriv->scanned_queue);
4871 struct wlan_network *pnetwork = NULL;
4873 u16 attr_content = 0;
4874 uint attr_contentlen = 0;
4875 u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4877 /* Commented by Albert 20110727 */
4878 /* The input data is the MAC address which the application wants to know its WPS config method. */
4879 /* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
4880 /* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
4882 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4884 macstr2num(peerMAC, subcmd);
4886 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4888 phead = get_list_head(queue);
4889 plist = get_next(phead);
4892 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4895 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4896 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4900 /* The mac address is matched. */
4902 wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4904 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4905 if (attr_contentlen) {
4906 attr_content = be16_to_cpu(attr_content);
4907 sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4915 plist = get_next(plist);
4919 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4922 sprintf(attr_content_str, "\n\nM=0000");
4924 wrqu->data.length = strlen(attr_content_str);
4925 _rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4932 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4933 struct iw_request_info *info,
4934 union iwreq_data *wrqu, char *extra)
4938 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4939 struct iw_point *pdata = &wrqu->data;
4940 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4942 RTW_INFO("[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
4944 sprintf(extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport);
4945 RTW_INFO("[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
4947 wrqu->data.length = strlen(extra);
4952 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4953 struct iw_request_info *info,
4954 union iwreq_data *wrqu, char *extra)
4958 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4959 struct iw_point *pdata = &wrqu->data;
4960 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4962 sprintf(extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc);
4963 RTW_INFO("[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc);
4965 wrqu->data.length = strlen(extra);
4966 pwdinfo->wfd_info->wfd_pc = _FALSE; /* Reset the WFD preferred connection to P2P */
4971 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4972 struct iw_request_info *info,
4973 union iwreq_data *wrqu, char *extra)
4977 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4978 struct iw_point *pdata = &wrqu->data;
4979 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4981 sprintf(extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail);
4982 RTW_INFO("[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail);
4984 wrqu->data.length = strlen(extra);
4985 pwdinfo->wfd_info->peer_session_avail = _TRUE; /* Reset the WFD session available */
4989 #endif /* CONFIG_WFD */
4991 static int rtw_p2p_get_go_device_address(struct net_device *dev,
4992 struct iw_request_info *info,
4993 union iwreq_data *wrqu, char *extra, char *subcmd)
4997 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4998 u8 peerMAC[ETH_ALEN] = { 0x00 };
4999 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5001 _list *plist, *phead;
5002 _queue *queue = &(pmlmepriv->scanned_queue);
5003 struct wlan_network *pnetwork = NULL;
5006 uint p2pielen = 0, attr_contentlen = 0;
5007 u8 attr_content[100] = { 0x00 };
5008 u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5010 /* Commented by Albert 20121209 */
5011 /* The input data is the GO's interface address which the application wants to know its device address. */
5012 /* Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 */
5014 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
5016 macstr2num(peerMAC, subcmd);
5018 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5020 phead = get_list_head(queue);
5021 plist = get_next(phead);
5024 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5027 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5028 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
5029 /* Commented by Albert 2011/05/18 */
5030 /* Match the device address located in the P2P IE */
5031 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
5033 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5036 /* The P2P Device ID attribute is included in the Beacon frame. */
5037 /* The P2P Device Info attribute is included in the probe response frame. */
5039 _rtw_memset(attr_content, 0x00, 100);
5040 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5041 /* Handle the P2P Device ID attribute of Beacon first */
5045 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5046 /* Handle the P2P Device Info attribute of probe response */
5051 /* Get the next P2P IE */
5052 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5057 plist = get_next(plist);
5061 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5064 sprintf(go_devadd_str, "\n\ndev_add=NULL");
5066 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
5067 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
5070 wrqu->data.length = strlen(go_devadd_str);
5071 _rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
5077 static int rtw_p2p_get_device_type(struct net_device *dev,
5078 struct iw_request_info *info,
5079 union iwreq_data *wrqu, char *extra, char *subcmd)
5083 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5084 u8 peerMAC[ETH_ALEN] = { 0x00 };
5085 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5087 _list *plist, *phead;
5088 _queue *queue = &(pmlmepriv->scanned_queue);
5089 struct wlan_network *pnetwork = NULL;
5091 u8 dev_type[8] = { 0x00 };
5092 uint dev_type_len = 0;
5093 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 */
5095 /* Commented by Albert 20121209 */
5096 /* The input data is the MAC address which the application wants to know its device type. */
5097 /* Such user interface could know the device type. */
5098 /* Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 */
5100 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
5102 macstr2num(peerMAC, subcmd);
5104 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5106 phead = get_list_head(queue);
5107 plist = get_next(phead);
5110 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5113 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5114 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
5118 /* The mac address is matched. */
5120 wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
5122 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
5126 _rtw_memcpy(&type, dev_type, 2);
5127 type = be16_to_cpu(type);
5128 sprintf(dev_type_str, "\n\nN=%.2d", type);
5135 plist = get_next(plist);
5139 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5142 sprintf(dev_type_str, "\n\nN=00");
5144 wrqu->data.length = strlen(dev_type_str);
5145 _rtw_memcpy(extra, dev_type_str, wrqu->data.length);
5151 static int rtw_p2p_get_device_name(struct net_device *dev,
5152 struct iw_request_info *info,
5153 union iwreq_data *wrqu, char *extra, char *subcmd)
5157 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5158 u8 peerMAC[ETH_ALEN] = { 0x00 };
5159 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5161 _list *plist, *phead;
5162 _queue *queue = &(pmlmepriv->scanned_queue);
5163 struct wlan_network *pnetwork = NULL;
5165 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
5167 u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5169 /* Commented by Albert 20121225 */
5170 /* The input data is the MAC address which the application wants to know its device name. */
5171 /* Such user interface could show peer device's device name instead of ssid. */
5172 /* Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 */
5174 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
5176 macstr2num(peerMAC, subcmd);
5178 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5180 phead = get_list_head(queue);
5181 plist = get_next(phead);
5184 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5187 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5188 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
5192 /* The mac address is matched. */
5194 wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
5196 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
5198 sprintf(dev_name_str, "\n\nN=%s", dev_name);
5205 plist = get_next(plist);
5209 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5212 sprintf(dev_name_str, "\n\nN=0000");
5214 wrqu->data.length = strlen(dev_name_str);
5215 _rtw_memcpy(extra, dev_name_str, wrqu->data.length);
5221 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
5222 struct iw_request_info *info,
5223 union iwreq_data *wrqu, char *extra, char *subcmd)
5227 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5228 u8 peerMAC[ETH_ALEN] = { 0x00 };
5229 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5231 _list *plist, *phead;
5232 _queue *queue = &(pmlmepriv->scanned_queue);
5233 struct wlan_network *pnetwork = NULL;
5236 uint p2pielen = 0, attr_contentlen = 0;
5237 u8 attr_content[2] = { 0x00 };
5238 u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5240 /* Commented by Ouden 20121226 */
5241 /* The application wants to know P2P initation procedure is support or not. */
5242 /* Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 */
5244 RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
5246 macstr2num(peerMAC, subcmd);
5248 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5250 phead = get_list_head(queue);
5251 plist = get_next(phead);
5254 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5257 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5258 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
5259 /* Commented by Albert 20121226 */
5260 /* Match the device address located in the P2P IE */
5261 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
5263 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5266 /* _rtw_memset( attr_content, 0x00, 2); */
5267 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
5268 /* Handle the P2P capability attribute */
5274 /* Get the next P2P IE */
5275 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5280 plist = get_next(plist);
5284 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5287 sprintf(inv_proc_str, "\nIP=-1");
5289 if ((attr_content[0] & 0x20) == 0x20)
5290 sprintf(inv_proc_str, "\nIP=1");
5292 sprintf(inv_proc_str, "\nIP=0");
5295 wrqu->data.length = strlen(inv_proc_str);
5296 _rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
5302 static int rtw_p2p_connect(struct net_device *dev,
5303 struct iw_request_info *info,
5304 union iwreq_data *wrqu, char *extra)
5308 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5309 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5310 u8 peerMAC[ETH_ALEN] = { 0x00 };
5312 u8 peerMACStr[ETH_ALEN * 2] = { 0x00 };
5313 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5315 _list *plist, *phead;
5316 _queue *queue = &(pmlmepriv->scanned_queue);
5317 struct wlan_network *pnetwork = NULL;
5318 uint uintPeerChannel = 0;
5320 /* Commented by Albert 20110304 */
5321 /* The input data contains two informations. */
5322 /* 1. First information is the MAC address which wants to formate with */
5323 /* 2. Second information is the WPS PINCode or "pbc" string for push button method */
5324 /* Format: 00:E0:4C:00:00:05 */
5325 /* Format: 00:E0:4C:00:00:05 */
5327 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5329 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
5330 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5334 #ifdef CONFIG_INTEL_WIDI
5335 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
5336 RTW_INFO("[%s] WiFi is under survey!\n", __FUNCTION__);
5339 #endif /* CONFIG_INTEL_WIDI */
5341 if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
5344 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5345 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5347 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5349 phead = get_list_head(queue);
5350 plist = get_next(phead);
5353 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5356 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5357 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
5358 if (pnetwork->network.Configuration.DSConfig != 0)
5359 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5360 else if (pwdinfo->nego_req_info.peer_ch != 0)
5361 uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch;
5363 /* Unexpected case */
5364 uintPeerChannel = 0;
5365 RTW_INFO("%s uintPeerChannel = 0\n", __func__);
5370 plist = get_next(plist);
5374 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5376 if (uintPeerChannel) {
5377 #ifdef CONFIG_CONCURRENT_MODE
5378 if (rtw_mi_check_status(padapter, MI_LINKED))
5379 _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
5380 #endif /* CONFIG_CONCURRENT_MODE */
5382 _rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
5383 _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
5385 pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
5386 _rtw_memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
5387 pwdinfo->nego_req_info.benable = _TRUE;
5389 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
5390 if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
5391 /* Restore to the listen state if the current p2p state is not nego OK */
5392 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
5395 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5396 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
5398 #ifdef CONFIG_CONCURRENT_MODE
5399 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5400 u8 union_ch = rtw_mi_get_union_chan(padapter);
5401 u8 union_bw = rtw_mi_get_union_bw(padapter);
5402 u8 union_offset = rtw_mi_get_union_offset(padapter);
5403 /* Have to enter the power saving with the AP */
5404 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5406 rtw_mi_buddy_issue_nulldata(padapter, NULL, 1, 3, 500);
5408 #endif /* CONFIG_CONCURRENT_MODE */
5410 RTW_INFO("[%s] Start PreTx Procedure!\n", __FUNCTION__);
5411 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5412 #ifdef CONFIG_CONCURRENT_MODE
5413 if (rtw_mi_check_status(padapter, MI_LINKED))
5414 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT);
5416 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
5418 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
5419 #endif /* CONFIG_CONCURRENT_MODE */
5422 RTW_INFO("[%s] Not Found in Scanning Queue~\n", __FUNCTION__);
5423 #ifdef CONFIG_INTEL_WIDI
5424 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
5425 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
5426 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
5427 rtw_free_network_queue(padapter, _TRUE);
5429 * For WiDi, if we can't find candidate device in scanning queue,
5430 * driver will do scanning itself
5432 _enter_critical_bh(&pmlmepriv->lock, &irqL);
5433 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
5434 _exit_critical_bh(&pmlmepriv->lock, &irqL);
5435 #endif /* CONFIG_INTEL_WIDI */
5442 static int rtw_p2p_invite_req(struct net_device *dev,
5443 struct iw_request_info *info,
5444 union iwreq_data *wrqu, char *extra)
5448 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5449 struct iw_point *pdata = &wrqu->data;
5450 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5452 u8 peerMACStr[ETH_ALEN * 2] = { 0x00 };
5453 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5454 _list *plist, *phead;
5455 _queue *queue = &(pmlmepriv->scanned_queue);
5456 struct wlan_network *pnetwork = NULL;
5457 uint uintPeerChannel = 0;
5458 u8 attr_content[50] = { 0x00 }, _status = 0;
5460 uint p2pielen = 0, attr_contentlen = 0;
5462 struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
5464 /* Commented by Albert 20120321 */
5465 /* The input data contains two informations. */
5466 /* 1. First information is the P2P device address which you want to send to. */
5467 /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
5468 /* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
5469 /* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
5471 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5473 if (wrqu->data.length <= 37) {
5474 RTW_INFO("[%s] Wrong format!\n", __FUNCTION__);
5478 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5479 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5482 /* Reset the content of struct tx_invite_req_info */
5483 pinvite_req_info->benable = _FALSE;
5484 _rtw_memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
5485 _rtw_memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
5486 pinvite_req_info->ssidlen = 0x00;
5487 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
5488 _rtw_memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
5489 pinvite_req_info->token = 3;
5492 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5493 pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5495 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5497 phead = get_list_head(queue);
5498 plist = get_next(phead);
5501 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5504 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5506 /* Commented by Albert 2011/05/18 */
5507 /* Match the device address located in the P2P IE */
5508 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
5510 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5512 /* The P2P Device ID attribute is included in the Beacon frame. */
5513 /* The P2P Device Info attribute is included in the probe response frame. */
5515 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5516 /* Handle the P2P Device ID attribute of Beacon first */
5517 if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
5518 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5521 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5522 /* Handle the P2P Device Info attribute of probe response */
5523 if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
5524 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5531 plist = get_next(plist);
5535 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5538 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) {
5539 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5543 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5548 RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5549 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5551 u16 wfd_devinfo_field = 0;
5553 /* Commented by Albert 20120319 */
5554 /* The first two bytes are the WFD device information field of WFD device information subelement. */
5555 /* In big endian format. */
5556 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5557 if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
5558 pwfd_info->peer_session_avail = _TRUE;
5560 pwfd_info->peer_session_avail = _FALSE;
5564 if (_FALSE == pwfd_info->peer_session_avail) {
5565 RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
5569 #endif /* CONFIG_WFD */
5571 if (uintPeerChannel) {
5572 #ifdef CONFIG_CONCURRENT_MODE
5573 if (rtw_mi_check_status(padapter, MI_LINKED))
5574 _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
5575 #endif /* CONFIG_CONCURRENT_MODE */
5577 /* Store the GO's bssid */
5578 for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
5579 pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5581 /* Store the GO's ssid */
5582 pinvite_req_info->ssidlen = wrqu->data.length - 36;
5583 _rtw_memcpy(pinvite_req_info->go_ssid, &extra[36], (u32) pinvite_req_info->ssidlen);
5584 pinvite_req_info->benable = _TRUE;
5585 pinvite_req_info->peer_ch = uintPeerChannel;
5587 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5588 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
5590 #ifdef CONFIG_CONCURRENT_MODE
5591 if (rtw_mi_check_status(padapter, MI_LINKED)) {
5592 u8 union_ch = rtw_mi_get_union_chan(padapter);
5593 u8 union_bw = rtw_mi_get_union_bw(padapter);
5594 u8 union_offset = rtw_mi_get_union_offset(padapter);
5595 /* Have to enter the power saving with the AP */
5596 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5598 rtw_mi_buddy_issue_nulldata(padapter, NULL, 1, 3, 500);
5600 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5602 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5605 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5607 #ifdef CONFIG_CONCURRENT_MODE
5608 if (rtw_mi_check_status(padapter, MI_LINKED))
5609 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT);
5611 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5613 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5614 #endif /* CONFIG_CONCURRENT_MODE */
5618 RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5625 static int rtw_p2p_set_persistent(struct net_device *dev,
5626 struct iw_request_info *info,
5627 union iwreq_data *wrqu, char *extra)
5631 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5632 struct iw_point *pdata = &wrqu->data;
5633 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5635 u8 peerMACStr[ETH_ALEN * 2] = { 0x00 };
5636 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5637 _list *plist, *phead;
5638 _queue *queue = &(pmlmepriv->scanned_queue);
5639 struct wlan_network *pnetwork = NULL;
5640 uint uintPeerChannel = 0;
5641 u8 attr_content[50] = { 0x00 }, _status = 0;
5643 uint p2pielen = 0, attr_contentlen = 0;
5645 struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
5647 /* Commented by Albert 20120328 */
5648 /* The input data is 0 or 1 */
5649 /* 0: disable persistent group functionality */
5650 /* 1: enable persistent group founctionality */
5652 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5654 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5655 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5658 if (extra[0] == '0') /* Disable the persistent group function. */
5659 pwdinfo->persistent_supported = _FALSE;
5660 else if (extra[0] == '1') /* Enable the persistent group function. */
5661 pwdinfo->persistent_supported = _TRUE;
5663 pwdinfo->persistent_supported = _FALSE;
5665 printk("[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported);
5673 static int hexstr2bin(const char *hex, u8 *buf, size_t len)
5677 const char *ipos = hex;
5680 for (i = 0; i < len; i++) {
5681 a = hex2byte_i(ipos);
5690 static int uuid_str2bin(const char *str, u8 *bin)
5698 if (hexstr2bin(pos, opos, 4))
5703 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5708 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5713 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5718 if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5724 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5725 struct iw_request_info *info,
5726 union iwreq_data *wrqu, char *extra)
5730 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5731 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5733 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5735 if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))
5736 pwdinfo->external_uuid = 1;
5738 pwdinfo->external_uuid = 0;
5746 static int rtw_p2p_set_pc(struct net_device *dev,
5747 struct iw_request_info *info,
5748 union iwreq_data *wrqu, char *extra)
5752 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5753 struct iw_point *pdata = &wrqu->data;
5754 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5755 u8 peerMAC[ETH_ALEN] = { 0x00 };
5757 u8 peerMACStr[ETH_ALEN * 2] = { 0x00 };
5758 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5759 _list *plist, *phead;
5760 _queue *queue = &(pmlmepriv->scanned_queue);
5761 struct wlan_network *pnetwork = NULL;
5762 u8 attr_content[50] = { 0x00 }, _status = 0;
5764 uint p2pielen = 0, attr_contentlen = 0;
5766 uint uintPeerChannel = 0;
5768 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5770 /* Commented by Albert 20120512 */
5771 /* 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) */
5772 /* Format: 00:E0:4C:00:00:05 */
5774 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5776 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5777 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5781 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5782 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5784 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5786 phead = get_list_head(queue);
5787 plist = get_next(phead);
5790 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5793 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5795 /* Commented by Albert 2011/05/18 */
5796 /* Match the device address located in the P2P IE */
5797 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
5799 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5801 /* The P2P Device ID attribute is included in the Beacon frame. */
5802 /* The P2P Device Info attribute is included in the probe response frame. */
5803 printk("[%s] Got P2P IE\n", __FUNCTION__);
5804 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5805 /* Handle the P2P Device ID attribute of Beacon first */
5806 printk("[%s] P2P_ATTR_DEVICE_ID\n", __FUNCTION__);
5807 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5808 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5811 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5812 /* Handle the P2P Device Info attribute of probe response */
5813 printk("[%s] P2P_ATTR_DEVICE_INFO\n", __FUNCTION__);
5814 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5815 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5822 plist = get_next(plist);
5826 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5827 printk("[%s] channel = %d\n", __FUNCTION__, uintPeerChannel);
5829 if (uintPeerChannel) {
5833 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5838 RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5839 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5841 u16 wfd_devinfo_field = 0;
5843 /* Commented by Albert 20120319 */
5844 /* The first two bytes are the WFD device information field of WFD device information subelement. */
5845 /* In big endian format. */
5846 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5847 if (wfd_devinfo_field & WFD_DEVINFO_PC_TDLS)
5848 pwfd_info->wfd_pc = _TRUE;
5850 pwfd_info->wfd_pc = _FALSE;
5854 RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5862 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5863 struct iw_request_info *info,
5864 union iwreq_data *wrqu, char *extra)
5868 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5869 struct iw_point *pdata = &wrqu->data;
5870 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5871 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5873 /* Commented by Albert 20120328 */
5874 /* The input data is 0 or 1 */
5875 /* 0: specify to Miracast source device */
5876 /* 1 or others: specify to Miracast sink device (display device) */
5878 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5880 if (extra[0] == '0') /* Set to Miracast source device. */
5881 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5882 else /* Set to Miracast sink device. */
5883 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5891 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
5892 struct iw_request_info *info,
5893 union iwreq_data *wrqu, char *extra)
5895 /* Commented by Kurt 20121206
5896 * This function is used to set wfd enabled */
5899 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5900 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5903 rtw_wfd_enable(padapter, 0);
5904 else if (*extra == '1')
5905 rtw_wfd_enable(padapter, 1);
5907 RTW_INFO("[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable);
5913 static int rtw_p2p_set_driver_iface(struct net_device *dev,
5914 struct iw_request_info *info,
5915 union iwreq_data *wrqu, char *extra)
5917 /* Commented by Kurt 20121206
5918 * This function is used to set driver iface is WEXT or CFG80211 */
5920 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5921 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5923 if (*extra == '1') {
5924 pwdinfo->driver_interface = DRIVER_WEXT;
5925 RTW_INFO("[%s] driver_interface = WEXT\n", __FUNCTION__);
5926 } else if (*extra == '2') {
5927 pwdinfo->driver_interface = DRIVER_CFG80211;
5928 RTW_INFO("[%s] driver_interface = CFG80211\n", __FUNCTION__);
5935 /* To set the WFD session available to enable or disable */
5936 static int rtw_p2p_set_sa(struct net_device *dev,
5937 struct iw_request_info *info,
5938 union iwreq_data *wrqu, char *extra)
5942 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5943 struct iw_point *pdata = &wrqu->data;
5944 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5945 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5947 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5950 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5953 if (extra[0] == '0') /* Disable the session available. */
5954 pwdinfo->session_available = _FALSE;
5955 else if (extra[0] == '1') /* Enable the session available. */
5956 pwdinfo->session_available = _TRUE;
5958 pwdinfo->session_available = _FALSE;
5960 printk("[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available);
5967 #endif /* CONFIG_WFD */
5969 static int rtw_p2p_prov_disc(struct net_device *dev,
5970 struct iw_request_info *info,
5971 union iwreq_data *wrqu, char *extra)
5974 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5975 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5976 u8 peerMAC[ETH_ALEN] = { 0x00 };
5978 u8 peerMACStr[ETH_ALEN * 2] = { 0x00 };
5979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5980 _list *plist, *phead;
5981 _queue *queue = &(pmlmepriv->scanned_queue);
5982 struct wlan_network *pnetwork = NULL;
5983 uint uintPeerChannel = 0;
5984 u8 attr_content[100] = { 0x00 }, _status = 0;
5986 uint p2pielen = 0, attr_contentlen = 0;
5989 /* Commented by Albert 20110301 */
5990 /* The input data contains two informations. */
5991 /* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
5992 /* 2. Second information is the WPS configuration method which wants to discovery */
5993 /* Format: 00:E0:4C:00:00:05_display */
5994 /* Format: 00:E0:4C:00:00:05_keypad */
5995 /* Format: 00:E0:4C:00:00:05_pbc */
5996 /* Format: 00:E0:4C:00:00:05_label */
5998 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
6000 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
6001 RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
6004 #ifdef CONFIG_INTEL_WIDI
6005 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
6006 RTW_INFO("[%s] WiFi is under survey!\n", __FUNCTION__);
6009 #endif /* CONFIG_INTEL_WIDI */
6011 /* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
6012 _rtw_memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
6013 _rtw_memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
6014 _rtw_memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(NDIS_802_11_SSID));
6015 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
6016 pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
6017 pwdinfo->tx_prov_disc_info.benable = _FALSE;
6020 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
6021 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
6023 if (_rtw_memcmp(&extra[18], "display", 7))
6024 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
6025 else if (_rtw_memcmp(&extra[18], "keypad", 7))
6026 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
6027 else if (_rtw_memcmp(&extra[18], "pbc", 3))
6028 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6029 else if (_rtw_memcmp(&extra[18], "label", 5))
6030 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
6032 RTW_INFO("[%s] Unknown WPS config methodn", __FUNCTION__);
6036 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6038 phead = get_list_head(queue);
6039 plist = get_next(phead);
6042 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
6045 if (uintPeerChannel != 0)
6048 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
6050 /* Commented by Albert 2011/05/18 */
6051 /* Match the device address located in the P2P IE */
6052 /* This is for the case that the P2P device address is not the same as the P2P interface address. */
6054 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
6057 /* The P2P Device ID attribute is included in the Beacon frame. */
6058 /* The P2P Device Info attribute is included in the probe response frame. */
6060 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
6061 /* Handle the P2P Device ID attribute of Beacon first */
6062 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
6063 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6066 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
6067 /* Handle the P2P Device Info attribute of probe response */
6068 if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
6069 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6074 /* Get the next P2P IE */
6075 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
6080 #ifdef CONFIG_INTEL_WIDI
6081 /* Some Intel WiDi source may not provide P2P IE, */
6082 /* so we could only compare mac addr by 802.11 Source Address */
6083 if (pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION
6084 && uintPeerChannel == 0) {
6085 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
6086 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6090 #endif /* CONFIG_INTEL_WIDI */
6092 plist = get_next(plist);
6096 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6098 if (uintPeerChannel) {
6100 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
6101 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
6105 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
6110 RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
6111 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
6113 u16 wfd_devinfo_field = 0;
6115 /* Commented by Albert 20120319 */
6116 /* The first two bytes are the WFD device information field of WFD device information subelement. */
6117 /* In big endian format. */
6118 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6119 if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
6120 pwfd_info->peer_session_avail = _TRUE;
6122 pwfd_info->peer_session_avail = _FALSE;
6126 if (_FALSE == pwfd_info->peer_session_avail) {
6127 RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
6131 #endif /* CONFIG_WFD */
6133 RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel);
6134 #ifdef CONFIG_CONCURRENT_MODE
6135 if (rtw_mi_check_status(padapter, MI_LINKED))
6136 _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
6137 #endif /* CONFIG_CONCURRENT_MODE */
6138 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
6139 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
6140 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16) uintPeerChannel;
6141 pwdinfo->tx_prov_disc_info.benable = _TRUE;
6142 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6143 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
6145 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
6146 _rtw_memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));
6147 else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6148 _rtw_memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
6149 pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
6152 #ifdef CONFIG_CONCURRENT_MODE
6153 if (rtw_mi_check_status(padapter, MI_LINKED)) {
6154 u8 union_ch = rtw_mi_get_union_chan(padapter);
6155 u8 union_bw = rtw_mi_get_union_bw(padapter);
6156 u8 union_offset = rtw_mi_get_union_offset(padapter);
6158 /* Have to enter the power saving with the AP */
6159 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
6161 rtw_mi_buddy_issue_nulldata(padapter, NULL, 1, 3, 500);
6163 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6165 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6168 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
6170 #ifdef CONFIG_CONCURRENT_MODE
6171 if (rtw_mi_check_status(padapter, MI_LINKED))
6172 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT);
6174 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
6176 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
6177 #endif /* CONFIG_CONCURRENT_MODE */
6180 RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
6181 #ifdef CONFIG_INTEL_WIDI
6182 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6183 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
6184 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
6185 rtw_free_network_queue(padapter, _TRUE);
6186 _enter_critical_bh(&pmlmepriv->lock, &irqL);
6187 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
6188 _exit_critical_bh(&pmlmepriv->lock, &irqL);
6189 #endif /* CONFIG_INTEL_WIDI */
6197 /* Added by Albert 20110328
6198 * This function is used to inform the driver the user had specified the pin code value or pbc
6199 * to application. */
6201 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
6202 struct iw_request_info *info,
6203 union iwreq_data *wrqu, char *extra)
6207 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6208 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6211 RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
6212 /* Added by Albert 20110328 */
6213 /* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
6214 /* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
6215 /* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
6216 /* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
6219 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6220 else if (*extra == '1')
6221 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
6222 else if (*extra == '2')
6223 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
6224 else if (*extra == '3')
6225 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
6227 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6233 #endif /* CONFIG_P2P */
6235 static int rtw_p2p_set(struct net_device *dev,
6236 struct iw_request_info *info,
6237 union iwreq_data *wrqu, char *extra)
6243 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6244 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6245 struct iw_point *pdata = &wrqu->data;
6246 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6247 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6249 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
6251 if (_rtw_memcmp(extra, "enable=", 7))
6252 rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
6253 else if (_rtw_memcmp(extra, "setDN=", 6)) {
6254 wrqu->data.length -= 6;
6255 rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
6256 } else if (_rtw_memcmp(extra, "profilefound=", 13)) {
6257 wrqu->data.length -= 13;
6258 rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
6259 } else if (_rtw_memcmp(extra, "prov_disc=", 10)) {
6260 wrqu->data.length -= 10;
6261 rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
6262 } else if (_rtw_memcmp(extra, "nego=", 5)) {
6263 wrqu->data.length -= 5;
6264 rtw_p2p_connect(dev, info, wrqu, &extra[5]);
6265 } else if (_rtw_memcmp(extra, "intent=", 7)) {
6266 /* Commented by Albert 2011/03/23 */
6267 /* The wrqu->data.length will include the null character */
6268 /* So, we will decrease 7 + 1 */
6269 wrqu->data.length -= 8;
6270 rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
6271 } else if (_rtw_memcmp(extra, "ssid=", 5)) {
6272 wrqu->data.length -= 5;
6273 rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
6274 } else if (_rtw_memcmp(extra, "got_wpsinfo=", 12)) {
6275 wrqu->data.length -= 12;
6276 rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
6277 } else if (_rtw_memcmp(extra, "listen_ch=", 10)) {
6278 /* Commented by Albert 2011/05/24 */
6279 /* The wrqu->data.length will include the null character */
6280 /* So, we will decrease (10 + 1) */
6281 wrqu->data.length -= 11;
6282 rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
6283 } else if (_rtw_memcmp(extra, "op_ch=", 6)) {
6284 /* Commented by Albert 2011/05/24 */
6285 /* The wrqu->data.length will include the null character */
6286 /* So, we will decrease (6 + 1) */
6287 wrqu->data.length -= 7;
6288 rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
6289 } else if (_rtw_memcmp(extra, "invite=", 7)) {
6290 wrqu->data.length -= 8;
6291 rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
6292 } else if (_rtw_memcmp(extra, "persistent=", 11)) {
6293 wrqu->data.length -= 11;
6294 rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
6295 } else if (_rtw_memcmp(extra, "uuid=", 5)) {
6296 wrqu->data.length -= 5;
6297 ret = rtw_p2p_set_wps_uuid(dev, info, wrqu, &extra[5]);
6301 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
6302 if (_rtw_memcmp(extra, "sa=", 3)) {
6303 /* sa: WFD Session Available information */
6304 wrqu->data.length -= 3;
6305 rtw_p2p_set_sa(dev, info, wrqu, &extra[3]);
6306 } else if (_rtw_memcmp(extra, "pc=", 3)) {
6307 /* pc: WFD Preferred Connection */
6308 wrqu->data.length -= 3;
6309 rtw_p2p_set_pc(dev, info, wrqu, &extra[3]);
6310 } else if (_rtw_memcmp(extra, "wfd_type=", 9)) {
6311 wrqu->data.length -= 9;
6312 rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]);
6313 } else if (_rtw_memcmp(extra, "wfd_enable=", 11)) {
6314 wrqu->data.length -= 11;
6315 rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]);
6316 } else if (_rtw_memcmp(extra, "driver_iface=", 13)) {
6317 wrqu->data.length -= 13;
6318 rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]);
6321 #endif /* CONFIG_WFD */
6323 #endif /* CONFIG_P2P */
6329 static int rtw_p2p_get(struct net_device *dev,
6330 struct iw_request_info *info,
6331 union iwreq_data *wrqu, char *extra)
6338 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6339 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6340 struct iw_point *pdata = &wrqu->data;
6341 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6342 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6344 if (padapter->bShowGetP2PState)
6345 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
6347 if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
6348 rtw_p2p_get_status(dev, info, wrqu, extra);
6349 else if (_rtw_memcmp(wrqu->data.pointer, "role", 4))
6350 rtw_p2p_get_role(dev, info, wrqu, extra);
6351 else if (_rtw_memcmp(wrqu->data.pointer, "peer_ifa", 8))
6352 rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
6353 else if (_rtw_memcmp(wrqu->data.pointer, "req_cm", 6))
6354 rtw_p2p_get_req_cm(dev, info, wrqu, extra);
6355 else if (_rtw_memcmp(wrqu->data.pointer, "peer_deva", 9)) {
6356 /* Get the P2P device address when receiving the provision discovery request frame. */
6357 rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
6358 } else if (_rtw_memcmp(wrqu->data.pointer, "group_id", 8))
6359 rtw_p2p_get_groupid(dev, info, wrqu, extra);
6360 else if (_rtw_memcmp(wrqu->data.pointer, "inv_peer_deva", 13)) {
6361 /* Get the P2P device address when receiving the P2P Invitation request frame. */
6362 rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
6363 } else if (_rtw_memcmp(wrqu->data.pointer, "op_ch", 5))
6364 rtw_p2p_get_op_ch(dev, info, wrqu, extra);
6367 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
6368 if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9))
6369 rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra);
6370 else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6))
6371 rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra);
6372 else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6))
6373 rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra);
6375 #endif /* CONFIG_WFD */
6377 #endif /* CONFIG_P2P */
6383 static int rtw_p2p_get2(struct net_device *dev,
6384 struct iw_request_info *info,
6385 union iwreq_data *wrqu, char *extra)
6392 int length = wrqu->data.length;
6393 char *buffer = (u8 *)rtw_malloc(length);
6395 if (buffer == NULL) {
6400 if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) {
6405 RTW_INFO("[%s] buffer = %s\n", __FUNCTION__, buffer);
6407 if (_rtw_memcmp(buffer, "wpsCM=", 6))
6408 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
6409 else if (_rtw_memcmp(buffer, "devN=", 5))
6410 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
6411 else if (_rtw_memcmp(buffer, "dev_type=", 9))
6412 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
6413 else if (_rtw_memcmp(buffer, "go_devadd=", 10))
6414 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
6415 else if (_rtw_memcmp(buffer, "InvProc=", 8))
6416 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
6418 snprintf(extra, sizeof("Command not found."), "Command not found.");
6419 wrqu->data.length = strlen(extra);
6424 rtw_mfree(buffer, length);
6426 #endif /* CONFIG_P2P */
6432 static int rtw_cta_test_start(struct net_device *dev,
6433 struct iw_request_info *info,
6434 union iwreq_data *wrqu, char *extra)
6437 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6438 RTW_INFO("%s %s\n", __func__, extra);
6439 if (!strcmp(extra, "1"))
6440 padapter->in_cta_test = 1;
6442 padapter->in_cta_test = 0;
6444 if (padapter->in_cta_test) {
6445 u32 v = rtw_read32(padapter, REG_RCR);
6446 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); /* | RCR_ADF */
6447 rtw_write32(padapter, REG_RCR, v);
6448 RTW_INFO("enable RCR_ADF\n");
6450 u32 v = rtw_read32(padapter, REG_RCR);
6451 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;/* | RCR_ADF */
6452 rtw_write32(padapter, REG_RCR, v);
6453 RTW_INFO("disable RCR_ADF\n");
6459 extern int rtw_change_ifname(_adapter *padapter, const char *ifname);
6460 static int rtw_rereg_nd_name(struct net_device *dev,
6461 struct iw_request_info *info,
6462 union iwreq_data *wrqu, char *extra)
6465 _adapter *padapter = rtw_netdev_priv(dev);
6466 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
6467 char new_ifname[IFNAMSIZ];
6469 if (rereg_priv->old_ifname[0] == 0) {
6471 #ifdef CONFIG_CONCURRENT_MODE
6472 if (padapter->isprimary)
6473 reg_ifname = padapter->registrypriv.ifname;
6476 reg_ifname = padapter->registrypriv.if2name;
6478 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
6479 rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
6482 /* RTW_INFO("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); */
6483 if (wrqu->data.length > IFNAMSIZ)
6486 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
6489 if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
6492 RTW_INFO("%s new_ifname:%s\n", __FUNCTION__, new_ifname);
6493 ret = rtw_change_ifname(padapter, new_ifname);
6497 if (_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {
6498 padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
6499 rtw_hal_sw_led_init(padapter);
6500 /* rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); */
6503 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
6504 rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
6506 if (_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {
6508 RTW_INFO("%s disable\n", __FUNCTION__);
6509 /* free network queue for Android's timming issue */
6510 rtw_free_network_queue(padapter, _TRUE);
6513 rtw_led_control(padapter, LED_CTL_POWER_OFF);
6514 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
6515 padapter->ledpriv.bRegUseLed = _FALSE;
6516 rtw_hal_sw_led_deinit(padapter);
6518 /* the interface is being "disabled", we can do deeper IPS */
6519 /* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */
6520 /* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */
6528 #include <rtw_iol.h>
6531 #ifdef DBG_CMD_QUEUE
6534 static int rtw_dbg_port(struct net_device *dev,
6535 struct iw_request_info *info,
6536 union iwreq_data *wrqu, char *extra)
6540 u8 major_cmd, minor_cmd;
6542 u32 extra_arg, *pdata, val32;
6543 struct sta_info *psta;
6544 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6545 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6546 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6547 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6548 struct security_priv *psecuritypriv = &padapter->securitypriv;
6549 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
6550 struct sta_priv *pstapriv = &padapter->stapriv;
6553 pdata = (u32 *)&wrqu->data;
6556 arg = (u16)(val32 & 0x0000ffff);
6557 major_cmd = (u8)(val32 >> 24);
6558 minor_cmd = (u8)((val32 >> 16) & 0x00ff);
6560 extra_arg = *(pdata + 1);
6562 switch (major_cmd) {
6563 case 0x70: /* read_reg */
6564 switch (minor_cmd) {
6566 RTW_INFO("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6569 RTW_INFO("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6572 RTW_INFO("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6576 case 0x71: /* write_reg */
6577 switch (minor_cmd) {
6579 rtw_write8(padapter, arg, extra_arg);
6580 RTW_INFO("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
6583 rtw_write16(padapter, arg, extra_arg);
6584 RTW_INFO("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
6587 rtw_write32(padapter, arg, extra_arg);
6588 RTW_INFO("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
6592 case 0x72: /* read_bb */
6593 RTW_INFO("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6595 case 0x73: /* write_bb */
6596 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
6597 RTW_INFO("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
6599 case 0x74: /* read_rf */
6600 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));
6602 case 0x75: /* write_rf */
6603 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
6604 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));
6608 switch (minor_cmd) {
6609 case 0x00: /* normal mode, */
6610 padapter->recvpriv.is_signal_dbg = 0;
6612 case 0x01: /* dbg mode */
6613 padapter->recvpriv.is_signal_dbg = 1;
6614 extra_arg = extra_arg > 100 ? 100 : extra_arg;
6615 padapter->recvpriv.signal_strength_dbg = extra_arg;
6619 case 0x78: /* IOL test */
6620 switch (minor_cmd) {
6622 case 0x04: { /* LLT table initialization test */
6623 u8 page_boundary = 0xf9;
6625 struct xmit_frame *xmit_frame;
6627 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6628 if (xmit_frame == NULL) {
6633 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
6636 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))
6641 case 0x05: { /* blink LED test */
6644 u32 blink_delay_ms = 200;
6648 struct xmit_frame *xmit_frame;
6650 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6651 if (xmit_frame == NULL) {
6656 for (i = 0; i < blink_num; i++) {
6657 #ifdef CONFIG_IOL_NEW_GENERATION
6658 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
6659 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6660 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
6661 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6663 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
6664 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6665 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
6666 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
6669 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0))
6675 case 0x06: { /* continuous wirte byte test */
6677 u16 start_value = 0;
6678 u32 write_num = extra_arg;
6683 struct xmit_frame *xmit_frame;
6685 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6686 if (xmit_frame == NULL) {
6691 for (i = 0; i < write_num; i++) {
6692 #ifdef CONFIG_IOL_NEW_GENERATION
6693 rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
6695 rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value);
6698 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6702 final = rtw_read8(padapter, reg);
6703 if (start_value + write_num - 1 == final)
6704 RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6706 RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6710 case 0x07: { /* continuous wirte word test */
6712 u16 start_value = 200;
6713 u32 write_num = extra_arg;
6719 struct xmit_frame *xmit_frame;
6721 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6722 if (xmit_frame == NULL) {
6727 for (i = 0; i < write_num; i++) {
6728 #ifdef CONFIG_IOL_NEW_GENERATION
6729 rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
6731 rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value);
6734 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6738 final = rtw_read16(padapter, reg);
6739 if (start_value + write_num - 1 == final)
6740 RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6742 RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6746 case 0x08: { /* continuous wirte dword test */
6748 u32 start_value = 0x110000c7;
6749 u32 write_num = extra_arg;
6755 struct xmit_frame *xmit_frame;
6757 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6758 if (xmit_frame == NULL) {
6763 for (i = 0; i < write_num; i++) {
6764 #ifdef CONFIG_IOL_NEW_GENERATION
6765 rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
6767 rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value);
6770 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6775 final = rtw_read32(padapter, reg);
6776 if (start_value + write_num - 1 == final)
6777 RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6779 RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6782 #endif /* CONFIG_IOL */
6787 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
6788 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
6790 u8 value = extra_arg & 0x0f;
6791 u8 sign = minor_cmd;
6792 u16 write_value = 0;
6794 RTW_INFO("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
6797 value = value | 0x10;
6799 write_value = value | (value << 5);
6800 rtw_write16(padapter, 0x6d9, write_value);
6804 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
6805 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
6808 switch (minor_cmd) {
6810 RTW_INFO("fwstate=0x%x\n", get_fwstate(pmlmepriv));
6813 RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
6814 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
6815 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
6818 RTW_INFO("pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
6819 RTW_INFO("DrvBcnEarly=%d\n", pmlmeext->DrvBcnEarly);
6820 RTW_INFO("DrvBcnTimeOut=%d\n", pmlmeext->DrvBcnTimeOut);
6823 RTW_INFO("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
6824 #ifdef CONFIG_80211N_HT
6825 RTW_INFO("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
6826 #endif /* CONFIG_80211N_HT */
6829 RTW_INFO("cur_ch=%d\n", pmlmeext->cur_channel);
6830 RTW_INFO("cur_bw=%d\n", pmlmeext->cur_bwmode);
6831 RTW_INFO("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
6833 RTW_INFO("oper_ch=%d\n", rtw_get_oper_ch(padapter));
6834 RTW_INFO("oper_bw=%d\n", rtw_get_oper_bw(padapter));
6835 RTW_INFO("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
6839 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
6841 RTW_INFO("SSID=%s\n", cur_network->network.Ssid.Ssid);
6842 RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
6843 RTW_INFO("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
6844 RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6845 RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
6846 #ifdef CONFIG_80211N_HT
6847 RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6848 RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
6849 RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6850 RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6851 #endif /* CONFIG_80211N_HT */
6853 sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6855 RTW_INFO("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
6861 RTW_INFO("bSurpriseRemoved=%s, bDriverStopped=%s\n"
6862 , rtw_is_surprise_removed(padapter) ? "True" : "False"
6863 , rtw_is_drv_stopped(padapter) ? "True" : "False");
6866 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6867 struct recv_priv *precvpriv = &padapter->recvpriv;
6869 RTW_INFO("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
6870 ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
6871 ", free_recvframe_cnt=%d\n",
6872 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
6873 pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
6874 precvpriv->free_recvframe_cnt);
6875 #ifdef CONFIG_USB_HCI
6876 RTW_INFO("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt)));
6882 _list *plist, *phead;
6884 #ifdef CONFIG_AP_MODE
6885 RTW_INFO("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
6887 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6889 for (i = 0; i < NUM_STA; i++) {
6890 phead = &(pstapriv->sta_hash[i]);
6891 plist = get_next(phead);
6893 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
6894 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
6896 plist = get_next(plist);
6898 if (extra_arg == psta->aid) {
6899 RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
6900 RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6901 RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
6902 #ifdef CONFIG_80211N_HT
6903 RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6904 RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m,
6905 psta->htpriv.sgi_40m);
6906 RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6907 RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6908 #endif /* CONFIG_80211N_HT */
6910 #ifdef CONFIG_AP_MODE
6911 RTW_INFO("capability=0x%x\n", psta->capability);
6912 RTW_INFO("flags=0x%x\n", psta->flags);
6913 RTW_INFO("wpa_psk=0x%x\n", psta->wpa_psk);
6914 RTW_INFO("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
6915 RTW_INFO("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
6916 RTW_INFO("qos_info=0x%x\n", psta->qos_info);
6918 RTW_INFO("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
6920 sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6926 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6931 case 0x0b: { /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6932 /* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6933 /* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
6936 RTW_INFO("disable driver ctrl vcs\n");
6937 padapter->driver_vcs_en = 0;
6938 } else if (arg == 1) {
6939 RTW_INFO("enable driver ctrl vcs = %d\n", extra_arg);
6940 padapter->driver_vcs_en = 1;
6943 padapter->driver_vcs_type = 1;
6945 padapter->driver_vcs_type = extra_arg;
6949 case 0x0c: { /* dump rx/tx packet */
6951 RTW_INFO("dump rx packet (%d)\n", extra_arg);
6952 /* pHalData->bDumpRxPkt =extra_arg; */
6953 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
6954 } else if (arg == 1) {
6955 RTW_INFO("dump tx packet (%d)\n", extra_arg);
6956 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
6962 RTW_INFO("disable driver ctrl rx_ampdu_factor\n");
6963 padapter->driver_rx_ampdu_factor = 0xFF;
6964 } else if (arg == 1) {
6966 RTW_INFO("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
6968 if (extra_arg > 0x03)
6969 padapter->driver_rx_ampdu_factor = 0xFF;
6971 padapter->driver_rx_ampdu_factor = extra_arg;
6975 #ifdef DBG_CONFIG_ERROR_DETECT
6977 if (extra_arg == 0) {
6978 RTW_INFO("###### silent reset test.......#####\n");
6979 rtw_hal_sreset_reset(padapter);
6981 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
6982 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
6983 psrtpriv->dbg_trigger_point = extra_arg;
6989 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6990 RTW_INFO("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
6996 case 0x10: /* driver version display */
6997 dump_drv_version(RTW_DBGDUMP);
6999 case 0x11: { /* dump linked status */
7001 pre_mode = padapter->bLinkInfoDump;
7002 /* linked_info_dump(padapter,extra_arg); */
7003 if (extra_arg == 1 || (extra_arg == 0 && pre_mode == 1)) /* not consider pwr_saving 0: */
7004 padapter->bLinkInfoDump = extra_arg;
7006 else if ((extra_arg == 2) || (extra_arg == 0 && pre_mode == 2)) { /* consider power_saving */
7007 /* RTW_INFO("linked_info_dump =%s\n", (padapter->bLinkInfoDump)?"enable":"disable") */
7008 linked_info_dump(padapter, extra_arg);
7015 #ifdef CONFIG_80211N_HT
7016 case 0x12: { /* set rx_stbc */
7017 struct registry_priv *pregpriv = &padapter->registrypriv;
7018 /* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
7019 /* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
7020 if (pregpriv && (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3)) {
7021 pregpriv->rx_stbc = extra_arg;
7022 RTW_INFO("set rx_stbc=%d\n", pregpriv->rx_stbc);
7024 RTW_INFO("get rx_stbc=%d\n", pregpriv->rx_stbc);
7028 case 0x13: { /* set ampdu_enable */
7029 struct registry_priv *pregpriv = &padapter->registrypriv;
7030 /* 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */
7031 if (pregpriv && extra_arg < 3) {
7032 pregpriv->ampdu_enable = extra_arg;
7033 RTW_INFO("set ampdu_enable=%d\n", pregpriv->ampdu_enable);
7035 RTW_INFO("get ampdu_enable=%d\n", pregpriv->ampdu_enable);
7040 case 0x14: { /* get wifi_spec */
7041 struct registry_priv *pregpriv = &padapter->registrypriv;
7042 RTW_INFO("get wifi_spec=%d\n", pregpriv->wifi_spec);
7048 rtw_odm_dbg_comp_msg(RTW_DBGDUMP, padapter);
7050 u64 dbg_comp = (u64)extra_arg;
7051 rtw_odm_dbg_comp_set(padapter, dbg_comp);
7055 #ifdef DBG_FIXED_CHAN
7057 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7058 printk("===> Fixed channel to %d\n", extra_arg);
7059 pmlmeext->fixed_chan = extra_arg;
7064 #ifdef CONFIG_80211N_HT
7066 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7068 /* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */
7069 /* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */
7071 RTW_INFO("driver disable LDPC\n");
7072 pregistrypriv->ldpc_cap = 0x00;
7073 } else if (arg == 1) {
7074 RTW_INFO("driver set LDPC cap = 0x%x\n", extra_arg);
7075 pregistrypriv->ldpc_cap = (u8)(extra_arg & 0x33);
7080 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7082 /* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */
7083 /* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */
7085 RTW_INFO("driver disable STBC\n");
7086 pregistrypriv->stbc_cap = 0x00;
7087 } else if (arg == 1) {
7088 RTW_INFO("driver set STBC cap = 0x%x\n", extra_arg);
7089 pregistrypriv->stbc_cap = (u8)(extra_arg & 0x33);
7093 #endif /* CONFIG_80211N_HT */
7095 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7098 RTW_INFO("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
7099 init_mlme_default_rate_set(padapter);
7100 #ifdef CONFIG_80211N_HT
7101 pregistrypriv->ht_enable = (u8)rtw_ht_enable;
7102 #endif /* CONFIG_80211N_HT */
7103 } else if (arg == 1) {
7108 RTW_INFO("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
7110 max_rx_rate = (u8)extra_arg;
7112 if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0->B or G -> disable HT */
7113 #ifdef CONFIG_80211N_HT
7114 pregistrypriv->ht_enable = 0;
7115 #endif /* CONFIG_80211N_HT */
7116 for (i = 0; i < NumRates; i++) {
7117 if (pmlmeext->datarate[i] > max_rx_rate)
7118 pmlmeext->datarate[i] = 0xff;
7122 #ifdef CONFIG_80211N_HT
7123 else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */
7124 u32 mcs_bitmap = 0x0;
7126 for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++)
7127 mcs_bitmap |= BIT(i);
7129 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
7131 #endif /* CONFIG_80211N_HT */
7135 case 0x1c: { /* enable/disable driver control AMPDU Density for peer sta's rx */
7137 RTW_INFO("disable driver ctrl ampdu density\n");
7138 padapter->driver_ampdu_spacing = 0xFF;
7139 } else if (arg == 1) {
7141 RTW_INFO("enable driver ctrl ampdu density = %d\n", extra_arg);
7143 if (extra_arg > 0x07)
7144 padapter->driver_ampdu_spacing = 0xFF;
7146 padapter->driver_ampdu_spacing = extra_arg;
7150 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
7152 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7153 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
7154 u8 chan = rtw_get_oper_ch(padapter);
7155 RTW_INFO("===========================================\n");
7156 ODM_InbandNoise_Monitor(pDM_Odm, _TRUE, 0x1e, 100);
7157 RTW_INFO("channel(%d),noise_a = %d, noise_b = %d , noise_all:%d\n",
7158 chan, pDM_Odm->noise_level.noise[ODM_RF_PATH_A],
7159 pDM_Odm->noise_level.noise[ODM_RF_PATH_B],
7160 pDM_Odm->noise_level.noise_all);
7161 RTW_INFO("===========================================\n");
7167 RTW_INFO("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
7168 padapter->bNotifyChannelChange = extra_arg;
7173 RTW_INFO("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
7174 padapter->bShowGetP2PState = extra_arg;
7175 #endif /* CONFIG_P2P */
7178 #ifdef CONFIG_GPIO_API
7179 case 0x25: { /* Get GPIO register */
7181 * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
7185 RTW_INFO("Read GPIO Value extra_arg = %d\n", extra_arg);
7186 value = rtw_hal_get_gpio(padapter, extra_arg);
7187 RTW_INFO("Read GPIO Value = %d\n", value);
7190 case 0x26: { /* Set GPIO direction */
7192 /* dbg 0x7f26000x [y], Set gpio direction,
7193 * x: gpio_num,4~7 y: indicate direction, 0~1
7197 RTW_INFO("Set GPIO Direction! arg = %d ,extra_arg=%d\n", arg , extra_arg);
7198 value = rtw_hal_config_gpio(padapter, arg, extra_arg);
7199 RTW_INFO("Set GPIO Direction %s\n", (value == -1) ? "Fail!!!" : "Success");
7202 case 0x27: { /* Set GPIO output direction value */
7204 * dbg 0x7f27000x [y], Set gpio output direction value,
7205 * x: gpio_num,4~7 y: indicate direction, 0~1
7209 RTW_INFO("Set GPIO Value! arg = %d ,extra_arg=%d\n", arg , extra_arg);
7210 value = rtw_hal_set_gpio_output_value(padapter, arg, extra_arg);
7211 RTW_INFO("Set GPIO Value %s\n", (value == -1) ? "Fail!!!" : "Success");
7215 #ifdef DBG_CMD_QUEUE
7217 dump_cmd_id = extra_arg;
7218 RTW_INFO("dump_cmd_id:%d\n", dump_cmd_id);
7221 #endif /* DBG_CMD_QUEUE */
7223 if ((extra_arg & 0x7F) > 0x3F)
7225 RTW_INFO("chang data rate to :0x%02x\n", extra_arg);
7226 padapter->fix_rate = extra_arg;
7229 case 0xdd: { /* registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg */
7231 mac_reg_dump(RTW_DBGDUMP, padapter);
7232 else if (extra_arg == 1)
7233 bb_reg_dump(RTW_DBGDUMP, padapter);
7234 else if (extra_arg == 2)
7235 rf_reg_dump(RTW_DBGDUMP, padapter);
7240 RTW_INFO(" === please control /proc to trun on/off PHYDM func ===\n");
7245 rtw_write8(padapter, 0xc50, arg);
7246 RTW_INFO("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7247 rtw_write8(padapter, 0xc58, arg);
7248 RTW_INFO("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7251 RTW_INFO("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7252 RTW_INFO("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7255 RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
7256 RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
7257 RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
7258 RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
7259 RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
7261 RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
7266 RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
7267 RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
7269 RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
7271 RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
7273 RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
7274 RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
7276 RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
7277 RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
7278 RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
7279 RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
7285 RTW_INFO("error dbg cmd!\n");
7294 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
7298 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7301 case IEEE_PARAM_WPA_ENABLED:
7303 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
7305 /* ret = ieee80211_wpa_enable(ieee, value); */
7307 switch ((value) & 0xff) {
7309 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
7310 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
7313 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
7314 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
7318 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype));
7322 case IEEE_PARAM_TKIP_COUNTERMEASURES:
7323 /* ieee->tkip_countermeasures=value; */
7326 case IEEE_PARAM_DROP_UNENCRYPTED: {
7329 * wpa_supplicant calls set_wpa_enabled when the driver
7330 * is loaded and unloaded, regardless of if WPA is being
7331 * used. No other calls are made which can be used to
7332 * determine if encryption will be used or not prior to
7333 * association being expected. If encryption is not being
7334 * used, drop_unencrypted is set to false, else true -- we
7335 * can use this to determine if the CAP_PRIVACY_ON bit should
7340 struct ieee80211_security sec = {
7341 .flags = SEC_ENABLED,
7344 ieee->drop_unencrypted = value;
7345 /* We only change SEC_LEVEL for open mode. Others
7346 * are set by ipw_wpa_set_encryption.
7349 sec.flags |= SEC_LEVEL;
7350 sec.level = SEC_LEVEL_0;
7352 sec.flags |= SEC_LEVEL;
7353 sec.level = SEC_LEVEL_1;
7355 if (ieee->set_security)
7356 ieee->set_security(ieee->dev, &sec);
7361 case IEEE_PARAM_PRIVACY_INVOKED:
7363 /* ieee->privacy_invoked=value; */
7367 case IEEE_PARAM_AUTH_ALGS:
7369 ret = wpa_set_auth_algs(dev, value);
7373 case IEEE_PARAM_IEEE_802_1X:
7375 /* ieee->ieee802_1x=value; */
7379 case IEEE_PARAM_WPAX_SELECT:
7381 /* added for WPA2 mixed mode */
7382 /*RTW_WARN("------------------------>wpax value = %x\n", value);*/
7384 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
7385 ieee->wpax_type_set = 1;
7386 ieee->wpax_type_notify = value;
7387 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
7407 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
7410 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7413 case IEEE_MLME_STA_DEAUTH:
7415 if (!rtw_set_802_11_disassociate(padapter))
7420 case IEEE_MLME_STA_DISASSOC:
7422 if (!rtw_set_802_11_disassociate(padapter))
7436 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
7438 struct ieee_param *param;
7441 /* down(&ieee->wx_sem); */
7443 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
7448 param = (struct ieee_param *)rtw_malloc(p->length);
7449 if (param == NULL) {
7454 if (copy_from_user(param, p->pointer, p->length)) {
7455 rtw_mfree((u8 *)param, p->length);
7460 switch (param->cmd) {
7462 case IEEE_CMD_SET_WPA_PARAM:
7463 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
7466 case IEEE_CMD_SET_WPA_IE:
7467 /* ret = wpa_set_wpa_ie(dev, param, p->length); */
7468 ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
7471 case IEEE_CMD_SET_ENCRYPTION:
7472 ret = wpa_set_encryption(dev, param, p->length);
7476 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
7480 RTW_INFO("Unknown WPA supplicant request: %d\n", param->cmd);
7486 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7489 rtw_mfree((u8 *)param, p->length);
7493 /* up(&ieee->wx_sem); */
7499 #ifdef CONFIG_AP_MODE
7500 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
7503 u32 wep_key_idx, wep_key_len, wep_total_len;
7504 NDIS_802_11_WEP *pwep = NULL;
7505 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
7506 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7507 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7508 struct security_priv *psecuritypriv = &(padapter->securitypriv);
7509 struct sta_priv *pstapriv = &padapter->stapriv;
7511 RTW_INFO("%s\n", __FUNCTION__);
7513 param->u.crypt.err = 0;
7514 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
7516 /* sizeof(struct ieee_param) = 64 bytes; */
7517 /* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
7518 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
7523 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7524 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7525 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
7526 if (param->u.crypt.idx >= WEP_KEYS
7527 #ifdef CONFIG_IEEE80211W
7528 && param->u.crypt.idx > BIP_MAX_KEYID
7529 #endif /* CONFIG_IEEE80211W */
7535 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7537 /* ret = -EINVAL; */
7538 RTW_INFO("rtw_set_encryption(), sta has already been removed or never been added\n");
7543 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
7544 /* todo:clear default encryption keys */
7546 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
7547 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
7548 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
7549 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7551 RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
7557 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
7558 RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
7560 wep_key_idx = param->u.crypt.idx;
7561 wep_key_len = param->u.crypt.key_len;
7563 RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
7565 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
7571 if (wep_key_len > 0) {
7572 wep_key_len = wep_key_len <= 5 ? 5 : 13;
7573 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
7574 pwep = (NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
7576 RTW_INFO(" r871x_set_encryption: pwep allocate fail !!!\n");
7580 _rtw_memset(pwep, 0, wep_total_len);
7582 pwep->KeyLength = wep_key_len;
7583 pwep->Length = wep_total_len;
7587 pwep->KeyIndex = wep_key_idx;
7589 _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
7591 if (param->u.crypt.set_tx) {
7592 RTW_INFO("wep, set_tx=1\n");
7594 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
7595 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
7596 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
7597 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7599 if (pwep->KeyLength == 13) {
7600 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
7601 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7605 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
7607 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7609 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
7611 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
7613 RTW_INFO("wep, set_tx=0\n");
7615 /* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
7616 /* "psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam */
7618 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
7620 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
7622 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
7630 if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* */ { /* group key */
7631 if (param->u.crypt.set_tx == 1) {
7632 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
7633 RTW_INFO("%s, set group_key, WEP\n", __FUNCTION__);
7635 _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));
7637 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7638 if (param->u.crypt.key_len == 13)
7639 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7641 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7642 RTW_INFO("%s, set group_key, TKIP\n", __FUNCTION__);
7644 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7646 _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));
7648 /* DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); */
7650 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7651 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7653 psecuritypriv->busetkipkey = _TRUE;
7655 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7656 RTW_INFO("%s, set group_key, CCMP\n", __FUNCTION__);
7658 psecuritypriv->dot118021XGrpPrivacy = _AES_;
7660 _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));
7662 #ifdef CONFIG_IEEE80211W
7663 else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
7666 RTW_INFO("BIP key_len=%d , index=%d\n", param->u.crypt.key_len, param->u.crypt.idx);
7667 /* save the IGTK key, length 16 bytes */
7668 _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));
7669 /* RTW_INFO("IGTK key below:\n");
7670 for(no=0;no<16;no++)
7671 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
7673 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
7674 padapter->securitypriv.binstallBIPkey = _TRUE;
7675 RTW_INFO(" ~~~~set sta key:IGKT\n");
7678 #endif /* CONFIG_IEEE80211W */
7680 RTW_INFO("%s, set group_key, none\n", __FUNCTION__);
7682 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7685 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7687 psecuritypriv->binstallGrpkey = _TRUE;
7689 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
7691 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7693 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7695 pbcmc_sta->ieee8021x_blocked = _FALSE;
7696 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy */
7705 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
7706 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
7707 if (param->u.crypt.set_tx == 1) {
7708 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
7710 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
7711 RTW_INFO("%s, set pairwise key, WEP\n", __FUNCTION__);
7713 psta->dot118021XPrivacy = _WEP40_;
7714 if (param->u.crypt.key_len == 13)
7715 psta->dot118021XPrivacy = _WEP104_;
7716 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7717 RTW_INFO("%s, set pairwise key, TKIP\n", __FUNCTION__);
7719 psta->dot118021XPrivacy = _TKIP_;
7721 /* DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); */
7723 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7724 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7726 psecuritypriv->busetkipkey = _TRUE;
7728 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7730 RTW_INFO("%s, set pairwise key, CCMP\n", __FUNCTION__);
7732 psta->dot118021XPrivacy = _AES_;
7734 RTW_INFO("%s, set pairwise key, none\n", __FUNCTION__);
7736 psta->dot118021XPrivacy = _NO_PRIVACY_;
7739 rtw_ap_set_pairwise_key(padapter, psta);
7741 psta->ieee8021x_blocked = _FALSE;
7743 psta->bpairwise_key_installed = _TRUE;
7745 } else { /* group key??? */
7746 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
7747 _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));
7749 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
7750 if (param->u.crypt.key_len == 13)
7751 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7752 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7753 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7755 _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));
7757 /* DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); */
7759 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7760 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7762 psecuritypriv->busetkipkey = _TRUE;
7764 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7765 psecuritypriv->dot118021XGrpPrivacy = _AES_;
7767 _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));
7769 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7771 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7773 psecuritypriv->binstallGrpkey = _TRUE;
7775 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
7777 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7779 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7781 pbcmc_sta->ieee8021x_blocked = _FALSE;
7782 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy */
7794 rtw_mfree((u8 *)pwep, wep_total_len);
7800 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
7803 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7804 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7805 struct sta_priv *pstapriv = &padapter->stapriv;
7806 unsigned char *pbuf = param->u.bcn_ie.buf;
7809 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7811 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7814 _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
7816 if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
7817 pstapriv->max_num_sta = NUM_STA;
7820 if (rtw_check_beacon_data(padapter, pbuf, (len - 12 - 2)) == _SUCCESS) /* 12 = param header, 2:no packed */
7830 static int rtw_hostapd_sta_flush(struct net_device *dev)
7833 /* _list *phead, *plist; */
7835 /* struct sta_info *psta = NULL; */
7836 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7837 /* struct sta_priv *pstapriv = &padapter->stapriv; */
7839 RTW_INFO("%s\n", __FUNCTION__);
7841 flush_all_cam_entry(padapter); /* clear CAM */
7843 ret = rtw_sta_flush(padapter, _TRUE);
7849 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
7853 struct sta_info *psta = NULL;
7854 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7855 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7856 struct sta_priv *pstapriv = &padapter->stapriv;
7858 RTW_INFO("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
7860 if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7863 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7864 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7865 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7869 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7871 RTW_INFO("rtw_add_sta(), free has been added psta=%p\n", psta);
7872 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7873 rtw_free_stainfo(padapter, psta);
7874 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7879 /* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
7880 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7882 int flags = param->u.add_sta.flags;
7884 /* RTW_INFO("rtw_add_sta(), init sta's variables, psta=%p\n", psta); */
7886 psta->aid = param->u.add_sta.aid;/* aid=1~2007 */
7888 _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
7891 /* check wmm cap. */
7892 if (WLAN_STA_WME & flags)
7893 psta->qos_option = 1;
7895 psta->qos_option = 0;
7897 if (pmlmepriv->qospriv.qos_option == 0)
7898 psta->qos_option = 0;
7901 #ifdef CONFIG_80211N_HT
7902 /* chec 802.11n ht cap. */
7903 if (WLAN_STA_HT & flags) {
7904 psta->htpriv.ht_option = _TRUE;
7905 psta->qos_option = 1;
7906 _rtw_memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7908 psta->htpriv.ht_option = _FALSE;
7910 if (pmlmepriv->htpriv.ht_option == _FALSE)
7911 psta->htpriv.ht_option = _FALSE;
7915 update_sta_info_apmode(padapter, psta);
7925 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
7929 struct sta_info *psta = NULL;
7930 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7931 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7932 struct sta_priv *pstapriv = &padapter->stapriv;
7934 RTW_INFO("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
7936 if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7939 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7940 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7941 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7944 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7946 u8 updated = _FALSE;
7948 /* RTW_INFO("free psta=%p, aid=%d\n", psta, psta->aid); */
7950 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7951 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
7952 rtw_list_delete(&psta->asoc_list);
7953 pstapriv->asoc_list_cnt--;
7954 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
7957 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7959 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
7964 RTW_INFO("rtw_del_sta(), sta has already been removed or never been added\n");
7974 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
7977 struct sta_info *psta = NULL;
7978 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7979 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7980 struct sta_priv *pstapriv = &padapter->stapriv;
7981 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
7982 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
7984 RTW_INFO("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
7986 if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7989 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
7990 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
7991 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
7994 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
8002 u8 tx_supp_rates[16];
8003 u32 tx_supp_rates_len;
8004 struct rtw_ieee80211_ht_cap ht_cap;
8013 psta_data->aid = (u16)psta->aid;
8014 psta_data->capability = psta->capability;
8015 psta_data->flags = psta->flags;
8019 no_short_slot_time_set : BIT(1)
8020 no_short_preamble_set : BIT(2)
8021 no_ht_gf_set : BIT(3)
8023 ht_20mhz_set : BIT(5)
8026 psta_data->sta_set = ((psta->nonerp_set) |
8027 (psta->no_short_slot_time_set << 1) |
8028 (psta->no_short_preamble_set << 2) |
8029 (psta->no_ht_gf_set << 3) |
8030 (psta->no_ht_set << 4) |
8031 (psta->ht_20mhz_set << 5));
8033 psta_data->tx_supp_rates_len = psta->bssratelen;
8034 _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
8035 #ifdef CONFIG_80211N_HT
8036 _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8037 #endif /* CONFIG_80211N_HT */
8038 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
8039 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
8040 psta_data->rx_drops = psta->sta_stats.rx_drops;
8042 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
8043 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
8044 psta_data->tx_drops = psta->sta_stats.tx_drops;
8054 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
8057 struct sta_info *psta = NULL;
8058 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8059 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8060 struct sta_priv *pstapriv = &padapter->stapriv;
8062 RTW_INFO("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
8064 if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
8067 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8068 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8069 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8072 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8074 if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
8078 wpa_ie_len = psta->wpa_ie[1];
8080 copy_len = ((wpa_ie_len + 2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len + 2);
8082 param->u.wpa_ie.len = copy_len;
8084 _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
8087 RTW_INFO("sta's wpa_ie is NONE\n");
8096 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
8099 unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
8100 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8101 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8102 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8103 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8106 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
8108 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8111 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
8114 if (pmlmepriv->wps_beacon_ie) {
8115 rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8116 pmlmepriv->wps_beacon_ie = NULL;
8120 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
8121 pmlmepriv->wps_beacon_ie_len = ie_len;
8122 if (pmlmepriv->wps_beacon_ie == NULL) {
8123 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8127 _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
8129 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
8131 pmlmeext->bstart_bss = _TRUE;
8140 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
8143 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8144 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8147 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
8149 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8152 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
8155 if (pmlmepriv->wps_probe_resp_ie) {
8156 rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
8157 pmlmepriv->wps_probe_resp_ie = NULL;
8161 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
8162 pmlmepriv->wps_probe_resp_ie_len = ie_len;
8163 if (pmlmepriv->wps_probe_resp_ie == NULL) {
8164 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8167 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
8175 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
8178 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8179 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8182 RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
8184 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8187 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
8190 if (pmlmepriv->wps_assoc_resp_ie) {
8191 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8192 pmlmepriv->wps_assoc_resp_ie = NULL;
8196 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
8197 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
8198 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
8199 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8203 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
8211 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
8214 _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8215 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
8216 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
8217 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
8220 char ssid[NDIS_802_11_LENGTH_SSID + 1];
8222 u8 ignore_broadcast_ssid;
8224 if (check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
8227 if (param->u.bcn_ie.reserved[0] != 0xea)
8230 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
8232 ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
8233 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
8235 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
8236 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
8237 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
8239 _rtw_memcpy(ssid, ssid_ie + 2, ssid_len);
8240 ssid[ssid_len] = 0x0;
8243 RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8245 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8246 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8248 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
8249 pbss_network->Ssid.SsidLength = ssid_len;
8250 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
8251 pbss_network_ext->Ssid.SsidLength = ssid_len;
8254 RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
8255 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
8256 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
8259 RTW_INFO(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
8260 ignore_broadcast_ssid, ssid, ssid_len);
8265 #if CONFIG_RTW_MACADDR_ACL
8266 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
8269 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8270 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8272 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8275 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8276 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8277 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8280 ret = rtw_acl_remove_sta(padapter, param->sta_addr);
8286 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
8289 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8290 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8292 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8295 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8296 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8297 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8300 ret = rtw_acl_add_sta(padapter, param->sta_addr);
8306 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
8309 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8310 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8312 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8315 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
8319 #endif /* CONFIG_RTW_MACADDR_ACL */
8321 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
8323 struct ieee_param *param;
8325 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8327 /* RTW_INFO("%s\n", __FUNCTION__); */
8330 * this function is expect to call in master mode, which allows no power saving
8331 * so, we just check hw_init_completed
8334 if (!rtw_is_hw_init_completed(padapter)) {
8340 /* if (p->length < sizeof(struct ieee_param) || !p->pointer){ */
8346 param = (struct ieee_param *)rtw_malloc(p->length);
8347 if (param == NULL) {
8352 if (copy_from_user(param, p->pointer, p->length)) {
8353 rtw_mfree((u8 *)param, p->length);
8358 /* RTW_INFO("%s, cmd=%d\n", __FUNCTION__, param->cmd); */
8360 switch (param->cmd) {
8361 case RTL871X_HOSTAPD_FLUSH:
8363 ret = rtw_hostapd_sta_flush(dev);
8367 case RTL871X_HOSTAPD_ADD_STA:
8369 ret = rtw_add_sta(dev, param);
8373 case RTL871X_HOSTAPD_REMOVE_STA:
8375 ret = rtw_del_sta(dev, param);
8379 case RTL871X_HOSTAPD_SET_BEACON:
8381 ret = rtw_set_beacon(dev, param, p->length);
8385 case RTL871X_SET_ENCRYPTION:
8387 ret = rtw_set_encryption(dev, param, p->length);
8391 case RTL871X_HOSTAPD_GET_WPAIE_STA:
8393 ret = rtw_get_sta_wpaie(dev, param);
8397 case RTL871X_HOSTAPD_SET_WPS_BEACON:
8399 ret = rtw_set_wps_beacon(dev, param, p->length);
8403 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
8405 ret = rtw_set_wps_probe_resp(dev, param, p->length);
8409 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
8411 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
8415 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
8417 ret = rtw_set_hidden_ssid(dev, param, p->length);
8421 case RTL871X_HOSTAPD_GET_INFO_STA:
8423 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
8427 #if CONFIG_RTW_MACADDR_ACL
8428 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
8429 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
8431 case RTL871X_HOSTAPD_ACL_ADD_STA:
8432 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
8434 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
8435 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
8437 #endif /* CONFIG_RTW_MACADDR_ACL */
8440 RTW_INFO("Unknown hostapd request: %d\n", param->cmd);
8446 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
8450 rtw_mfree((u8 *)param, p->length);
8459 static int rtw_wx_set_priv(struct net_device *dev,
8460 struct iw_request_info *info,
8461 union iwreq_data *awrq,
8465 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8474 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8475 struct iw_point *dwrq = (struct iw_point *)awrq;
8477 /* RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n")); */
8478 if (dwrq->length == 0)
8482 ext = rtw_vmalloc(len);
8486 if (copy_from_user(ext, dwrq->pointer, len)) {
8487 rtw_vmfree(ext, len);
8492 /* RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, */
8493 /* ("rtw_wx_set_priv: %s req=%s\n", */
8494 /* dev->name, ext)); */
8496 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8497 ext_dbg = rtw_vmalloc(len);
8499 rtw_vmfree(ext, len);
8503 _rtw_memcpy(ext_dbg, ext, len);
8506 /* added for wps2.0 @20110524 */
8507 if (dwrq->flags == 0x8766 && len > 8) {
8509 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8510 u8 *probereq_wpsie = ext;
8511 int probereq_wpsie_len = len;
8512 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
8514 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
8515 (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) == _TRUE)) {
8516 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
8518 if (pmlmepriv->wps_probe_req_ie) {
8519 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
8520 pmlmepriv->wps_probe_req_ie_len = 0;
8521 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
8522 pmlmepriv->wps_probe_req_ie = NULL;
8525 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
8526 if (pmlmepriv->wps_probe_req_ie == NULL) {
8527 printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8533 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
8534 pmlmepriv->wps_probe_req_ie_len = cp_sz;
8542 if (len >= WEXT_CSCAN_HEADER_SIZE
8543 && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
8545 ret = rtw_wx_set_scan(dev, info, awrq, ext);
8549 #ifdef CONFIG_ANDROID
8550 /* RTW_INFO("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); */
8552 i = rtw_android_cmdstr_to_num(ext);
8555 case ANDROID_WIFI_CMD_START:
8556 indicate_wx_custom_event(padapter, "START");
8558 case ANDROID_WIFI_CMD_STOP:
8559 indicate_wx_custom_event(padapter, "STOP");
8561 case ANDROID_WIFI_CMD_RSSI: {
8562 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8563 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
8565 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
8566 sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
8571 case ANDROID_WIFI_CMD_LINKSPEED: {
8572 u16 mbps = rtw_get_cur_max_rate(padapter) / 10;
8573 sprintf(ext, "LINKSPEED %d", mbps);
8576 case ANDROID_WIFI_CMD_MACADDR:
8577 sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
8579 case ANDROID_WIFI_CMD_SCAN_ACTIVE: {
8580 /* rtw_set_scan_mode(padapter, SCAN_ACTIVE); */
8584 case ANDROID_WIFI_CMD_SCAN_PASSIVE: {
8585 /* rtw_set_scan_mode(padapter, SCAN_PASSIVE); */
8590 case ANDROID_WIFI_CMD_COUNTRY: {
8591 char country_code[10];
8592 sscanf(ext, "%*s %s", country_code);
8593 rtw_set_country(padapter, country_code);
8598 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8599 RTW_INFO("%s: %s unknowned req=%s\n", __FUNCTION__,
8600 dev->name, ext_dbg);
8607 if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext) + 1))))
8610 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8611 RTW_INFO("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
8612 dev->name, ext_dbg , ext, dwrq->length, (u16)(strlen(ext) + 1));
8614 #endif /* end of CONFIG_ANDROID */
8619 rtw_vmfree(ext, len);
8620 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
8621 rtw_vmfree(ext_dbg, len);
8624 /* RTW_INFO("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", */
8625 /* dev->name, ret); */
8630 #ifdef CONFIG_WOWLAN
8631 static int rtw_wowlan_ctrl(struct net_device *dev,
8632 struct iw_request_info *info,
8633 union iwreq_data *wrqu, char *extra)
8635 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8636 struct wowlan_ioctl_param poidparam;
8637 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8638 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8639 struct sta_info *psta = NULL;
8641 u32 start_time = rtw_get_current_time();
8642 poidparam.subcode = 0;
8644 RTW_INFO("+rtw_wowlan_ctrl: %s\n", extra);
8646 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
8647 check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
8648 #ifdef CONFIG_PNO_SUPPORT
8649 pwrctrlpriv->wowlan_pno_enable = _TRUE;
8651 RTW_INFO("[%s] WARNING: Please Connect With AP First!!\n", __func__);
8652 goto _rtw_wowlan_ctrl_exit_free;
8653 #endif /* CONFIG_PNO_SUPPORT */
8656 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
8657 rtw_scan_abort(padapter);
8659 if (_rtw_memcmp(extra, "enable", 6))
8662 rtw_suspend_common(padapter);
8664 else if (_rtw_memcmp(extra, "disable", 7)) {
8665 #ifdef CONFIG_USB_HCI
8666 RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
8667 RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
8669 rtw_resume_common(padapter);
8671 #ifdef CONFIG_PNO_SUPPORT
8672 pwrctrlpriv->wowlan_pno_enable = _FALSE;
8673 #endif /* CONFIG_PNO_SUPPORT */
8676 RTW_INFO("[%s] Invalid Parameter.\n", __func__);
8677 goto _rtw_wowlan_ctrl_exit_free;
8679 /* mutex_lock(&ioctl_mutex); */
8680 _rtw_wowlan_ctrl_exit_free:
8681 RTW_INFO("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8682 RTW_PRINT("%s in %d ms\n", __func__,
8683 rtw_get_passing_time_ms(start_time));
8684 _rtw_wowlan_ctrl_exit:
8689 * IP filter This pattern if for a frame containing a ip packet:
8690 * 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
8692 * A: Ethernet destination address
8693 * B: Ethernet source address
8694 * C: Ethernet protocol type
8695 * D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20)
8697 * F: IP source address ( 192.168.0.4: C0:A8:00:2C )
8698 * G: IP destination address ( 192.168.0.4: C0:A8:00:2C )
8699 * H: Source port (1024: 04:00)
8700 * I: Destination port (1024: 04:00)
8703 static int rtw_wowlan_set_pattern(struct net_device *dev,
8704 struct iw_request_info *info,
8705 union iwreq_data *wrqu, char *extra)
8707 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8708 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8709 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8710 struct wowlan_ioctl_param poidparam;
8711 int ret = 0, len = 0, i = 0;
8712 u32 start_time = rtw_get_current_time();
8713 u8 input[wrqu->data.length];
8716 poidparam.subcode = 0;
8718 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
8719 check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
8721 RTW_INFO("Please Connect With AP First!!\n");
8722 goto _rtw_wowlan_set_pattern_exit;
8725 if (wrqu->data.length <= 0) {
8727 RTW_INFO("ERROR: parameter length <= 0\n");
8728 goto _rtw_wowlan_set_pattern_exit;
8731 if (copy_from_user(input,
8732 wrqu->data.pointer, wrqu->data.length))
8734 /* leave PS first */
8735 rtw_ps_deny(padapter, PS_DENY_IOCTL);
8736 LeaveAllPowerSaveModeDirect(padapter);
8737 if (strncmp(input, "pattern=", 8) == 0) {
8738 if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_NUM) {
8739 RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n",
8740 pwrpriv->wowlan_pattern_idx);
8741 RTW_INFO("WARNING: please clean priv-pattern first\n");
8743 goto _rtw_wowlan_set_pattern_exit;
8745 index = pwrpriv->wowlan_pattern_idx;
8746 ret = rtw_wowlan_parser_pattern_cmd(input,
8747 pwrpriv->patterns[index].content,
8748 &pwrpriv->patterns[index].len,
8749 pwrpriv->patterns[index].mask);
8752 pwrpriv->wowlan_pattern_idx++;
8754 } else if (strncmp(input, "clean", 5) == 0) {
8755 poidparam.subcode = WOWLAN_PATTERN_CLEAN;
8756 rtw_hal_set_hwreg(padapter,
8757 HW_VAR_WOWLAN, (u8 *)&poidparam);
8758 } else if (strncmp(input, "show", 4) == 0) {
8759 for (i = 0 ; i < MAX_WKFM_NUM ; i++) {
8760 RTW_INFO("=======[%d]=======\n", i);
8761 rtw_read_from_frame_mask(padapter, i);
8764 RTW_INFO("********[RTK priv-patterns]*********\n");
8765 for (i = 0 ; i < MAX_WKFM_NUM ; i++)
8766 rtw_dump_priv_pattern(padapter, i);
8768 RTW_INFO("ERROR: incorrect parameter!\n");
8771 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
8773 _rtw_wowlan_set_pattern_exit:
8776 #endif /* CONFIG_WOWLAN */
8778 #ifdef CONFIG_AP_WOWLAN
8779 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
8780 struct iw_request_info *info,
8781 union iwreq_data *wrqu, char *extra)
8783 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8784 struct wowlan_ioctl_param poidparam;
8785 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8786 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8787 struct sta_info *psta = NULL;
8789 u32 start_time = rtw_get_current_time();
8790 poidparam.subcode = 0;
8792 RTW_INFO("+rtw_ap_wowlan_ctrl: %s\n", extra);
8794 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
8795 RTW_INFO("[%s] It is not AP mode!!\n", __func__);
8796 goto _rtw_ap_wowlan_ctrl_exit_free;
8799 if (_rtw_memcmp(extra, "enable", 6)) {
8801 pwrctrlpriv->wowlan_ap_mode = _TRUE;
8803 rtw_suspend_common(padapter);
8804 } else if (_rtw_memcmp(extra, "disable", 7)) {
8805 #ifdef CONFIG_USB_HCI
8806 RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
8807 RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
8809 rtw_resume_common(padapter);
8811 RTW_INFO("[%s] Invalid Parameter.\n", __func__);
8812 goto _rtw_ap_wowlan_ctrl_exit_free;
8814 /* mutex_lock(&ioctl_mutex); */
8815 _rtw_ap_wowlan_ctrl_exit_free:
8816 RTW_INFO("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8817 RTW_PRINT("%s in %d ms\n", __func__,
8818 rtw_get_passing_time_ms(start_time));
8819 _rtw_ap_wowlan_ctrl_exit:
8822 #endif /* CONFIG_AP_WOWLAN */
8824 static int rtw_pm_set(struct net_device *dev,
8825 struct iw_request_info *info,
8826 union iwreq_data *wrqu, char *extra)
8830 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8832 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
8834 if (_rtw_memcmp(extra, "lps=", 4)) {
8835 sscanf(extra + 4, "%u", &mode);
8836 ret = rtw_pm_set_lps(padapter, mode);
8837 } else if (_rtw_memcmp(extra, "ips=", 4)) {
8838 sscanf(extra + 4, "%u", &mode);
8839 ret = rtw_pm_set_ips(padapter, mode);
8845 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8847 int rtw_vendor_ie_get_raw_data(struct net_device *dev, u32 vendor_ie_num,
8848 char *extra, u32 length)
8851 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8852 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8853 u32 vendor_ie_mask = 0;
8856 if (vendor_ie_num >= WLAN_MAX_VENDOR_IE_NUM) {
8857 RTW_INFO("[%s] only support %d vendor ie\n", __func__ ,
8858 WLAN_MAX_VENDOR_IE_NUM);
8862 if (pmlmepriv->vendor_ielen[vendor_ie_num] == 0) {
8863 RTW_INFO("[%s] Fail, vendor_ie_num: %d is not set\n", __func__,
8868 if (length < 2 * pmlmepriv->vendor_ielen[vendor_ie_num] + 5) {
8869 RTW_INFO("[%s] Fail, buffer size is too small\n", __func__);
8873 vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8874 _rtw_memset(extra, 0, length);
8877 pstring += sprintf(pstring, "%d,%x,", vendor_ie_num, vendor_ie_mask);
8879 for (j = 0; j < pmlmepriv->vendor_ielen[vendor_ie_num]; j++)
8880 pstring += sprintf(pstring, "%02x", pmlmepriv->vendor_ie[vendor_ie_num][j]);
8882 length = pstring - extra;
8886 int rtw_vendor_ie_get_data(struct net_device *dev, int vendor_ie_num, char *extra)
8890 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8891 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8892 u32 vendor_ie_mask = 0;
8895 vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8897 pstring += sprintf(pstring , "\nVendor IE num %d , Mask:%x " , vendor_ie_num , vendor_ie_mask);
8899 if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8900 pstring += sprintf(pstring , "[Beacon]");
8901 if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8902 pstring += sprintf(pstring , "[Probe Req]");
8903 if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8904 pstring += sprintf(pstring , "[Probe Resp]");
8905 if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8906 pstring += sprintf(pstring , "[Assoc Req]");
8907 if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8908 pstring += sprintf(pstring , "[Assoc Resp]");
8910 pstring += sprintf(pstring , "\nVendor IE:\n");
8911 for (j = 0 ; j < pmlmepriv->vendor_ielen[vendor_ie_num] ; j++)
8912 pstring += sprintf(pstring , "%02x" , pmlmepriv->vendor_ie[vendor_ie_num][j]);
8914 length = pstring - extra;
8919 int rtw_vendor_ie_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8921 int ret = 0, vendor_ie_num = 0, cmdlen;
8930 ptmp = (u8 *)rtw_malloc(cmdlen);
8934 if (copy_from_user(ptmp, p->pointer, cmdlen)) {
8938 ret = sscanf(ptmp , "%d", &vendor_ie_num);
8939 if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8944 wrqu->data.length = rtw_vendor_ie_get_data(dev, vendor_ie_num, extra);
8947 rtw_mfree(ptmp, cmdlen);
8952 int rtw_vendor_ie_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8954 int ret = 0, i , len = 0 , totoal_ie_len = 0 , total_ie_len_byte = 0;
8955 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8956 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8957 u32 vendor_ie_mask = 0;
8958 u32 vendor_ie_num = 0;
8961 ret = sscanf(extra, "%d,%x,%*s", &vendor_ie_num , &vendor_ie_mask);
8962 if (strrchr(extra , ','))
8963 extra = strrchr(extra , ',') + 1;
8966 totoal_ie_len = strlen(extra);
8967 RTW_INFO("[%s] vendor_ie_num = %d , vendor_ie_mask = %x , vendor_ie = %s , len = %d\n", __func__ , vendor_ie_num , vendor_ie_mask , extra , totoal_ie_len);
8969 if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8970 RTW_INFO("[%s] only support %d vendor ie\n", __func__ , WLAN_MAX_VENDOR_IE_NUM);
8974 if (totoal_ie_len > WLAN_MAX_VENDOR_IE_LEN) {
8975 RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_VENDOR_IE_LEN);
8979 if (vendor_ie_mask == 0) {
8980 RTW_INFO("[%s] Clear vendor_ie_num %d group\n", __func__ , vendor_ie_num);
8984 if (totoal_ie_len % 2 != 0) {
8985 RTW_INFO("[%s] Fail , IE length = %zu is odd\n" , __func__ , strlen(extra));
8989 if (totoal_ie_len > 0) {
8990 for (i = 0 ; i < strlen(extra) ; i += 2) {
8991 pmlmepriv->vendor_ie[vendor_ie_num][len] = key_2char2num(extra[i] , extra[i + 1]);
8993 id = pmlmepriv->vendor_ie[vendor_ie_num][len];
8994 if (id != WLAN_EID_VENDOR_SPECIFIC) {
8995 RTW_INFO("[%s] Fail , VENDOR SPECIFIC IE ID \"%x\" was not correct\n", __func__ , id);
8998 } else if (len == 1) {
8999 total_ie_len_byte = (totoal_ie_len / 2) - 2;
9000 elen = pmlmepriv->vendor_ie[vendor_ie_num][len];
9001 if (elen != total_ie_len_byte) {
9002 RTW_INFO("[%s] Fail , Input IE length = \"%d\"(hex:%x) bytes , not match input total IE context length \"%d\" bytes\n", __func__ , elen , elen ,
9009 pmlmepriv->vendor_ielen[vendor_ie_num] = len;
9011 pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
9015 if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
9016 RTW_INFO("[%s] Beacon append vendor ie\n", __func__);
9017 if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
9018 RTW_INFO("[%s] Probe Req append vendor ie\n", __func__);
9019 if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
9020 RTW_INFO("[%s] Probe Resp append vendor ie\n", __func__);
9021 if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
9022 RTW_INFO("[%s] Assoc Req append vendor ie\n", __func__);
9023 if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
9024 RTW_INFO("[%s] Assoc Resp append vendor ie\n", __func__);
9026 pmlmepriv->vendor_ie_mask[vendor_ie_num] = vendor_ie_mask;
9031 _rtw_memset(pmlmepriv->vendor_ie[vendor_ie_num] , 0 , sizeof(u32) * WLAN_MAX_VENDOR_IE_LEN);
9032 pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
9033 pmlmepriv->vendor_ie_mask[vendor_ie_num] = 0;
9038 static int rtw_mp_efuse_get(struct net_device *dev,
9039 struct iw_request_info *info,
9040 union iwreq_data *wdata, char *extra)
9042 PADAPTER padapter = rtw_netdev_priv(dev);
9043 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9045 PEFUSE_HAL pEfuseHal;
9046 struct iw_point *wrqu;
9048 u8 *PROMContent = pHalData->efuse_eeprom_data;
9049 u8 ips_mode = IPS_NUM; /* init invalid value */
9050 u8 lps_mode = PS_MODE_NUM; /* init invalid value */
9051 struct pwrctrl_priv *pwrctrlpriv ;
9054 char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
9055 u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;
9056 u16 max_available_len = 0, raw_cursize = 0, raw_maxsize = 0;
9060 u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
9063 wrqu = (struct iw_point *)wdata;
9064 pwrctrlpriv = adapter_to_pwrctl(padapter);
9065 pEfuseHal = &pHalData->EfuseHal;
9068 data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9073 rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9074 if (rawdata == NULL) {
9079 if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {
9084 lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
9085 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
9089 ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
9090 rtw_pm_set_ips(padapter, IPS_NONE);
9094 RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
9097 /* mac 16 "00e04c871200" rmap,00,2 */
9098 while ((token = strsep(&pch, ",")) != NULL) {
9105 padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */
9108 if (strcmp(tmp[0], "status") == 0) {
9109 sprintf(extra, "Load File efuse=%s,Load File MAC=%s"
9110 , pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK"
9111 , pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK"
9114 } else if (strcmp(tmp[0], "drvmap") == 0) {
9115 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
9117 sprintf(extra, "\n");
9118 for (i = 0; i < mapLen; i += 16) {
9119 /*RTW_INFO("0x%02x\t", i);*/
9120 sprintf(extra, "%s0x%02x\t", extra, i);
9121 for (j = 0; j < 8; j++) {
9122 /* RTW_INFO("%02X ", data[i+j]); */
9123 sprintf(extra, "%s%02X ", extra, PROMContent[i + j]);
9125 /* RTW_INFO("\t"); */
9126 sprintf(extra, "%s\t", extra);
9127 for (; j < 16; j++) {
9128 /* RTW_INFO("%02X ", data[i+j]); */
9129 sprintf(extra, "%s%02X ", extra, PROMContent[i + j]);
9131 /* RTW_INFO("\n"); */
9132 sprintf(extra, "%s\n", extra);
9134 /* RTW_INFO("\n"); */
9135 } else if (strcmp(tmp[0], "realmap") == 0) {
9136 static u8 order = 0;
9139 u32 blksz = 0x200; /* The size of one time show, default 512 */
9141 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
9142 efuse = pEfuseHal->fakeEfuseInitMap;
9143 if (rtw_efuse_mask_map_read(padapter, 0, mapLen, efuse) == _FAIL) {
9144 RTW_INFO("%s: read realmap Fail!!\n", __FUNCTION__);
9150 RTW_INFO("OFFSET\tVALUE(hex)\n");
9151 for (i = 0; i < mapLen; i += 16) {
9152 RTW_INFO("0x%02x\t", i);
9153 for (j = 0; j < 8; j++)
9154 RTW_INFO("%02X ", efuse[i + j]);
9157 RTW_INFO("%02X ", efuse[i + j]);
9163 shift = blksz * order;
9165 cnt = mapLen - shift;
9172 sprintf(extra, "\n");
9173 for (i = 0; i < cnt; i += 16) {
9174 sprintf(extra, "%s0x%02x\t", extra, shift + i);
9175 for (j = 0; j < 8; j++)
9176 sprintf(extra, "%s%02X ", extra, efuse[i + j]);
9177 sprintf(extra, "%s\t", extra);
9179 sprintf(extra, "%s%02X ", extra, efuse[i + j]);
9180 sprintf(extra, "%s\n", extra);
9182 if ((shift + cnt) < mapLen)
9183 sprintf(extra, "%s\t...more\n", extra);
9184 } else if (strcmp(tmp[0], "rmap") == 0) {
9185 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9186 RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9191 /* rmap addr cnts */
9192 addr = simple_strtoul(tmp[1], &ptmp, 16);
9193 RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9195 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9197 RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9201 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9203 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (PVOID)&max_available_len, _FALSE);
9204 if ((addr + cnts) > max_available_len) {
9205 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9210 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
9211 RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
9216 /* RTW_INFO("%s: data={", __FUNCTION__); */
9218 for (i = 0; i < cnts; i++) {
9219 /* RTW_INFO("0x%02x ", data[i]); */
9220 sprintf(extra, "%s0x%02X ", extra, data[i]);
9222 /* RTW_INFO("}\n"); */
9223 } else if (strcmp(tmp[0], "realraw") == 0) {
9224 static u8 raw_order = 0;
9226 u32 blksz = 0x200; /* The size of one time show, default 512 */
9229 mapLen = EFUSE_MAX_SIZE;
9230 RTW_INFO("EFUSE_MAX_SIZE = %d\n", EFUSE_MAX_SIZE);
9232 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
9233 RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
9238 shift = blksz * raw_order;
9240 cnt = mapLen - shift;
9247 sprintf(extra, "\n");
9248 for (i = 0; i < cnt; i += 16) {
9249 sprintf(extra, "%s0x%02x\t", extra, shift + i);
9250 for (j = 0; j < 8; j++)
9251 sprintf(extra, "%s%02X ", extra, rawdata[i + j]);
9252 sprintf(extra, "%s\t", extra);
9254 sprintf(extra, "%s%02X ", extra, rawdata[i + j]);
9255 sprintf(extra, "%s\n", extra);
9257 if ((shift + cnt) < mapLen)
9258 sprintf(extra, "%s\t...more (left:%d/%d)\n", extra, mapLen-(shift + cnt), mapLen);
9260 } else if (strcmp(tmp[0], "btrealraw") == 0) {
9261 static u8 bt_raw_order = 0;
9263 u32 blksz = 0x200; /* The size of one time show, default 512 */
9265 mapLen = EFUSE_BT_REAL_CONTENT_LEN;
9266 RTW_INFO("Real content len = %d\n", mapLen);
9268 if (rtw_efuse_bt_access(padapter, _FALSE, 0, mapLen, rawdata) == _FAIL) {
9269 RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
9274 rtw_write8(padapter, 0x35, 0x1);
9276 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
9277 RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
9282 _rtw_memset(extra, '\0', strlen(extra));
9284 shift = blksz * bt_raw_order;
9286 cnt = mapLen - shift;
9293 sprintf(extra, "\n");
9294 for (i = 0; i < cnt; i += 16) {
9295 sprintf(extra, "%s0x%02x\t", extra, shift + i);
9296 for (j = 0; j < 8; j++)
9297 sprintf(extra, "%s%02X ", extra, rawdata[i + j]);
9298 sprintf(extra, "%s\t", extra);
9300 sprintf(extra, "%s%02X ", extra, rawdata[i + j]);
9301 sprintf(extra, "%s\n", extra);
9304 if ((shift + cnt) < mapLen)
9305 sprintf(extra, "%s\t...more (left:%d/%d)\n", extra, mapLen-(shift + cnt), mapLen);
9306 } else if (strcmp(tmp[0], "mac") == 0) {
9307 if (hal_efuse_macaddr_offset(padapter) == -1) {
9312 addr = hal_efuse_macaddr_offset(padapter);
9315 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
9316 if ((addr + cnts) > max_available_len) {
9317 RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9322 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
9323 RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
9328 /* RTW_INFO("%s: MAC address={", __FUNCTION__); */
9330 for (i = 0; i < cnts; i++) {
9331 /* RTW_INFO("%02X", data[i]); */
9332 sprintf(extra, "%s%02X", extra, data[i]);
9333 if (i != (cnts - 1)) {
9334 /* RTW_INFO(":"); */
9335 sprintf(extra, "%s:", extra);
9338 /* RTW_INFO("}\n"); */
9339 } else if (strcmp(tmp[0], "vidpid") == 0) {
9340 #ifdef CONFIG_RTL8188E
9341 #ifdef CONFIG_USB_HCI
9342 addr = EEPROM_VID_88EU;
9344 #ifdef CONFIG_PCI_HCI
9345 addr = EEPROM_VID_88EE;
9347 #endif /* CONFIG_RTL8188E */
9349 #ifdef CONFIG_RTL8192E
9350 #ifdef CONFIG_USB_HCI
9351 addr = EEPROM_VID_8192EU;
9353 #ifdef CONFIG_PCI_HCI
9354 addr = EEPROM_VID_8192EE;
9356 #endif /* CONFIG_RTL8192E */
9357 #ifdef CONFIG_RTL8723B
9358 addr = EEPROM_VID_8723BU;
9359 #endif /* CONFIG_RTL8192E */
9361 #ifdef CONFIG_RTL8188F
9362 addr = EEPROM_VID_8188FU;
9363 #endif /* CONFIG_RTL8188F */
9365 #ifdef CONFIG_RTL8703B
9366 #ifdef CONFIG_USB_HCI
9367 addr = EEPROM_VID_8703BU;
9369 #endif /* CONFIG_RTL8703B */
9371 #ifdef CONFIG_RTL8723D
9372 #ifdef CONFIG_USB_HCI
9373 addr = EEPROM_VID_8723DU;
9374 #endif /* CONFIG_USB_HCI */
9375 #endif /* CONFIG_RTL8723D */
9379 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
9380 if ((addr + cnts) > max_available_len) {
9381 RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9385 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
9386 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9391 /* RTW_INFO("%s: {VID,PID}={", __FUNCTION__); */
9393 for (i = 0; i < cnts; i++) {
9394 /* RTW_INFO("0x%02x", data[i]); */
9395 sprintf(extra, "%s0x%02X", extra, data[i]);
9396 if (i != (cnts - 1)) {
9397 /* RTW_INFO(","); */
9398 sprintf(extra, "%s,", extra);
9401 /* RTW_INFO("}\n"); */
9402 } else if (strcmp(tmp[0], "ableraw") == 0) {
9404 raw_maxsize = efuse_GetavailableSize(padapter);
9406 efuse_GetCurrentSize(padapter, &raw_cursize);
9407 raw_maxsize = efuse_GetMaxSize(padapter);
9409 sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
9410 } else if (strcmp(tmp[0], "btableraw") == 0) {
9411 efuse_bt_GetCurrentSize(padapter, &raw_cursize);
9412 raw_maxsize = efuse_bt_GetMaxSize(padapter);
9413 sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
9414 } else if (strcmp(tmp[0], "btfmap") == 0) {
9416 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9418 mapLen = EFUSE_BT_MAX_MAP_LEN;
9419 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
9420 RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9425 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9426 sprintf(extra, "\n");
9427 for (i = 0; i < 512; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */
9428 /* RTW_INFO("0x%03x\t", i); */
9429 sprintf(extra, "%s0x%03x\t", extra, i);
9430 for (j = 0; j < 8; j++) {
9431 /* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
9432 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i + j]);
9434 /* RTW_INFO("\t"); */
9435 sprintf(extra, "%s\t", extra);
9436 for (; j < 16; j++) {
9437 /* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
9438 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i + j]);
9440 /* RTW_INFO("\n"); */
9441 sprintf(extra, "%s\n", extra);
9443 /* RTW_INFO("\n"); */
9444 } else if (strcmp(tmp[0], "btbmap") == 0) {
9445 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9447 mapLen = EFUSE_BT_MAX_MAP_LEN;
9448 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
9449 RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
9454 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9455 sprintf(extra, "\n");
9456 for (i = 512; i < 1024 ; i += 16) {
9457 /* RTW_INFO("0x%03x\t", i); */
9458 sprintf(extra, "%s0x%03x\t", extra, i);
9459 for (j = 0; j < 8; j++) {
9460 /* RTW_INFO("%02X ", data[i+j]); */
9461 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i + j]);
9463 /* RTW_INFO("\t"); */
9464 sprintf(extra, "%s\t", extra);
9465 for (; j < 16; j++) {
9466 /* RTW_INFO("%02X ", data[i+j]); */
9467 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i + j]);
9469 /* RTW_INFO("\n"); */
9470 sprintf(extra, "%s\n", extra);
9472 /* RTW_INFO("\n"); */
9473 } else if (strcmp(tmp[0], "btrmap") == 0) {
9474 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9478 rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
9479 BTStatus = rtw_read8(padapter, 0xa0);
9481 RTW_INFO("%s: Check 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9482 if (BTStatus != 0x04) {
9483 sprintf(extra, "BT Status not Active ,can't to read BT eFuse\n");
9487 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9492 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9494 /* rmap addr cnts */
9495 addr = simple_strtoul(tmp[1], &ptmp, 16);
9496 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9498 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9500 RTW_INFO("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
9504 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9506 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
9507 if ((addr + cnts) > max_available_len) {
9508 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9513 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
9514 RTW_INFO("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
9520 /* RTW_INFO("%s: bt efuse data={", __FUNCTION__); */
9521 for (i = 0; i < cnts; i++) {
9522 /* RTW_INFO("0x%02x ", data[i]); */
9523 sprintf(extra, "%s 0x%02X ", extra, data[i]);
9525 /* RTW_INFO("}\n"); */
9526 RTW_INFO(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
9527 } else if (strcmp(tmp[0], "btffake") == 0) {
9528 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9529 sprintf(extra, "\n");
9530 for (i = 0; i < 512; i += 16) {
9531 /* RTW_INFO("0x%03x\t", i); */
9532 sprintf(extra, "%s0x%03x\t", extra, i);
9533 for (j = 0; j < 8; j++) {
9534 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9535 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9537 /* RTW_INFO("\t"); */
9538 sprintf(extra, "%s\t", extra);
9539 for (; j < 16; j++) {
9540 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9541 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9543 /* RTW_INFO("\n"); */
9544 sprintf(extra, "%s\n", extra);
9546 /* RTW_INFO("\n"); */
9547 } else if (strcmp(tmp[0], "btbfake") == 0) {
9548 /* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
9549 sprintf(extra, "\n");
9550 for (i = 512; i < 1024; i += 16) {
9551 /* RTW_INFO("0x%03x\t", i); */
9552 sprintf(extra, "%s0x%03x\t", extra, i);
9553 for (j = 0; j < 8; j++) {
9554 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9555 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9557 /* RTW_INFO("\t"); */
9558 sprintf(extra, "%s\t", extra);
9559 for (; j < 16; j++) {
9560 /* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
9561 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9563 /* RTW_INFO("\n"); */
9564 sprintf(extra, "%s\n", extra);
9566 /* RTW_INFO("\n"); */
9567 } else if (strcmp(tmp[0], "wlrfkmap") == 0) {
9568 static u8 fk_order = 0;
9571 u32 blksz = 0x200; /* The size of one time show, default 512 */
9573 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
9574 efuse = pEfuseHal->fakeEfuseModifiedMap;
9576 shift = blksz * fk_order;
9578 cnt = mapLen - shift;
9585 sprintf(extra, "\n");
9586 for (i = 0; i < cnt; i += 16) {
9587 sprintf(extra, "%s0x%02x\t", extra, shift + i);
9588 for (j = 0; j < 8; j++)
9589 sprintf(extra, "%s%02X ", extra, efuse[i + j]);
9590 sprintf(extra, "%s\t", extra);
9592 sprintf(extra, "%s%02X ", extra, efuse[i + j]);
9593 sprintf(extra, "%s\n", extra);
9595 if ((shift + cnt) < mapLen)
9596 sprintf(extra, "%s\t...more\n", extra);
9598 } else if (strcmp(tmp[0], "wlrfkrmap") == 0) {
9599 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9600 RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9604 /* rmap addr cnts */
9605 addr = simple_strtoul(tmp[1], &ptmp, 16);
9606 RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9608 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9610 RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9614 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9616 /* RTW_INFO("%s: data={", __FUNCTION__); */
9618 for (i = 0; i < cnts; i++) {
9619 RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9620 sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9622 } else if (strcmp(tmp[0], "btrfkrmap") == 0) {
9623 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9624 RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9628 /* rmap addr cnts */
9629 addr = simple_strtoul(tmp[1], &ptmp, 16);
9630 RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9632 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9634 RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9638 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9640 /* RTW_INFO("%s: data={", __FUNCTION__); */
9642 for (i = 0; i < cnts; i++) {
9643 RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeBTEfuseModifiedMap[addr + i]);
9644 sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[addr + i]);
9647 sprintf(extra, "Command not found!");
9651 rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9653 rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9655 wrqu->length = strlen(extra);
9657 if (padapter->registrypriv.mp_mode == 0) {
9659 rtw_pm_set_ips(padapter, ips_mode);
9660 #endif /* CONFIG_IPS */
9663 rtw_pm_set_lps(padapter, lps_mode);
9664 #endif /* CONFIG_LPS */
9668 padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
9673 static int rtw_mp_efuse_set(struct net_device *dev,
9674 struct iw_request_info *info,
9675 union iwreq_data *wdata, char *extra)
9677 struct iw_point *wrqu;
9679 struct pwrctrl_priv *pwrctrlpriv ;
9680 PHAL_DATA_TYPE pHalData;
9681 PEFUSE_HAL pEfuseHal;
9683 u8 ips_mode = IPS_NUM; /* init invalid value */
9684 u8 lps_mode = PS_MODE_NUM; /* init invalid value */
9685 u32 i = 0, j = 0, jj, kk;
9687 u8 *ShadowMapBT = NULL;
9688 u8 *ShadowMapWiFi = NULL;
9689 u8 *setrawdata = NULL;
9690 char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
9691 u16 addr = 0xFF, cnts = 0, BTStatus = 0 , max_available_len = 0;
9695 wrqu = (struct iw_point *)wdata;
9696 padapter = rtw_netdev_priv(dev);
9697 pwrctrlpriv = adapter_to_pwrctl(padapter);
9698 pHalData = GET_HAL_DATA(padapter);
9699 pEfuseHal = &pHalData->EfuseHal;
9702 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9705 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&wifimaplen, _FALSE);
9707 setdata = rtw_zmalloc(1024);
9708 if (setdata == NULL) {
9712 ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9713 if (ShadowMapBT == NULL) {
9717 ShadowMapWiFi = rtw_malloc(wifimaplen);
9718 if (ShadowMapWiFi == NULL) {
9722 setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9723 if (setrawdata == NULL) {
9729 lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
9730 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
9734 ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
9735 rtw_pm_set_ips(padapter, IPS_NONE);
9739 RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
9742 while ((token = strsep(&pch, ",")) != NULL) {
9749 /* tmp[0],[1],[2] */
9750 /* wmap,addr,00e04c871200 */
9751 if (strcmp(tmp[0], "wmap") == 0) {
9752 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9758 /* unknown bug workaround, need to fix later */
9760 rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9762 rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9764 rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9766 rtw_read8(padapter, EFUSE_CTRL);
9767 #endif /* RTW_HALMAC */
9769 addr = simple_strtoul(tmp[1], &ptmp, 16);
9772 cnts = strlen(tmp[2]);
9783 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9784 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9785 RTW_INFO("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9787 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9788 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9790 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
9792 if ((addr + cnts) > max_available_len) {
9793 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9798 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9799 RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9804 RTW_INFO("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__);
9805 if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS) {
9806 if (_rtw_memcmp((void *)ShadowMapWiFi , (void *)setdata, cnts)) {
9807 RTW_INFO("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9808 sprintf(extra, "WiFi write map compare OK\n");
9812 sprintf(extra, "WiFi write map compare FAIL\n");
9813 RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9818 } else if (strcmp(tmp[0], "wraw") == 0) {
9819 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9824 addr = simple_strtoul(tmp[1], &ptmp, 16);
9827 cnts = strlen(tmp[2]);
9838 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9839 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9840 RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9842 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9843 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9845 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9846 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9850 } else if (strcmp(tmp[0], "btwraw") == 0) {
9851 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9856 addr = simple_strtoul(tmp[1], &ptmp, 16);
9859 cnts = strlen(tmp[2]);
9870 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9871 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9872 RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9874 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9875 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9877 if (rtw_efuse_bt_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9878 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9883 rtw_write8(padapter, 0x35, 1); /* switch bank 1 (BT)*/
9884 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9885 RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9886 rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9890 rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9892 } else if (strcmp(tmp[0], "mac") == 0) {
9893 if (tmp[1] == NULL) {
9898 /* mac,00e04c871200 */
9900 if (hal_efuse_macaddr_offset(padapter) == -1) {
9905 addr = hal_efuse_macaddr_offset(padapter);
9906 cnts = strlen(tmp[1]);
9917 RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9922 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9923 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9924 RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9926 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9927 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9929 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
9931 if ((addr + cnts) > max_available_len) {
9932 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9937 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9938 RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9942 } else if (strcmp(tmp[0], "vidpid") == 0) {
9943 if (tmp[1] == NULL) {
9948 /* pidvid,da0b7881 */
9949 #ifdef CONFIG_RTL8188E
9950 #ifdef CONFIG_USB_HCI
9951 addr = EEPROM_VID_88EU;
9953 #ifdef CONFIG_PCI_HCI
9954 addr = EEPROM_VID_88EE;
9956 #endif /* CONFIG_RTL8188E */
9958 #ifdef CONFIG_RTL8192E
9959 #ifdef CONFIG_USB_HCI
9960 addr = EEPROM_VID_8192EU;
9962 #ifdef CONFIG_PCI_HCI
9963 addr = EEPROM_VID_8192EE;
9965 #endif /* CONFIG_RTL8188E */
9967 #ifdef CONFIG_RTL8723B
9968 addr = EEPROM_VID_8723BU;
9971 #ifdef CONFIG_RTL8188F
9972 addr = EEPROM_VID_8188FU;
9975 #ifdef CONFIG_RTL8703B
9976 #ifdef CONFIG_USB_HCI
9977 addr = EEPROM_VID_8703BU;
9978 #endif /* CONFIG_USB_HCI */
9979 #endif /* CONFIG_RTL8703B */
9981 #ifdef CONFIG_RTL8723D
9982 #ifdef CONFIG_USB_HCI
9983 addr = EEPROM_VID_8723DU;
9984 #endif /* CONFIG_USB_HCI */
9985 #endif /* CONFIG_RTL8723D */
9987 cnts = strlen(tmp[1]);
9998 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9999 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
10000 RTW_INFO("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
10002 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
10003 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
10005 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10006 if ((addr + cnts) > max_available_len) {
10007 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10012 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
10013 RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10017 } else if (strcmp(tmp[0], "wldumpfake") == 0) {
10018 if (wifimaplen > EFUSE_MAX_MAP_LEN)
10019 cnts = EFUSE_MAX_MAP_LEN;
10022 if (rtw_efuse_mask_map_read(padapter, 0, cnts, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS)
10023 RTW_INFO("%s: WiFi hw efuse dump to Fake map success\n", __func__);
10025 RTW_INFO("%s: WiFi hw efuse dump to Fake map Fail\n", __func__);
10028 } else if (strcmp(tmp[0], "btwmap") == 0) {
10029 rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
10030 BTStatus = rtw_read8(padapter, 0xa0);
10031 RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
10032 if (BTStatus != 0x04) {
10033 sprintf(extra, "BT Status not Active ,can't do Write\n");
10037 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
10043 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
10045 rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
10047 rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
10049 rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
10051 rtw_read8(padapter, EFUSE_CTRL);
10052 BTEfuse_PowerSwitch(padapter, 1, _FALSE);
10053 #endif /* RTW_HALMAC */
10055 addr = simple_strtoul(tmp[1], &ptmp, 16);
10058 cnts = strlen(tmp[2]);
10069 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
10070 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
10071 RTW_INFO("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
10073 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
10074 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
10075 #ifdef CONFIG_RTL8703B
10076 if (cnts == 1 && addr == 0x189) {
10077 setdata[1] = setdata[0];
10081 RTW_INFO("addr 0x%x ,setdata=0x%X 0x%X\n", addr, setdata[0], setdata[1]);
10082 } else if (cnts == 1 && addr == 0x161) {
10083 setdata[1] = setdata[0];
10087 RTW_INFO("addr 0x%x ,setdata=0x%X 0x%X\n", addr, setdata[0], setdata[1]);
10091 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10092 if ((addr + cnts) > max_available_len) {
10093 RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10098 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
10099 RTW_INFO("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
10104 RTW_INFO("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __FUNCTION__);
10105 if ((rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT) == _SUCCESS)) {
10106 if (_rtw_memcmp((void *)ShadowMapBT , (void *)setdata, cnts)) {
10107 RTW_INFO("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__, BTStatus);
10108 sprintf(extra, "BT write map compare OK");
10112 sprintf(extra, "BT write map compare FAIL");
10113 RTW_INFO("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__, BTStatus);
10118 } else if (strcmp(tmp[0], "btwfake") == 0) {
10119 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
10124 addr = simple_strtoul(tmp[1], &ptmp, 16);
10127 cnts = strlen(tmp[2]);
10138 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
10139 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
10140 RTW_INFO("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
10142 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
10143 pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
10144 } else if (strcmp(tmp[0], "btdumpfake") == 0) {
10145 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS)
10146 RTW_INFO("%s: BT read all map success\n", __FUNCTION__);
10148 RTW_INFO("%s: BT read all map Fail!\n", __FUNCTION__);
10151 } else if (strcmp(tmp[0], "btfk2map") == 0) {
10152 rtw_write8(padapter, 0xa3, 0x05);
10153 BTStatus = rtw_read8(padapter, 0xa0);
10154 RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
10155 if (BTStatus != 0x04) {
10156 sprintf(extra, "BT Status not Active Write FAIL\n");
10160 BTEfuse_PowerSwitch(padapter, 1, _TRUE);
10162 rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
10164 rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
10166 rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
10168 rtw_read8(padapter, EFUSE_CTRL);
10169 BTEfuse_PowerSwitch(padapter, 1, _FALSE);
10170 #endif /* RTW_HALMAC */
10171 _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
10173 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {
10174 RTW_INFO("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
10179 RTW_INFO("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
10180 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
10181 printk("0x%02x\t", i);
10182 for (j = 0; j < 8; j++)
10183 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
10186 for (; j < 16; j++)
10187 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
10193 RTW_INFO("%s: rtw_BT_efuse_map_read _rtw_memcmp\n", __FUNCTION__);
10194 if ((rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)) {
10195 if (_rtw_memcmp((void *)pEfuseHal->fakeBTEfuseModifiedMap, (void *)pEfuseHal->fakeBTEfuseInitMap, EFUSE_BT_MAX_MAP_LEN)) {
10196 sprintf(extra, "BT write map compare OK");
10197 RTW_INFO("%s: BT write map afterf compare success BTStatus=0x%x\n", __FUNCTION__, BTStatus);
10201 sprintf(extra, "BT write map compare FAIL");
10202 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10203 RTW_INFO("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__, i);
10205 if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS) {
10206 RTW_INFO("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
10208 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
10209 printk("0x%02x\t", i);
10210 for (j = 0; j < 8; j++)
10211 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
10213 for (; j < 16; j++)
10214 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
10219 RTW_INFO("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__, BTStatus);
10225 } else if (strcmp(tmp[0], "wlfk2map") == 0) {
10226 if (wifimaplen > EFUSE_MAX_MAP_LEN)
10227 cnts = EFUSE_MAX_MAP_LEN;
10230 if (rtw_efuse_map_write(padapter, 0x00, cnts, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {
10231 RTW_INFO("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
10236 if (rtw_efuse_mask_map_read(padapter, 0x00, wifimaplen, ShadowMapWiFi) == _SUCCESS) {
10237 if (_rtw_memcmp((void *)ShadowMapWiFi , (void *)pEfuseHal->fakeEfuseModifiedMap, cnts)) {
10238 RTW_INFO("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
10239 sprintf(extra, "WiFi write map compare OK\n");
10243 sprintf(extra, "WiFi write map compare FAIL\n");
10244 RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
10249 } else if (strcmp(tmp[0], "wlwfake") == 0) {
10250 if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
10255 addr = simple_strtoul(tmp[1], &ptmp, 16);
10258 cnts = strlen(tmp[2]);
10269 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
10270 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
10271 RTW_INFO("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
10273 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
10274 pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
10275 _rtw_memset(extra, '\0', strlen(extra));
10276 sprintf(extra, "wlwfake OK\n");
10279 else if (strcmp(tmp[0], "wfakemac") == 0) {
10280 if (tmp[1] == NULL) {
10284 /* wfakemac,00e04c871200 */
10285 if (hal_efuse_macaddr_offset(padapter) == -1) {
10290 addr = hal_efuse_macaddr_offset(padapter);
10291 cnts = strlen(tmp[1]);
10302 RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
10307 RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
10308 RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
10309 RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
10311 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
10312 pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
10314 _rtw_memset(extra, '\0', strlen(extra));
10315 sprintf(extra, "write mac addr to fake map OK\n");
10320 rtw_mfree(setdata, 1024);
10322 rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
10324 rtw_mfree(ShadowMapWiFi, wifimaplen);
10326 rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
10328 wrqu->length = strlen(extra);
10330 if (padapter->registrypriv.mp_mode == 0) {
10332 rtw_pm_set_ips(padapter, ips_mode);
10333 #endif /* CONFIG_IPS */
10336 rtw_pm_set_lps(padapter, lps_mode);
10337 #endif /* CONFIG_LPS */
10344 #ifdef CONFIG_MP_INCLUDED
10345 static int rtw_priv_mp_set(struct net_device *dev,
10346 struct iw_request_info *info,
10347 union iwreq_data *wdata, char *extra)
10350 struct iw_point *wrqu = (struct iw_point *)wdata;
10351 u32 subcmd = wrqu->flags;
10355 RTW_INFO("set case mp_start\n");
10356 rtw_mp_start(dev, info, wrqu, extra);
10359 RTW_INFO("set case mp_stop\n");
10360 rtw_mp_stop(dev, info, wrqu, extra);
10363 RTW_INFO("set case mp_bandwidth\n");
10364 rtw_mp_bandwidth(dev, info, wrqu, extra);
10366 case MP_RESET_STATS:
10367 RTW_INFO("set case MP_RESET_STATS\n");
10368 rtw_mp_reset_stats(dev, info, wrqu, extra);
10370 case MP_SetRFPathSwh:
10371 RTW_INFO("set MP_SetRFPathSwitch\n");
10372 rtw_mp_SetRFPath(dev, info, wdata, extra);
10375 RTW_INFO("set CTA_TEST\n");
10376 rtw_cta_test_start(dev, info, wdata, extra);
10378 case MP_DISABLE_BT_COEXIST:
10379 RTW_INFO("set case MP_DISABLE_BT_COEXIST\n");
10380 rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
10389 static int rtw_priv_mp_get(struct net_device *dev,
10390 struct iw_request_info *info,
10391 union iwreq_data *wdata, char *extra)
10394 struct iw_point *wrqu = (struct iw_point *)wdata;
10395 u32 subcmd = wrqu->flags;
10399 rtw_mp_write_reg(dev, info, wrqu, extra);
10402 rtw_mp_write_rf(dev, info, wrqu, extra);
10405 RTW_INFO("mp_get MP_PHYPARA\n");
10406 rtw_mp_phypara(dev, info, wrqu, extra);
10409 RTW_INFO("set case mp_channel\n");
10410 rtw_mp_channel(dev , info, wrqu, extra);
10413 RTW_INFO("mp_get READ_REG\n");
10414 rtw_mp_read_reg(dev, info, wrqu, extra);
10417 RTW_INFO("mp_get READ_RF\n");
10418 rtw_mp_read_rf(dev, info, wrqu, extra);
10421 RTW_INFO("set case mp_rate\n");
10422 rtw_mp_rate(dev, info, wrqu, extra);
10425 RTW_INFO("set case MP_TXPOWER\n");
10426 rtw_mp_txpower(dev, info, wrqu, extra);
10429 RTW_INFO("set case MP_ANT_TX\n");
10430 rtw_mp_ant_tx(dev, info, wrqu, extra);
10433 RTW_INFO("set case MP_ANT_RX\n");
10434 rtw_mp_ant_rx(dev, info, wrqu, extra);
10437 rtw_mp_trx_query(dev, info, wrqu, extra);
10440 RTW_INFO("set case MP_CTX\n");
10441 rtw_mp_ctx(dev, info, wrqu, extra);
10444 RTW_INFO("set case MP_ARX\n");
10445 rtw_mp_arx(dev, info, wrqu, extra);
10448 RTW_INFO("set case MP_DUMP\n");
10449 rtw_mp_dump(dev, info, wrqu, extra);
10452 RTW_INFO("set case MP_PSD\n");
10453 rtw_mp_psd(dev, info, wrqu, extra);
10456 RTW_INFO("set case MP_THER\n");
10457 rtw_mp_thermal(dev, info, wrqu, extra);
10460 RTW_INFO("set MP_PwrCtlDM\n");
10461 rtw_mp_PwrCtlDM(dev, info, wrqu, extra);
10463 case MP_QueryDrvStats:
10464 RTW_INFO("mp_get MP_QueryDrvStats\n");
10465 rtw_mp_QueryDrv(dev, info, wdata, extra);
10468 RTW_INFO("set case MP_PWRTRK\n");
10469 rtw_mp_pwrtrk(dev, info, wrqu, extra);
10472 RTW_INFO("set case efuse set\n");
10473 rtw_mp_efuse_set(dev, info, wdata, extra);
10476 RTW_INFO("efuse get EFUSE_GET\n");
10477 rtw_mp_efuse_get(dev, info, wdata, extra);
10479 case MP_GET_TXPOWER_INX:
10480 RTW_INFO("mp_get MP_GET_TXPOWER_INX\n");
10481 rtw_mp_txpower_index(dev, info, wrqu, extra);
10484 RTW_INFO("mp_get MP_GETVER\n");
10485 rtw_mp_getver(dev, info, wdata, extra);
10488 RTW_INFO("mp_get MP_MON\n");
10489 rtw_mp_mon(dev, info, wdata, extra);
10492 RTW_INFO("mp_get EFUSE_MASK\n");
10493 rtw_efuse_mask_file(dev, info, wdata, extra);
10496 RTW_INFO("mp_get EFUSE_FILE\n");
10497 rtw_efuse_file_map(dev, info, wdata, extra);
10500 RTW_INFO("mp_get MP_TX\n");
10501 rtw_mp_tx(dev, info, wdata, extra);
10504 RTW_INFO("mp_get MP_RX\n");
10505 rtw_mp_rx(dev, info, wdata, extra);
10507 case MP_HW_TX_MODE:
10508 RTW_INFO("mp_get MP_HW_TX_MODE\n");
10509 rtw_mp_hwtx(dev, info, wdata, extra);
10517 #endif /*#if defined(CONFIG_MP_INCLUDED)*/
10520 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
10521 #define DBG_MP_SDIO_INDIRECT_ACCESS 1
10522 static int rtw_mp_sd_iread(struct net_device *dev
10523 , struct iw_request_info *info
10524 , struct iw_point *wrqu
10529 unsigned long addr;
10531 PADAPTER padapter = rtw_netdev_priv(dev);
10533 if (wrqu->length > 16) {
10534 RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10539 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10540 RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10545 _rtw_memset(extra, 0, wrqu->length);
10547 if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) {
10548 RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10553 if (addr > 0x3FFF) {
10554 RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10559 if (DBG_MP_SDIO_INDIRECT_ACCESS)
10560 RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr);
10564 sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr));
10565 wrqu->length = strlen(extra);
10568 sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr));
10569 wrqu->length = strlen(extra);
10572 sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr));
10573 wrqu->length = strlen(extra);
10585 static int rtw_mp_sd_iwrite(struct net_device *dev
10586 , struct iw_request_info *info
10587 , struct iw_point *wrqu
10591 unsigned long addr, data;
10593 PADAPTER padapter = rtw_netdev_priv(dev);
10596 if (wrqu->length > 32) {
10597 RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10602 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10603 RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10608 _rtw_memset(extra, 0, wrqu->length);
10610 if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) {
10611 RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10616 if (addr > 0x3FFF) {
10617 RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10622 if (DBG_MP_SDIO_INDIRECT_ACCESS)
10623 RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data);
10631 rtw_sd_iwrite8(padapter, addr, data);
10634 if (data > 0xFFFF) {
10638 rtw_sd_iwrite16(padapter, addr, data);
10641 rtw_sd_iwrite32(padapter, addr, data);
10652 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
10654 static int rtw_priv_set(struct net_device *dev,
10655 struct iw_request_info *info,
10656 union iwreq_data *wdata, char *extra)
10658 struct iw_point *wrqu = (struct iw_point *)wdata;
10659 u32 subcmd = wrqu->flags;
10660 PADAPTER padapter = rtw_netdev_priv(dev);
10662 if (padapter == NULL)
10665 if (padapter->bup == _FALSE) {
10666 RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10670 if (RTW_CANNOT_RUN(padapter)) {
10671 RTW_INFO("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__);
10675 if (extra == NULL) {
10680 if (subcmd < MP_NULL) {
10681 rtw_priv_mp_set(dev, info, wdata, extra);
10686 #ifdef CONFIG_WOWLAN
10687 case MP_WOW_ENABLE:
10688 RTW_INFO("set case MP_WOW_ENABLE: %s\n", extra);
10690 rtw_wowlan_ctrl(dev, info, wdata, extra);
10692 case MP_WOW_SET_PATTERN:
10693 RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra);
10694 rtw_wowlan_set_pattern(dev, info, wdata, extra);
10697 #ifdef CONFIG_AP_WOWLAN
10698 case MP_AP_WOW_ENABLE:
10699 RTW_INFO("set case MP_AP_WOW_ENABLE: %s\n", extra);
10700 rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
10703 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10704 case VENDOR_IE_SET:
10705 RTW_INFO("set case VENDOR_IE_SET\n");
10706 rtw_vendor_ie_set(dev , info , wdata , extra);
10717 static int rtw_priv_get(struct net_device *dev,
10718 struct iw_request_info *info,
10719 union iwreq_data *wdata, char *extra)
10721 struct iw_point *wrqu = (struct iw_point *)wdata;
10722 u32 subcmd = wrqu->flags;
10723 PADAPTER padapter = rtw_netdev_priv(dev);
10726 if (padapter == NULL)
10729 if (padapter->bup == _FALSE) {
10730 RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10734 if (RTW_CANNOT_RUN(padapter)) {
10735 RTW_INFO("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__);
10739 if (extra == NULL) {
10744 if (subcmd < MP_NULL) {
10745 rtw_priv_mp_get(dev, info, wdata, extra);
10750 #if defined(CONFIG_RTL8723B)
10752 RTW_INFO("set MP_SetBT\n");
10753 rtw_mp_SetBT(dev, info, wdata, extra);
10756 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
10758 rtw_mp_sd_iread(dev, info, wrqu, extra);
10761 rtw_mp_sd_iwrite(dev, info, wrqu, extra);
10764 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10765 case VENDOR_IE_GET:
10766 RTW_INFO("get case VENDOR_IE_GET\n");
10767 rtw_vendor_ie_get(dev , info , wdata , extra);
10774 rtw_msleep_os(10); /* delay 5ms for sending pkt before exit adb shell operation */
10780 static int rtw_wx_tdls_wfd_enable(struct net_device *dev,
10781 struct iw_request_info *info,
10782 union iwreq_data *wrqu, char *extra)
10789 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10791 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10793 if (extra[0] == '0')
10794 rtw_tdls_wfd_enable(padapter, 0);
10796 rtw_tdls_wfd_enable(padapter, 1);
10798 #endif /* CONFIG_WFD */
10799 #endif /* CONFIG_TDLS */
10804 static int rtw_tdls_weaksec(struct net_device *dev,
10805 struct iw_request_info *info,
10806 union iwreq_data *wrqu, char *extra)
10813 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10815 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10817 if (extra[0] == '0')
10818 padapter->wdinfo.wfd_tdls_weaksec = 0;
10820 padapter->wdinfo.wfd_tdls_weaksec = 1;
10822 #endif /* CONFIG_TDLS */
10828 static int rtw_tdls_enable(struct net_device *dev,
10829 struct iw_request_info *info,
10830 union iwreq_data *wrqu, char *extra)
10836 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10837 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10839 _list *plist, *phead;
10841 struct sta_info *psta = NULL;
10842 struct sta_priv *pstapriv = &padapter->stapriv;
10843 u8 tdls_sta[NUM_STA][ETH_ALEN];
10844 u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
10845 struct tdls_txmgmt txmgmt;
10847 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10849 _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta));
10850 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10852 if (extra[0] == '0') {
10853 ptdlsinfo->tdls_enable = 0;
10855 if (pstapriv->asoc_sta_count == 1)
10858 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
10859 for (index = 0; index < NUM_STA; index++) {
10860 phead = &(pstapriv->sta_hash[index]);
10861 plist = get_next(phead);
10863 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
10864 psta = LIST_CONTAINOR(plist, struct sta_info , hash_list);
10866 plist = get_next(plist);
10868 if (psta->tdls_sta_state != TDLS_STATE_NONE)
10869 _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN);
10872 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
10874 for (index = 0; index < NUM_STA; index++) {
10875 if (!_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN)) {
10876 RTW_INFO("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index]));
10877 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
10878 _rtw_memcpy(txmgmt.peer, tdls_sta[index], ETH_ALEN);
10879 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
10882 rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR);
10883 rtw_reset_tdls_info(padapter);
10884 } else if (extra[0] == '1')
10885 ptdlsinfo->tdls_enable = 1;
10886 #endif /* CONFIG_TDLS */
10891 static int rtw_tdls_setup(struct net_device *dev,
10892 struct iw_request_info *info,
10893 union iwreq_data *wrqu, char *extra)
10898 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10899 struct tdls_txmgmt txmgmt;
10901 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
10902 #endif /* CONFIG_WFD */
10904 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10906 if (wrqu->data.length - 1 != 17) {
10907 RTW_INFO("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length - 1));
10911 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10912 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10913 txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10916 if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
10917 /* Weak Security situation with AP. */
10918 if (0 == pwdinfo->wfd_tdls_weaksec) {
10919 /* Can't send the tdls setup request out!! */
10920 RTW_INFO("[%s] Current link is not AES, "
10921 "SKIP sending the tdls setup request!!\n", __FUNCTION__);
10923 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10925 #endif /* CONFIG_WFD */
10927 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10929 #endif /* CONFIG_TDLS */
10934 static int rtw_tdls_teardown(struct net_device *dev,
10935 struct iw_request_info *info,
10936 union iwreq_data *wrqu, char *extra)
10943 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10944 struct sta_info *ptdls_sta = NULL;
10945 struct tdls_txmgmt txmgmt;
10947 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10949 if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) {
10950 RTW_INFO("[%s] length:%d != 17 or 19\n",
10951 __FUNCTION__, (wrqu->data.length - 1));
10955 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10956 for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
10957 txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10959 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
10961 if (ptdls_sta != NULL) {
10962 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
10963 if (wrqu->data.length - 1 == 19)
10964 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
10966 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
10968 RTW_INFO("TDLS peer not found\n");
10969 #endif /* CONFIG_TDLS */
10974 static int rtw_tdls_discovery(struct net_device *dev,
10975 struct iw_request_info *info,
10976 union iwreq_data *wrqu, char *extra)
10982 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10983 struct tdls_txmgmt txmgmt;
10986 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10988 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10989 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10990 txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10992 issue_tdls_dis_req(padapter, &txmgmt);
10994 #endif /* CONFIG_TDLS */
10999 static int rtw_tdls_ch_switch(struct net_device *dev,
11000 struct iw_request_info *info,
11001 union iwreq_data *wrqu, char *extra)
11006 #ifdef CONFIG_TDLS_CH_SW
11007 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11008 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
11010 struct sta_info *ptdls_sta = NULL;
11013 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11015 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
11016 RTW_INFO("TDLS channel switch is not allowed\n");
11020 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
11021 pchsw_info->addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11023 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr);
11024 if (ptdls_sta == NULL)
11027 pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE;
11029 if (ptdls_sta != NULL) {
11030 if (pchsw_info->off_ch_num == 0)
11031 pchsw_info->off_ch_num = 11;
11033 RTW_INFO("TDLS peer not found\n");
11035 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
11037 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
11038 if (take_care_iqk == _TRUE) {
11042 bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
11043 central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
11044 if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) >= 0)
11045 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
11047 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_PREPARE);
11049 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
11051 /* issue_tdls_ch_switch_req(padapter, ptdls_sta); */
11052 /* RTW_INFO("issue tdls ch switch req\n"); */
11054 #endif /* CONFIG_TDLS_CH_SW */
11055 #endif /* CONFIG_TDLS */
11060 static int rtw_tdls_ch_switch_off(struct net_device *dev,
11061 struct iw_request_info *info,
11062 union iwreq_data *wrqu, char *extra)
11067 #ifdef CONFIG_TDLS_CH_SW
11069 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11070 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
11071 u8 i, j, mac_addr[ETH_ALEN];
11072 struct sta_info *ptdls_sta = NULL;
11073 struct tdls_txmgmt txmgmt;
11075 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
11077 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11079 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
11080 RTW_INFO("TDLS channel switch is not allowed\n");
11084 if (wrqu->data.length >= 17) {
11085 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
11086 mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11087 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11090 if (ptdls_sta == NULL)
11093 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
11095 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
11096 TDLS_CH_SWITCH_ON_STATE |
11097 TDLS_PEER_AT_OFF_STATE);
11098 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
11100 ptdls_sta->ch_switch_time = 0;
11101 ptdls_sta->ch_switch_timeout = 0;
11102 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
11103 _cancel_timer_ex(&ptdls_sta->delay_timer);
11104 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
11105 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
11107 rtw_pm_set_lps(padapter, PS_MODE_MAX);
11108 #endif /* CONFIG_TDLS_CH_SW */
11109 #endif /* CONFIG_TDLS */
11114 static int rtw_tdls_dump_ch(struct net_device *dev,
11115 struct iw_request_info *info,
11116 union iwreq_data *wrqu, char *extra)
11121 #ifdef CONFIG_TDLS_CH_SW
11122 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11123 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11125 RTW_INFO("[%s] dump_stack:%s\n", __FUNCTION__, extra);
11127 extra[wrqu->data.length] = 0x00;
11128 ptdlsinfo->chsw_info.dump_stack = rtw_atoi(extra);
11133 #endif /* CONFIG_TDLS */
11138 static int rtw_tdls_off_ch_num(struct net_device *dev,
11139 struct iw_request_info *info,
11140 union iwreq_data *wrqu, char *extra)
11145 #ifdef CONFIG_TDLS_CH_SW
11146 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11147 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11149 RTW_INFO("[%s] off_ch_num:%s\n", __FUNCTION__, extra);
11151 extra[wrqu->data.length] = 0x00;
11152 ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra);
11157 #endif /* CONFIG_TDLS */
11162 static int rtw_tdls_ch_offset(struct net_device *dev,
11163 struct iw_request_info *info,
11164 union iwreq_data *wrqu, char *extra)
11169 #ifdef CONFIG_TDLS_CH_SW
11170 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11171 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11173 RTW_INFO("[%s] ch_offset:%s\n", __FUNCTION__, extra);
11175 extra[wrqu->data.length] = 0x00;
11176 switch (rtw_atoi(extra)) {
11178 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11182 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11186 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11193 #endif /* CONFIG_TDLS */
11198 static int rtw_tdls_pson(struct net_device *dev,
11199 struct iw_request_info *info,
11200 union iwreq_data *wrqu, char *extra)
11206 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11207 u8 i, j, mac_addr[ETH_ALEN];
11208 struct sta_info *ptdls_sta = NULL;
11210 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11212 for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
11213 mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11215 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11217 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 3, 500);
11219 #endif /* CONFIG_TDLS */
11224 static int rtw_tdls_psoff(struct net_device *dev,
11225 struct iw_request_info *info,
11226 union iwreq_data *wrqu, char *extra)
11232 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11233 u8 i, j, mac_addr[ETH_ALEN];
11234 struct sta_info *ptdls_sta = NULL;
11236 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11238 for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
11239 mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
11241 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11244 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 3, 500);
11246 #endif /* CONFIG_TDLS */
11251 static int rtw_tdls_setip(struct net_device *dev,
11252 struct iw_request_info *info,
11253 union iwreq_data *wrqu, char *extra)
11260 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11261 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11262 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11263 u8 i = 0, j = 0, k = 0, tag = 0;
11265 RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11268 for (j = 0; j < 4; j++) {
11269 if (*(extra + j + tag) == '.' || *(extra + j + tag) == '\0') {
11271 pwfd_info->ip_address[i] = convert_ip_addr('0', '0', *(extra + (j - 1) + tag));
11273 pwfd_info->ip_address[i] = convert_ip_addr('0', *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
11275 pwfd_info->ip_address[i] = convert_ip_addr(*(extra + (j - 3) + tag), *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
11284 RTW_INFO("[%s] Set IP = %u.%u.%u.%u\n", __FUNCTION__,
11285 ptdlsinfo->wfd_info->ip_address[0],
11286 ptdlsinfo->wfd_info->ip_address[1],
11287 ptdlsinfo->wfd_info->ip_address[2],
11288 ptdlsinfo->wfd_info->ip_address[3]);
11290 #endif /* CONFIG_WFD */
11291 #endif /* CONFIG_TDLS */
11296 static int rtw_tdls_getip(struct net_device *dev,
11297 struct iw_request_info *info,
11298 union iwreq_data *wrqu, char *extra)
11305 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11306 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11307 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11309 RTW_INFO("[%s]\n", __FUNCTION__);
11311 sprintf(extra, "\n\n%u.%u.%u.%u\n",
11312 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11313 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11315 RTW_INFO("[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
11316 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11317 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11319 wrqu->data.length = strlen(extra);
11321 #endif /* CONFIG_WFD */
11322 #endif /* CONFIG_TDLS */
11327 static int rtw_tdls_getport(struct net_device *dev,
11328 struct iw_request_info *info,
11329 union iwreq_data *wrqu, char *extra)
11337 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11338 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11339 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11341 RTW_INFO("[%s]\n", __FUNCTION__);
11343 sprintf(extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport);
11344 RTW_INFO("[%s] remote port = %d\n",
11345 __FUNCTION__, pwfd_info->peer_rtsp_ctrlport);
11347 wrqu->data.length = strlen(extra);
11349 #endif /* CONFIG_WFD */
11350 #endif /* CONFIG_TDLS */
11356 /* WFDTDLS, for sigma test */
11357 static int rtw_tdls_dis_result(struct net_device *dev,
11358 struct iw_request_info *info,
11359 union iwreq_data *wrqu, char *extra)
11367 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11368 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11370 RTW_INFO("[%s]\n", __FUNCTION__);
11372 if (ptdlsinfo->dev_discovered == _TRUE) {
11373 sprintf(extra, "\n\nDis=1\n");
11374 ptdlsinfo->dev_discovered = _FALSE;
11377 wrqu->data.length = strlen(extra);
11379 #endif /* CONFIG_WFD */
11380 #endif /* CONFIG_TDLS */
11386 /* WFDTDLS, for sigma test */
11387 static int rtw_wfd_tdls_status(struct net_device *dev,
11388 struct iw_request_info *info,
11389 union iwreq_data *wrqu, char *extra)
11396 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11397 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11399 RTW_INFO("[%s]\n", __FUNCTION__);
11401 sprintf(extra, "\nlink_established:%d\n"
11406 #ifdef CONFIG_TDLS_CH_SW
11407 "ch_sw_state:%08x\n"
11412 "delay_swtich_back:%d"
11415 ptdlsinfo->link_established, ptdlsinfo->sta_cnt,
11416 ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel,
11417 ptdlsinfo->tdls_enable
11418 #ifdef CONFIG_TDLS_CH_SW
11420 ptdlsinfo->chsw_info.ch_sw_state,
11421 ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on),
11422 ptdlsinfo->chsw_info.off_ch_num,
11423 ptdlsinfo->chsw_info.cur_time,
11424 ptdlsinfo->chsw_info.ch_offset,
11425 ptdlsinfo->chsw_info.delay_switch_back
11429 wrqu->data.length = strlen(extra);
11431 #endif /* CONFIG_TDLS */
11437 static int rtw_tdls_getsta(struct net_device *dev,
11438 struct iw_request_info *info,
11439 union iwreq_data *wrqu, char *extra)
11445 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11446 u8 addr[ETH_ALEN] = {0};
11448 struct sta_info *ptdls_sta = NULL;
11450 RTW_INFO("[%s] %s %d\n", __FUNCTION__,
11451 (char *)wrqu->data.pointer, wrqu->data.length - 1);
11453 if (copy_from_user(charmac, wrqu->data.pointer + 9, 17)) {
11458 RTW_INFO("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
11459 for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
11460 addr[i] = key_2char2num(*(charmac + j), *(charmac + j + 1));
11462 RTW_INFO("[%s] %d, charmac:%s, addr:"MAC_FMT"\n",
11463 __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
11464 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);
11466 sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state);
11467 RTW_INFO("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
11469 sprintf(extra, "\n\nNot found this sta\n");
11470 RTW_INFO("\n\nNot found this sta\n");
11472 wrqu->data.length = strlen(extra);
11474 #endif /* CONFIG_TDLS */
11480 static int rtw_tdls_get_best_ch(struct net_device *dev,
11481 struct iw_request_info *info,
11482 union iwreq_data *wrqu, char *extra)
11484 #ifdef CONFIG_FIND_BEST_CHANNEL
11485 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11486 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11487 u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
11489 for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
11490 if (pmlmeext->channel_set[i].ChannelNum == 1)
11492 if (pmlmeext->channel_set[i].ChannelNum == 36)
11496 for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
11498 if (pmlmeext->channel_set[i].ChannelNum == 6 || pmlmeext->channel_set[i].ChannelNum == 11) {
11499 if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) {
11501 best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
11506 if (pmlmeext->channel_set[i].ChannelNum >= 36
11507 && pmlmeext->channel_set[i].ChannelNum < 140) {
11508 /* Find primary channel */
11509 if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0)
11510 && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
11512 best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
11516 if (pmlmeext->channel_set[i].ChannelNum >= 149
11517 && pmlmeext->channel_set[i].ChannelNum < 165) {
11518 /* Find primary channel */
11519 if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0)
11520 && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
11522 best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
11526 RTW_INFO("The rx cnt of channel %3d = %d\n",
11527 pmlmeext->channel_set[i].ChannelNum,
11528 pmlmeext->channel_set[i].rx_count);
11532 sprintf(extra, "\nbest_channel_24G = %d\n", best_channel_24G);
11533 RTW_INFO("best_channel_24G = %d\n", best_channel_24G);
11535 if (index_5G != 0) {
11536 sprintf(extra, "best_channel_5G = %d\n", best_channel_5G);
11537 RTW_INFO("best_channel_5G = %d\n", best_channel_5G);
11540 wrqu->data.length = strlen(extra);
11548 static int rtw_tdls(struct net_device *dev,
11549 struct iw_request_info *info,
11550 union iwreq_data *wrqu, char *extra)
11556 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11558 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
11560 if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
11561 RTW_INFO("Discard tdls oper since hal doesn't support tdls\n");
11565 if (padapter->tdlsinfo.tdls_enable == 0) {
11566 RTW_INFO("tdls haven't enabled\n");
11570 /* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */
11572 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11573 if (_rtw_memcmp(extra, "wfdenable=", 10)) {
11574 wrqu->data.length -= 10;
11575 rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]);
11580 if (_rtw_memcmp(extra, "weaksec=", 8)) {
11581 wrqu->data.length -= 8;
11582 rtw_tdls_weaksec(dev, info, wrqu, &extra[8]);
11584 } else if (_rtw_memcmp(extra, "tdlsenable=", 11)) {
11585 wrqu->data.length -= 11;
11586 rtw_tdls_enable(dev, info, wrqu, &extra[11]);
11590 if (_rtw_memcmp(extra, "setup=", 6)) {
11591 wrqu->data.length -= 6;
11592 rtw_tdls_setup(dev, info, wrqu, &extra[6]);
11593 } else if (_rtw_memcmp(extra, "tear=", 5)) {
11594 wrqu->data.length -= 5;
11595 rtw_tdls_teardown(dev, info, wrqu, &extra[5]);
11596 } else if (_rtw_memcmp(extra, "dis=", 4)) {
11597 wrqu->data.length -= 4;
11598 rtw_tdls_discovery(dev, info, wrqu, &extra[4]);
11599 } else if (_rtw_memcmp(extra, "swoff=", 6)) {
11600 wrqu->data.length -= 6;
11601 rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]);
11602 } else if (_rtw_memcmp(extra, "sw=", 3)) {
11603 wrqu->data.length -= 3;
11604 rtw_tdls_ch_switch(dev, info, wrqu, &extra[3]);
11605 } else if (_rtw_memcmp(extra, "dumpstack=", 10)) {
11606 wrqu->data.length -= 10;
11607 rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]);
11608 } else if (_rtw_memcmp(extra, "offchnum=", 9)) {
11609 wrqu->data.length -= 9;
11610 rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]);
11611 } else if (_rtw_memcmp(extra, "choffset=", 9)) {
11612 wrqu->data.length -= 9;
11613 rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]);
11614 } else if (_rtw_memcmp(extra, "pson=", 5)) {
11615 wrqu->data.length -= 5;
11616 rtw_tdls_pson(dev, info, wrqu, &extra[5]);
11617 } else if (_rtw_memcmp(extra, "psoff=", 6)) {
11618 wrqu->data.length -= 6;
11619 rtw_tdls_psoff(dev, info, wrqu, &extra[6]);
11623 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11624 if (_rtw_memcmp(extra, "setip=", 6)) {
11625 wrqu->data.length -= 6;
11626 rtw_tdls_setip(dev, info, wrqu, &extra[6]);
11627 } else if (_rtw_memcmp(extra, "tprobe=", 6))
11628 issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
11630 #endif /* CONFIG_WFD */
11632 #endif /* CONFIG_TDLS */
11638 static int rtw_tdls_get(struct net_device *dev,
11639 struct iw_request_info *info,
11640 union iwreq_data *wrqu, char *extra)
11646 RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
11648 if (_rtw_memcmp(wrqu->data.pointer, "ip", 2))
11649 rtw_tdls_getip(dev, info, wrqu, extra);
11650 else if (_rtw_memcmp(wrqu->data.pointer, "port", 4))
11651 rtw_tdls_getport(dev, info, wrqu, extra);
11652 /* WFDTDLS, for sigma test */
11653 else if (_rtw_memcmp(wrqu->data.pointer, "dis", 3))
11654 rtw_tdls_dis_result(dev, info, wrqu, extra);
11655 else if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
11656 rtw_wfd_tdls_status(dev, info, wrqu, extra);
11657 else if (_rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9))
11658 rtw_tdls_getsta(dev, info, wrqu, extra);
11659 else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7))
11660 rtw_tdls_get_best_ch(dev, info, wrqu, extra);
11661 #endif /* CONFIG_TDLS */
11670 #ifdef CONFIG_INTEL_WIDI
11671 static int rtw_widi_set(struct net_device *dev,
11672 struct iw_request_info *info,
11673 union iwreq_data *wrqu, char *extra)
11676 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11678 process_intel_widi_cmd(padapter, extra);
11683 static int rtw_widi_set_probe_request(struct net_device *dev,
11684 struct iw_request_info *info,
11685 union iwreq_data *wrqu, char *extra)
11689 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11691 pbuf = rtw_malloc(sizeof(l2_msg_t));
11693 if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length))
11695 /* _rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length); */
11697 if (wrqu->data.flags == 0)
11698 intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t));
11699 else if (wrqu->data.flags == 1)
11700 rtw_set_wfd_rds_sink_info(padapter, (l2_msg_t *)pbuf);
11704 #endif /* CONFIG_INTEL_WIDI */
11706 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
11708 #if defined(CONFIG_RTL8188E)
11709 #include <rtl8188e_hal.h>
11710 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11711 #define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum
11712 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11713 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11714 #define fill_default_txdesc rtl8188es_fill_default_txdesc
11715 #endif /* CONFIG_SDIO_HCI */
11716 #endif /* CONFIG_RTL8188E */
11717 #if defined(CONFIG_RTL8723B)
11718 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11719 #define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum
11720 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11721 #define fill_default_txdesc rtl8723b_fill_default_txdesc
11722 #endif /* CONFIG_RTL8723B */
11724 #if defined(CONFIG_RTL8703B)
11725 /* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11726 #define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum
11727 /* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11728 #define fill_default_txdesc rtl8703b_fill_default_txdesc
11729 #endif /* CONFIG_RTL8703B */
11731 #if defined(CONFIG_RTL8723D)
11732 /* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11733 #define cal_txdesc_chksum rtl8723d_cal_txdesc_chksum
11734 /* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11735 #define fill_default_txdesc rtl8723d_fill_default_txdesc
11736 #endif /* CONFIG_RTL8723D */
11738 #if defined(CONFIG_RTL8192E)
11739 extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11740 #define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum
11741 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11742 extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11743 #define fill_default_txdesc rtl8192es_fill_default_txdesc
11744 #endif /* CONFIG_SDIO_HCI */
11745 #endif /* CONFIG_RTL8192E */
11747 static s32 initLoopback(PADAPTER padapter)
11749 PLOOPBACKDATA ploopback;
11752 if (padapter->ploopback == NULL) {
11753 ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
11754 if (ploopback == NULL)
11757 _rtw_init_sema(&ploopback->sema, 0);
11758 ploopback->bstop = _TRUE;
11759 ploopback->cnt = 0;
11760 ploopback->size = 300;
11761 _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
11763 padapter->ploopback = ploopback;
11769 static void freeLoopback(PADAPTER padapter)
11771 PLOOPBACKDATA ploopback;
11774 ploopback = padapter->ploopback;
11776 rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA));
11777 padapter->ploopback = NULL;
11781 static s32 initpseudoadhoc(PADAPTER padapter)
11783 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
11786 networkType = Ndis802_11IBSS;
11787 err = rtw_set_802_11_infrastructure_mode(padapter, networkType);
11791 err = rtw_setopmode_cmd(padapter, networkType, _TRUE);
11798 static s32 createpseudoadhoc(PADAPTER padapter)
11800 NDIS_802_11_AUTHENTICATION_MODE authmode;
11801 struct mlme_priv *pmlmepriv;
11802 NDIS_802_11_SSID *passoc_ssid;
11803 WLAN_BSSID_EX *pdev_network;
11805 u8 ssid[] = "pseduo_ad-hoc";
11810 pmlmepriv = &padapter->mlmepriv;
11812 authmode = Ndis802_11AuthModeOpen;
11813 err = rtw_set_802_11_authentication_mode(padapter, authmode);
11817 passoc_ssid = &pmlmepriv->assoc_ssid;
11818 _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
11819 passoc_ssid->SsidLength = sizeof(ssid) - 1;
11820 _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
11822 pdev_network = &padapter->registrypriv.dev_network;
11823 pibss = padapter->registrypriv.dev_network.MacAddress;
11824 _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
11826 rtw_update_registrypriv_dev_network(padapter);
11827 rtw_generate_random_ibss(pibss);
11829 _enter_critical_bh(&pmlmepriv->lock, &irqL);
11830 /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
11831 init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
11833 _exit_critical_bh(&pmlmepriv->lock, &irqL);
11836 err = rtw_create_ibss_cmd(padapter, 0);
11841 struct wlan_network *pcur_network;
11842 struct sta_info *psta;
11844 /* 3 create a new psta */
11845 pcur_network = &pmlmepriv->cur_network;
11847 /* clear psta in the cur_network, if any */
11848 psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
11850 rtw_free_stainfo(padapter, psta);
11852 psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
11856 /* 3 join psudo AdHoc */
11857 pcur_network->join_res = 1;
11858 pcur_network->aid = psta->aid = 1;
11859 _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
11861 /* set msr to WIFI_FW_ADHOC_STATE */
11862 padapter->hw_port = HW_PORT0;
11863 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11871 static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size)
11873 struct xmit_priv *pxmitpriv;
11874 struct xmit_frame *pframe;
11875 struct xmit_buf *pxmitbuf;
11876 struct pkt_attrib *pattrib;
11877 struct tx_desc *desc;
11878 u8 *pkt_start, *pkt_end, *ptr;
11879 struct rtw_ieee80211_hdr *hdr;
11884 if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ)
11887 pxmitpriv = &padapter->xmitpriv;
11890 /* 2 1. allocate xmit frame */
11891 pframe = rtw_alloc_xmitframe(pxmitpriv);
11892 if (pframe == NULL)
11894 pframe->padapter = padapter;
11896 /* 2 2. allocate xmit buffer */
11897 _enter_critical_bh(&pxmitpriv->lock, &irqL);
11898 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
11899 _exit_critical_bh(&pxmitpriv->lock, &irqL);
11900 if (pxmitbuf == NULL) {
11901 rtw_free_xmitframe(pxmitpriv, pframe);
11905 pframe->pxmitbuf = pxmitbuf;
11906 pframe->buf_addr = pxmitbuf->pbuf;
11907 pxmitbuf->priv_data = pframe;
11909 /* 2 3. update_attrib() */
11910 pattrib = &pframe->attrib;
11912 /* init xmitframe attribute */
11913 _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
11915 pattrib->ether_type = 0x8723;
11916 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
11917 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
11918 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11919 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
11921 /* pattrib->dhcp_pkt = 0;
11922 * pattrib->pktlen = 0; */
11923 pattrib->ack_policy = 0;
11924 /* pattrib->pkt_hdrlen = ETH_HLEN; */
11925 pattrib->hdrlen = WLAN_HDR_A3_LEN;
11926 pattrib->subtype = WIFI_DATA;
11927 pattrib->priority = 0;
11928 pattrib->qsel = pattrib->priority;
11929 /* do_queue_select(padapter, pattrib); */
11930 pattrib->nr_frags = 1;
11931 pattrib->encrypt = 0;
11932 pattrib->bswenc = _FALSE;
11933 pattrib->qos_en = _FALSE;
11935 bmcast = IS_MCAST(pattrib->ra);
11937 pattrib->mac_id = 1;
11938 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
11940 pattrib->mac_id = 0;
11941 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
11944 pattrib->pktlen = size;
11945 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
11947 /* 2 4. fill TX descriptor */
11948 desc = (struct tx_desc *)pframe->buf_addr;
11949 _rtw_memset(desc, 0, TXDESC_SIZE);
11951 fill_default_txdesc(pframe, (u8 *)desc);
11953 /* Hw set sequence number */
11954 ((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable
11955 * ((PTXDESC)desc)->hwseq_sel = 0; */ /* HWSEQ_SEL */
11957 ((PTXDESC)desc)->disdatafb = 1;
11959 /* convert to little endian */
11960 desc->txdw0 = cpu_to_le32(desc->txdw0);
11961 desc->txdw1 = cpu_to_le32(desc->txdw1);
11962 desc->txdw2 = cpu_to_le32(desc->txdw2);
11963 desc->txdw3 = cpu_to_le32(desc->txdw3);
11964 desc->txdw4 = cpu_to_le32(desc->txdw4);
11965 desc->txdw5 = cpu_to_le32(desc->txdw5);
11966 desc->txdw6 = cpu_to_le32(desc->txdw6);
11967 desc->txdw7 = cpu_to_le32(desc->txdw7);
11968 #ifdef CONFIG_PCI_HCI
11969 desc->txdw8 = cpu_to_le32(desc->txdw8);
11970 desc->txdw9 = cpu_to_le32(desc->txdw9);
11971 desc->txdw10 = cpu_to_le32(desc->txdw10);
11972 desc->txdw11 = cpu_to_le32(desc->txdw11);
11973 desc->txdw12 = cpu_to_le32(desc->txdw12);
11974 desc->txdw13 = cpu_to_le32(desc->txdw13);
11975 desc->txdw14 = cpu_to_le32(desc->txdw14);
11976 desc->txdw15 = cpu_to_le32(desc->txdw15);
11979 cal_txdesc_chksum(desc);
11981 /* 2 5. coalesce */
11982 pkt_start = pframe->buf_addr + TXDESC_SIZE;
11983 pkt_end = pkt_start + pattrib->last_txcmdsz;
11985 /* 3 5.1. make wlan header, make_wlanhdr() */
11986 hdr = (struct rtw_ieee80211_hdr *)pkt_start;
11987 SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
11988 _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */
11989 _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */
11990 _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */
11992 /* 3 5.2. make payload */
11993 ptr = pkt_start + pattrib->hdrlen;
11994 get_random_bytes(ptr, pkt_end - ptr);
11996 pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
11997 pxmitbuf->ptail += pxmitbuf->len;
12002 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
12004 struct xmit_priv *pxmitpriv;
12005 struct xmit_buf *pxmitbuf;
12008 pxmitpriv = &padapter->xmitpriv;
12009 pxmitbuf = pframe->pxmitbuf;
12011 rtw_free_xmitframe(pxmitpriv, pframe);
12012 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
12015 static void printdata(u8 *pbuf, u32 len)
12020 for (i = 0; (i + 4) <= len; i += 4) {
12021 printk("%08X", *(u32 *)(pbuf + i));
12022 if ((i + 4) & 0x1F)
12029 #ifdef CONFIG_BIG_ENDIAN
12030 for (; i < len, i++)
12031 printk("%02X", pbuf + i);
12032 #else /* CONFIG_LITTLE_ENDIAN */
12035 _rtw_memcpy(&val, pbuf + i, len - i);
12036 printk("%8X", val);
12042 _rtw_memcpy(&val, pbuf + i, n);
12043 sprintf(str, "%08X", val);
12045 printk("%8s", str + n);
12047 #endif /* CONFIG_LITTLE_ENDIAN */
12052 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
12054 PHAL_DATA_TYPE phal;
12055 struct recv_stat *prxstat;
12056 struct recv_stat report;
12057 PRXREPORT prxreport;
12063 prxstat = (struct recv_stat *)rxbuf;
12064 report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
12065 report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
12066 report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
12067 report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
12068 report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
12069 report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
12071 prxreport = (PRXREPORT)&report;
12072 drvinfosize = prxreport->drvinfosize << 3;
12073 rxpktsize = prxreport->pktlen;
12075 phal = GET_HAL_DATA(padapter);
12076 if (phal->ReceiveConfig & RCR_APPFCS)
12077 fcssize = IEEE80211_FCS_LEN;
12081 if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
12082 RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n",
12083 __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
12086 ret = _rtw_memcmp(txbuf + TXDESC_SIZE, \
12087 rxbuf + RXDESC_SIZE + drvinfosize, \
12088 txsz - TXDESC_SIZE);
12090 RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__);
12093 if (ret == _FALSE) {
12094 RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
12095 __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
12096 RTW_INFO("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
12097 printdata(txbuf, TXDESC_SIZE);
12098 RTW_INFO("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
12099 printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
12101 RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
12102 __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
12103 if (rxpktsize != 0) {
12104 RTW_INFO("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
12105 printdata(rxbuf, RXDESC_SIZE);
12106 RTW_INFO("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
12107 printdata(rxbuf + RXDESC_SIZE, drvinfosize);
12108 RTW_INFO("%s: RX content size=%d\n", __func__, rxpktsize);
12109 printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
12111 RTW_INFO("%s: RX data size=%d\n", __func__, rxsz);
12112 printdata(rxbuf, rxsz);
12119 thread_return lbk_thread(thread_context context)
12123 PLOOPBACKDATA ploopback;
12124 struct xmit_frame *pxmitframe;
12125 u32 cnt, ok, fail, headerlen;
12130 padapter = (PADAPTER)context;
12131 ploopback = padapter->ploopback;
12132 if (ploopback == NULL)
12138 daemonize("%s", "RTW_LBK_THREAD");
12139 allow_signal(SIGTERM);
12142 if (ploopback->size == 0) {
12143 get_random_bytes(&pktsize, 4);
12144 pktsize = (pktsize % 1535) + 1; /* 1~1535 */
12146 pktsize = ploopback->size;
12148 pxmitframe = createloopbackpkt(padapter, pktsize);
12149 if (pxmitframe == NULL) {
12150 sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
12154 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
12155 _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
12156 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
12158 RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
12159 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
12160 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
12162 /* wait for rx pkt */
12163 _rtw_down_sema(&ploopback->sema);
12165 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
12171 ploopback->txsize = 0;
12172 _rtw_memset(ploopback->txbuf, 0, 0x8000);
12173 ploopback->rxsize = 0;
12174 _rtw_memset(ploopback->rxbuf, 0, 0x8000);
12176 freeloopbackpkt(padapter, pxmitframe);
12179 if (signal_pending(current))
12180 flush_signals(current);
12182 if ((ploopback->bstop == _TRUE) ||
12183 ((ploopback->cnt != 0) && (ploopback->cnt == cnt))) {
12184 u32 ok_rate, fail_rate, all;
12186 ok_rate = (ok * 100) / all;
12187 fail_rate = (fail * 100) / all;
12188 sprintf(ploopback->msg, \
12189 "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)", \
12190 ok_rate, ok, all, fail_rate, fail, all);
12195 ploopback->bstop = _TRUE;
12200 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg)
12202 PLOOPBACKDATA ploopback;
12207 ploopback = padapter->ploopback;
12210 if (ploopback->bstop == _FALSE) {
12211 ploopback->bstop = _TRUE;
12212 _rtw_up_sema(&ploopback->sema);
12216 len = strlen(ploopback->msg);
12221 _rtw_memcpy(pmsg, ploopback->msg, len + 1);
12222 freeLoopback(padapter);
12227 /* disable dynamic algorithm */
12228 rtw_phydm_ability_backup(padapter);
12229 rtw_phydm_func_disable_all(padapter);
12231 /* create pseudo ad-hoc connection */
12232 err = initpseudoadhoc(padapter);
12233 if (err == _FAIL) {
12234 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
12238 err = createpseudoadhoc(padapter);
12239 if (err == _FAIL) {
12240 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
12244 err = initLoopback(padapter);
12246 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
12250 ploopback = padapter->ploopback;
12252 ploopback->bstop = _FALSE;
12253 ploopback->cnt = cnt;
12254 ploopback->size = size;
12255 ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
12256 if (IS_ERR(padapter->lbkthread)) {
12257 freeLoopback(padapter);
12258 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
12262 sprintf(pmsg, "loopback start! cnt=%d", cnt);
12264 #endif /* CONFIG_MAC_LOOPBACK_DRIVER */
12266 static int rtw_test(
12267 struct net_device *dev,
12268 struct iw_request_info *info,
12269 union iwreq_data *wrqu, char *extra)
12275 PADAPTER padapter = rtw_netdev_priv(dev);
12278 RTW_INFO("+%s\n", __func__);
12279 len = wrqu->data.length;
12281 pbuf = (u8 *)rtw_zmalloc(len);
12282 if (pbuf == NULL) {
12283 RTW_INFO("%s: no memory!\n", __func__);
12287 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
12288 rtw_mfree(pbuf, len);
12289 RTW_INFO("%s: copy from user fail!\n", __func__);
12292 RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
12294 ptmp = (char *)pbuf;
12295 pch = strsep(&ptmp, delim);
12296 if ((pch == NULL) || (strlen(pch) == 0)) {
12297 rtw_mfree(pbuf, len);
12298 RTW_INFO("%s: parameter error(level 1)!\n", __func__);
12302 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
12303 if (strcmp(pch, "loopback") == 0) {
12307 pch = strsep(&ptmp, delim);
12308 if ((pch == NULL) || (strlen(pch) == 0)) {
12309 rtw_mfree(pbuf, len);
12310 RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12314 sscanf(pch, "%d", &cnt);
12315 RTW_INFO("%s: loopback cnt=%d\n", __func__, cnt);
12317 pch = strsep(&ptmp, delim);
12318 if ((pch == NULL) || (strlen(pch) == 0)) {
12319 rtw_mfree(pbuf, len);
12320 RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12324 sscanf(pch, "%d", &size);
12325 RTW_INFO("%s: loopback size=%d\n", __func__, size);
12327 loopbackTest(padapter, cnt, size, extra);
12328 wrqu->data.length = strlen(extra) + 1;
12335 #ifdef CONFIG_BT_COEXIST
12336 if (strcmp(pch, "bton") == 0) {
12337 rtw_btcoex_SetManualControl(padapter, _FALSE);
12339 } else if (strcmp(pch, "btoff") == 0) {
12340 rtw_btcoex_SetManualControl(padapter, _TRUE);
12345 if (strcmp(pch, "h2c") == 0) {
12354 pch = strsep(&ptmp, delim);
12355 if ((pch == NULL) || (strlen(pch) == 0))
12358 sscanf(pch, "%x", &tmp);
12359 param[count++] = (u8)tmp;
12360 } while (count < 8);
12363 rtw_mfree(pbuf, len);
12364 RTW_INFO("%s: parameter error(level 2)!\n", __func__);
12368 ret = rtw_test_h2c_cmd(padapter, param, count);
12370 pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
12371 for (i = 1; i < count; i++)
12372 pos += sprintf(extra + pos, "%02x,", param[i]);
12375 pos += sprintf(extra + pos, " %s", ret == _FAIL ? "FAIL" : "OK");
12377 wrqu->data.length = strlen(extra) + 1;
12383 rtw_mfree(pbuf, len);
12387 static iw_handler rtw_handlers[] = {
12388 NULL, /* SIOCSIWCOMMIT */
12389 rtw_wx_get_name, /* SIOCGIWNAME */
12390 dummy, /* SIOCSIWNWID */
12391 dummy, /* SIOCGIWNWID */
12392 rtw_wx_set_freq, /* SIOCSIWFREQ */
12393 rtw_wx_get_freq, /* SIOCGIWFREQ */
12394 rtw_wx_set_mode, /* SIOCSIWMODE */
12395 rtw_wx_get_mode, /* SIOCGIWMODE */
12396 dummy, /* SIOCSIWSENS */
12397 rtw_wx_get_sens, /* SIOCGIWSENS */
12398 NULL, /* SIOCSIWRANGE */
12399 rtw_wx_get_range, /* SIOCGIWRANGE */
12400 rtw_wx_set_priv, /* SIOCSIWPRIV */
12401 NULL, /* SIOCGIWPRIV */
12402 NULL, /* SIOCSIWSTATS */
12403 NULL, /* SIOCGIWSTATS */
12404 dummy, /* SIOCSIWSPY */
12405 dummy, /* SIOCGIWSPY */
12406 NULL, /* SIOCGIWTHRSPY */
12407 NULL, /* SIOCWIWTHRSPY */
12408 rtw_wx_set_wap, /* SIOCSIWAP */
12409 rtw_wx_get_wap, /* SIOCGIWAP */
12410 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */
12411 dummy, /* SIOCGIWAPLIST -- depricated */
12412 rtw_wx_set_scan, /* SIOCSIWSCAN */
12413 rtw_wx_get_scan, /* SIOCGIWSCAN */
12414 rtw_wx_set_essid, /* SIOCSIWESSID */
12415 rtw_wx_get_essid, /* SIOCGIWESSID */
12416 dummy, /* SIOCSIWNICKN */
12417 rtw_wx_get_nick, /* SIOCGIWNICKN */
12418 NULL, /* -- hole -- */
12419 NULL, /* -- hole -- */
12420 rtw_wx_set_rate, /* SIOCSIWRATE */
12421 rtw_wx_get_rate, /* SIOCGIWRATE */
12422 rtw_wx_set_rts, /* SIOCSIWRTS */
12423 rtw_wx_get_rts, /* SIOCGIWRTS */
12424 rtw_wx_set_frag, /* SIOCSIWFRAG */
12425 rtw_wx_get_frag, /* SIOCGIWFRAG */
12426 dummy, /* SIOCSIWTXPOW */
12427 dummy, /* SIOCGIWTXPOW */
12428 dummy, /* SIOCSIWRETRY */
12429 rtw_wx_get_retry, /* SIOCGIWRETRY */
12430 rtw_wx_set_enc, /* SIOCSIWENCODE */
12431 rtw_wx_get_enc, /* SIOCGIWENCODE */
12432 dummy, /* SIOCSIWPOWER */
12433 rtw_wx_get_power, /* SIOCGIWPOWER */
12434 NULL, /*---hole---*/
12435 NULL, /*---hole---*/
12436 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */
12437 NULL, /* SIOCGWGENIE */
12438 rtw_wx_set_auth, /* SIOCSIWAUTH */
12439 NULL, /* SIOCGIWAUTH */
12440 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
12441 NULL, /* SIOCGIWENCODEEXT */
12442 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */
12443 NULL, /*---hole---*/
12447 static const struct iw_priv_args rtw_private_args[] = {
12449 SIOCIWFIRSTPRIV + 0x0,
12450 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
12453 SIOCIWFIRSTPRIV + 0x1,
12454 IW_PRIV_TYPE_CHAR | 0x7FF,
12455 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
12458 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
12461 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
12464 SIOCIWFIRSTPRIV + 0x4,
12465 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
12468 SIOCIWFIRSTPRIV + 0x5,
12469 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
12472 SIOCIWFIRSTPRIV + 0x6,
12473 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
12475 /* for PLATFORM_MT53XX */
12477 SIOCIWFIRSTPRIV + 0x7,
12478 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
12481 SIOCIWFIRSTPRIV + 0x8,
12482 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
12485 SIOCIWFIRSTPRIV + 0x9,
12486 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
12489 /* for RTK_DMP_PLATFORM */
12491 SIOCIWFIRSTPRIV + 0xA,
12492 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
12496 SIOCIWFIRSTPRIV + 0xB,
12497 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
12500 SIOCIWFIRSTPRIV + 0xC,
12501 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
12504 SIOCIWFIRSTPRIV + 0xD,
12505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
12509 SIOCIWFIRSTPRIV + 0xE, 0, 0, "wowlan_ctrl"
12513 SIOCIWFIRSTPRIV + 0x10,
12514 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
12517 SIOCIWFIRSTPRIV + 0x11,
12518 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
12521 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
12524 SIOCIWFIRSTPRIV + 0x13,
12525 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
12528 SIOCIWFIRSTPRIV + 0x14,
12529 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
12532 SIOCIWFIRSTPRIV + 0x15,
12533 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
12536 SIOCIWFIRSTPRIV + 0x16,
12537 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
12540 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
12541 #ifdef CONFIG_MP_INCLUDED
12542 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
12543 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
12545 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
12546 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
12549 SIOCIWFIRSTPRIV + 0x1D,
12550 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
12553 #ifdef CONFIG_INTEL_WIDI
12555 SIOCIWFIRSTPRIV + 0x1E,
12556 IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
12559 SIOCIWFIRSTPRIV + 0x1F,
12560 IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
12562 #endif /* CONFIG_INTEL_WIDI */
12564 { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, /* set */
12565 { SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},/* get
12566 * --- sub-ioctls definitions --- */
12568 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
12569 { VENDOR_IE_SET, IW_PRIV_TYPE_CHAR | 1024 , 0 , "vendor_ie_set" },
12570 { VENDOR_IE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "vendor_ie_get" },
12572 #if defined(CONFIG_RTL8723B)
12573 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
12574 { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
12576 #ifdef CONFIG_WOWLAN
12577 { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
12578 { MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },
12580 #ifdef CONFIG_AP_WOWLAN
12581 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */
12583 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
12584 { MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },
12585 { MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },
12590 static const struct iw_priv_args rtw_mp_private_args[] = {
12591 /* --- sub-ioctls definitions --- */
12592 #ifdef CONFIG_MP_INCLUDED
12593 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" },
12594 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },
12595 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" },
12596 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },
12597 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"},
12598 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12599 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
12600 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"},
12601 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
12602 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12603 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
12604 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
12605 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
12606 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
12607 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
12608 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
12609 { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
12610 { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
12611 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
12612 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
12613 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
12614 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
12615 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
12616 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
12617 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
12618 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},
12619 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },
12620 { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
12621 { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
12622 { MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },
12623 { MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },
12624 { EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },
12625 { EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },
12626 { MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },
12627 { MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },
12628 { MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },
12629 { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
12630 #endif /* CONFIG_MP_INCLUDED */
12633 static iw_handler rtw_private_handler[] = {
12634 rtw_wx_write32, /* 0x00 */
12635 rtw_wx_read32, /* 0x01 */
12636 rtw_drvext_hdl, /* 0x02 */
12637 #ifdef MP_IOCTL_HDL
12638 rtw_mp_ioctl_hdl, /* 0x03 */
12642 /* for MM DTV platform */
12643 rtw_get_ap_info, /* 0x04 */
12645 rtw_set_pid, /* 0x05 */
12646 rtw_wps_start, /* 0x06 */
12648 /* for PLATFORM_MT53XX */
12649 rtw_wx_get_sensitivity, /* 0x07 */
12650 rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */
12651 rtw_wx_set_mtk_wps_ie, /* 0x09 */
12653 /* for RTK_DMP_PLATFORM
12654 * Set Channel depend on the country code */
12655 rtw_wx_set_channel_plan, /* 0x0A */
12657 rtw_dbg_port, /* 0x0B */
12658 rtw_wx_write_rf, /* 0x0C */
12659 rtw_wx_read_rf, /* 0x0D */
12661 rtw_priv_set, /*0x0E*/
12662 rtw_priv_get, /*0x0F*/
12664 rtw_p2p_set, /* 0x10 */
12665 rtw_p2p_get, /* 0x11 */
12667 rtw_p2p_get2, /* 0x13 */
12669 rtw_tdls, /* 0x14 */
12670 rtw_tdls_get, /* 0x15 */
12672 rtw_pm_set, /* 0x16 */
12673 rtw_wx_priv_null, /* 0x17 */
12674 rtw_rereg_nd_name, /* 0x18 */
12675 rtw_wx_priv_null, /* 0x19 */
12676 #ifdef CONFIG_MP_INCLUDED
12677 rtw_wx_priv_null, /* 0x1A */
12678 rtw_wx_priv_null, /* 0x1B */
12680 rtw_mp_efuse_set, /* 0x1A */
12681 rtw_mp_efuse_get, /* 0x1B */
12683 NULL, /* 0x1C is reserved for hostapd */
12684 rtw_test, /* 0x1D */
12685 #ifdef CONFIG_INTEL_WIDI
12686 rtw_widi_set, /* 0x1E */
12687 rtw_widi_set_probe_request, /* 0x1F */
12688 #endif /* CONFIG_INTEL_WIDI */
12691 #if WIRELESS_EXT >= 17
12692 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
12694 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12695 struct iw_statistics *piwstats = &padapter->iwstats;
12700 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE) {
12701 piwstats->qual.qual = 0;
12702 piwstats->qual.level = 0;
12703 piwstats->qual.noise = 0;
12704 /* RTW_INFO("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */
12706 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
12707 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
12709 #ifdef CONFIG_SIGNAL_SCALE_MAPPING
12710 tmp_level = padapter->recvpriv.signal_strength;
12713 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
12715 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
12717 tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength);
12722 tmp_qual = padapter->recvpriv.signal_qual;
12723 rtw_get_noise(padapter);
12724 tmp_noise = padapter->recvpriv.noise;
12725 /* RTW_INFO("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); */
12727 piwstats->qual.level = tmp_level;
12728 piwstats->qual.qual = tmp_qual;
12729 piwstats->qual.noise = tmp_noise;
12731 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14))
12732 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* |IW_QUAL_DBM; */
12734 #ifdef RTK_DMP_PLATFORM
12735 /* IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. */
12736 /* remove this flag for show percentage 0~100 */
12737 piwstats->qual.updated = 0x07;
12739 piwstats->qual.updated = 0x0f;
12743 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
12744 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
12747 return &padapter->iwstats;
12751 #ifdef CONFIG_WIRELESS_EXT
12752 struct iw_handler_def rtw_handlers_def = {
12753 .standard = rtw_handlers,
12754 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
12755 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) || defined(CONFIG_WEXT_PRIV)
12756 .private = rtw_private_handler,
12757 .private_args = (struct iw_priv_args *)rtw_private_args,
12758 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
12759 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
12761 #if WIRELESS_EXT >= 17
12762 .get_wireless_stats = rtw_get_wireless_stats,
12767 /* copy from net/wireless/wext.c start
12768 * ----------------------------------------------------------------
12770 * Calculate size of private arguments
12772 static const char iw_priv_type_size[] = {
12773 0, /* IW_PRIV_TYPE_NONE */
12774 1, /* IW_PRIV_TYPE_BYTE */
12775 1, /* IW_PRIV_TYPE_CHAR */
12776 0, /* Not defined */
12777 sizeof(__u32), /* IW_PRIV_TYPE_INT */
12778 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
12779 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
12780 0, /* Not defined */
12783 static int get_priv_size(__u16 args)
12785 int num = args & IW_PRIV_SIZE_MASK;
12786 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
12788 return num * iw_priv_type_size[type];
12790 /* copy from net/wireless/wext.c end */
12793 static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
12798 const char delim[] = " ";
12800 u32 output_len = 0;
12803 u32 buffer_len = 0;
12805 u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */
12809 u32 extra_size = 0;
12812 const iw_handler *priv; /* Private ioctl */
12813 const struct iw_priv_args *priv_args; /* Private ioctl description */
12814 const struct iw_priv_args *mp_priv_args; /*MP Private ioctl description */
12815 const struct iw_priv_args *sel_priv_args; /*Selected Private ioctl description */
12816 u32 num_priv; /* Number of ioctl */
12817 u32 num_priv_args; /* Number of descriptions */
12818 u32 num_mp_priv_args; /*Number of MP descriptions */
12819 u32 num_sel_priv_args; /*Number of Selected descriptions */
12820 iw_handler handler;
12822 int subcmd = 0; /* sub-ioctl index */
12823 int offset = 0; /* Space for sub-ioctl index */
12825 union iwreq_data wdata;
12827 _rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
12829 input_len = wdata.data.length;
12830 input = rtw_zmalloc(input_len);
12831 if (NULL == input || input_len == 0)
12833 if (copy_from_user(input, wdata.data.pointer, input_len)) {
12837 input[input_len - 1] = '\0';
12846 sscanf(ptr, "%16s", cmdname);
12847 cmdlen = strlen(cmdname);
12848 RTW_INFO("%s: cmd=%s\n", __func__, cmdname);
12850 /* skip command string */
12852 cmdlen += 1; /* skip one space */
12855 RTW_INFO("%s: parameters=%s\n", __func__, ptr);
12857 priv = rtw_private_handler;
12858 priv_args = rtw_private_args;
12859 mp_priv_args = rtw_mp_private_args;
12860 num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
12861 num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
12862 num_mp_priv_args = sizeof(rtw_mp_private_args) / sizeof(struct iw_priv_args);
12864 if (num_priv_args == 0) {
12869 /* Search the correct ioctl */
12871 sel_priv_args = priv_args;
12872 num_sel_priv_args = num_priv_args;
12874 ((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12877 /* If not found... */
12878 if (k == num_sel_priv_args) {
12880 sel_priv_args = mp_priv_args;
12881 num_sel_priv_args = num_mp_priv_args;
12883 ((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12886 if (k == num_sel_priv_args) {
12892 /* Watch out for sub-ioctls ! */
12893 if (sel_priv_args[k].cmd < SIOCDEVPRIVATE) {
12896 /* Find the matching *real* ioctl */
12897 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
12898 (priv_args[j].set_args != sel_priv_args[k].set_args) ||
12899 (priv_args[j].get_args != sel_priv_args[k].get_args)))
12902 /* If not found... */
12903 if (j == num_priv_args) {
12908 /* Save sub-ioctl number */
12909 subcmd = sel_priv_args[k].cmd;
12910 /* Reserve one int (simplify alignment issues) */
12911 offset = sizeof(__u32);
12912 /* Use real ioctl definition from now on */
12916 buffer = rtw_zmalloc(4096);
12917 if (NULL == buffer) {
12922 /* If we have to set some data */
12923 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
12924 (priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
12927 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
12928 case IW_PRIV_TYPE_BYTE:
12932 str = strsep(&ptr, delim);
12935 sscanf(str, "%i", &temp);
12936 buffer[count++] = (u8)temp;
12938 buffer_len = count;
12940 /* Number of args to fetch */
12941 wdata.data.length = count;
12942 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12943 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12947 case IW_PRIV_TYPE_INT:
12951 str = strsep(&ptr, delim);
12954 sscanf(str, "%i", &temp);
12955 ((s32 *)buffer)[count++] = (s32)temp;
12957 buffer_len = count * sizeof(s32);
12959 /* Number of args to fetch */
12960 wdata.data.length = count;
12961 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12962 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12966 case IW_PRIV_TYPE_CHAR:
12968 /* Size of the string to fetch */
12969 wdata.data.length = len;
12970 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12971 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12974 _rtw_memcpy(buffer, ptr, wdata.data.length);
12976 wdata.data.length = 1;
12979 buffer_len = wdata.data.length;
12983 RTW_INFO("%s: Not yet implemented...\n", __func__);
12988 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12989 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
12990 RTW_INFO("%s: The command %s needs exactly %d argument(s)...\n",
12991 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
12995 } /* if args to set */
12997 wdata.data.length = 0L;
12999 /* Those two tests are important. They define how the driver
13000 * will have to handle the data */
13001 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
13002 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
13003 /* First case : all SET args fit within wrq */
13005 wdata.mode = subcmd;
13006 _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
13008 if ((priv_args[k].set_args == 0) &&
13009 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
13010 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
13011 /* Second case : no SET args, GET args fit within wrq */
13013 wdata.mode = subcmd;
13015 /* Third case : args won't fit in wrq, or variable number of args */
13016 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
13020 wdata.data.flags = subcmd;
13024 rtw_mfree(input, input_len);
13028 if (IW_IS_SET(priv_args[k].cmd)) {
13029 /* Size of set arguments */
13030 extra_size = get_priv_size(priv_args[k].set_args);
13032 /* Does it fits in iwr ? */
13033 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
13034 ((extra_size + offset) <= IFNAMSIZ))
13037 /* Size of get arguments */
13038 extra_size = get_priv_size(priv_args[k].get_args);
13040 /* Does it fits in iwr ? */
13041 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
13042 (extra_size <= IFNAMSIZ))
13046 if (extra_size == 0) {
13047 extra = (u8 *)&wdata;
13048 rtw_mfree(buffer, 4096);
13053 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
13054 err = handler(dev, NULL, &wdata, extra);
13056 /* If we have to get some data */
13057 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
13058 (priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
13060 int n = 0; /* number of args */
13063 /* Check where is the returned data */
13064 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
13065 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
13066 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
13068 n = wdata.data.length;
13070 output = rtw_zmalloc(4096);
13071 if (NULL == output) {
13076 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
13077 case IW_PRIV_TYPE_BYTE:
13079 for (j = 0; j < n; j++) {
13080 sprintf(str, "%d ", extra[j]);
13082 output_len = strlen(output);
13083 if ((output_len + len + 1) > 4096) {
13087 _rtw_memcpy(output + output_len, str, len);
13091 case IW_PRIV_TYPE_INT:
13093 for (j = 0; j < n; j++) {
13094 sprintf(str, "%d ", ((__s32 *)extra)[j]);
13096 output_len = strlen(output);
13097 if ((output_len + len + 1) > 4096) {
13101 _rtw_memcpy(output + output_len, str, len);
13105 case IW_PRIV_TYPE_CHAR:
13107 _rtw_memcpy(output, extra, n);
13111 RTW_INFO("%s: Not yet implemented...\n", __func__);
13116 output_len = strlen(output) + 1;
13117 wrq_data->data.length = output_len;
13118 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
13122 } /* if args to set */
13124 wrq_data->data.length = 0;
13128 rtw_mfree(input, input_len);
13130 rtw_mfree(buffer, 4096);
13132 rtw_mfree(output, 4096);
13137 #ifdef CONFIG_COMPAT
13138 static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)
13140 struct compat_iw_point iwp_compat;
13141 union iwreq_data wrq_data;
13143 RTW_INFO("%s:...\n", __func__);
13144 if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))
13147 wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);
13148 wrq_data.data.length = iwp_compat.length;
13149 wrq_data.data.flags = iwp_compat.flags;
13151 err = _rtw_ioctl_wext_private(dev, &wrq_data);
13153 iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);
13154 iwp_compat.length = wrq_data.data.length;
13155 iwp_compat.flags = wrq_data.data.flags;
13156 if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))
13161 #endif /* CONFIG_COMPAT */
13163 static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)
13165 struct iw_point *iwp;
13167 union iwreq_data wrq_data;
13169 iwp = &wrq_data.data;
13170 RTW_INFO("%s:...\n", __func__);
13171 if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))
13174 err = _rtw_ioctl_wext_private(dev, &wrq_data);
13176 if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))
13182 static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq)
13184 #ifdef CONFIG_COMPAT
13185 if (is_compat_task())
13186 return rtw_ioctl_compat_wext_private(dev, rq);
13188 #endif /* CONFIG_COMPAT */
13189 return rtw_ioctl_standard_wext_private(dev, rq);
13192 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
13194 struct iwreq *wrq = (struct iwreq *)rq;
13198 case RTL_IOCTL_WPA_SUPPLICANT:
13199 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
13201 #ifdef CONFIG_AP_MODE
13202 case RTL_IOCTL_HOSTAPD:
13203 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
13205 #ifdef CONFIG_WIRELESS_EXT
13207 ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
13210 #endif /* CONFIG_AP_MODE */
13211 case SIOCDEVPRIVATE:
13212 ret = rtw_ioctl_wext_private(dev, rq);
13214 case (SIOCDEVPRIVATE+1):
13215 ret = rtw_android_priv_cmd(dev, rq, cmd);