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};
69 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 DBG_871X("%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 DBG_871X("%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 DBG_871X("%s\n", __FUNCTION__);
177 #ifndef CONFIG_IOCTL_CFG80211
178 wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
183 rtw_mfree(buff, IW_CUSTOM_MAX);
188 #ifdef CONFIG_SUPPORT_HW_WPS_PBC
189 void rtw_request_wps_pbc_event(_adapter *padapter)
191 #ifdef RTK_DMP_PLATFORM
192 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
193 kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
195 kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
199 if ( padapter->pid[0] == 0 )
200 { // 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver.
204 rtw_signal_process(padapter->pid[0], SIGUSR1);
208 rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
210 #endif//#ifdef CONFIG_SUPPORT_HW_WPS_PBC
212 void indicate_wx_scan_complete_event(_adapter *padapter)
214 union iwreq_data wrqu;
215 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
217 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
219 //DBG_871X("+rtw_indicate_wx_scan_complete_event\n");
220 #ifndef CONFIG_IOCTL_CFG80211
221 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
226 void rtw_indicate_wx_assoc_event(_adapter *padapter)
228 union iwreq_data wrqu;
229 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
230 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
231 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
232 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
234 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
236 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
238 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE )
239 _rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
241 _rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
243 DBG_871X_LEVEL(_drv_always_, "assoc success\n");
244 #ifndef CONFIG_IOCTL_CFG80211
245 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
249 void rtw_indicate_wx_disassoc_event(_adapter *padapter)
251 union iwreq_data wrqu;
253 _rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
255 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
256 _rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
258 #ifndef CONFIG_IOCTL_CFG80211
259 DBG_871X_LEVEL(_drv_always_, "indicate disassoc\n");
260 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
265 uint rtw_is_cckrates_included(u8 *rate)
271 if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
272 (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )
280 uint rtw_is_cckratesonly_included(u8 *rate)
286 if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
287 (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )
296 static int search_p2p_wfd_ie(_adapter *padapter,
297 struct iw_request_info* info, struct wlan_network *pnetwork,
298 char *start, char *stop)
301 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
303 if ( SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type )
307 else if ( ( SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type ) ||
308 ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type ) )
311 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
313 u32 blnGotP2PIE = _FALSE;
315 // User is doing the P2P device discovery
316 // The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE.
317 // If not, the driver should ignore this AP and go to the next AP.
319 // Verifying the SSID
320 if ( _rtw_memcmp( pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN ) )
324 // Verifying the P2P IE
325 if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen))
329 if ( blnGotP2PIE == _FALSE )
338 if ( SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type )
340 u32 blnGotWFD = _FALSE;
344 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
349 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
351 if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK )
353 // the first two bits will indicate the WFD device type
354 if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_SOURCE )
356 // If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source.
360 else if ( pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE )
362 // the first two bits will indicate the WFD device type
363 if ( ( wfd_devinfo[ 1 ] & 0x03 ) == WFD_DEVINFO_PSINK )
365 // If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink.
366 // Todo: How about the SSink?!
373 if ( blnGotWFD == _FALSE )
383 static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,
384 struct iw_request_info* info, struct wlan_network *pnetwork,
385 char *start, char *stop,struct iw_event *iwe)
388 iwe->cmd = SIOCGIWAP;
389 iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
391 _rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
392 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);
395 static inline char * iwe_stream_essid_proess(_adapter *padapter,
396 struct iw_request_info* info, struct wlan_network *pnetwork,
397 char *start, char *stop,struct iw_event *iwe)
401 iwe->cmd = SIOCGIWESSID;
402 iwe->u.data.flags = 1;
403 iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
404 start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
408 static inline char * iwe_stream_chan_process(_adapter *padapter,
409 struct iw_request_info* info, struct wlan_network *pnetwork,
410 char *start, char *stop,struct iw_event *iwe)
412 if(pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
413 pnetwork->network.Configuration.DSConfig = 1;
415 /* Add frequency/channel */
416 iwe->cmd = SIOCGIWFREQ;
417 iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
419 iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;
420 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);
423 static inline char * iwe_stream_mode_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 if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){
429 iwe->cmd = SIOCGIWMODE;
430 if (cap & WLAN_CAPABILITY_BSS)
431 iwe->u.mode = IW_MODE_MASTER;
433 iwe->u.mode = IW_MODE_ADHOC;
435 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);
439 static inline char * iwe_stream_encryption_process(_adapter *padapter,
440 struct iw_request_info* info, struct wlan_network *pnetwork,
441 char *start, char *stop,struct iw_event *iwe,u16 cap)
444 /* Add encryption capability */
445 iwe->cmd = SIOCGIWENCODE;
446 if (cap & WLAN_CAPABILITY_PRIVACY)
447 iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
449 iwe->u.data.flags = IW_ENCODE_DISABLED;
450 iwe->u.data.length = 0;
451 start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
456 static inline char * iwe_stream_protocol_process(_adapter *padapter,
457 struct iw_request_info* info, struct wlan_network *pnetwork,
458 char *start, char *stop,struct iw_event *iwe)
460 u16 ht_cap=_FALSE,vht_cap = _FALSE;
461 u32 ht_ielen = 0, vht_ielen = 0;
463 u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);// Probe Request
466 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-ie_offset);
470 #ifdef CONFIG_80211AC_VHT
472 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset);
476 /* Add the protocol name */
477 iwe->cmd = SIOCGIWNAME;
478 if ((rtw_is_cckratesonly_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
481 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");
483 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");
485 else if ((rtw_is_cckrates_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
488 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");
490 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");
494 if(pnetwork->network.Configuration.DSConfig > 14)
496 #ifdef CONFIG_80211AC_VHT
497 if(vht_cap == _TRUE){
498 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");
504 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");
506 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");
512 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");
514 snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");
517 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);
521 static inline char * iwe_stream_rate_process(_adapter *padapter,
522 struct iw_request_info* info, struct wlan_network *pnetwork,
523 char *start, char *stop,struct iw_event *iwe)
525 u32 ht_ielen = 0, vht_ielen = 0;
527 u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE;
529 u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0;
530 u16 mcs_rate=0, vht_data_rate=0;
531 char custom[MAX_CUSTOM_LEN]={0};
532 u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);// Probe Request
535 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-ie_offset);
538 struct rtw_ieee80211_ht_cap *pht_capie;
540 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
541 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
542 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0;
543 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
546 #ifdef CONFIG_80211AC_VHT
548 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset);
554 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
556 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p+2);
558 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p+2);
560 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p+2), 2);
562 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
563 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
567 /*Add basic and extended rates */
569 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
570 while(pnetwork->network.SupportedRates[i]!=0)
572 rate = pnetwork->network.SupportedRates[i]&0x7F;
575 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
576 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
579 #ifdef CONFIG_80211AC_VHT
580 if(vht_cap == _TRUE) {
581 max_rate = vht_data_rate;
587 if(mcs_rate&0x8000)//MCS15
589 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
592 else if(mcs_rate&0x0080)//MCS7
594 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
598 //DBG_871X("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate);
599 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
602 max_rate = max_rate*2;//Mbps/2;
605 iwe->cmd = SIOCGIWRATE;
606 iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
607 iwe->u.bitrate.value = max_rate * 500000;
608 start =iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);
612 static inline char * iwe_stream_wpa_wpa2_process(_adapter *padapter,
613 struct iw_request_info* info, struct wlan_network *pnetwork,
614 char *start, char *stop,struct iw_event *iwe)
616 int buf_size = MAX_WPA_IE_LEN*2;
617 //u8 pbuf[buf_size]={0};
618 u8 *pbuf = rtw_zmalloc(buf_size);
620 u8 wpa_ie[255]={0},rsn_ie[255]={0};
621 u16 i, wpa_len=0,rsn_len=0;
629 //parsing WPA/WPA2 IE
630 if (pnetwork->network.Reserved[0] != 2) // Probe Request
632 out_len=rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,rsn_ie,&rsn_len,wpa_ie,&wpa_len);
633 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
634 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len));
638 _rtw_memset(pbuf, 0, buf_size);
639 p += sprintf(p, "wpa_ie=");
640 for (i = 0; i < wpa_len; i++) {
641 p += sprintf(p, "%02x", wpa_ie[i]);
645 printk("-----------------Len %d----------------\n", wpa_len);
646 for (i = 0; i < wpa_len; i++) {
647 printk("%02x ", wpa_ie[i]);
650 printk("-----------------Len %d----------------\n", wpa_len);
653 _rtw_memset(iwe, 0, sizeof(*iwe));
654 iwe->cmd = IWEVCUSTOM;
655 iwe->u.data.length = strlen(pbuf);
656 start = iwe_stream_add_point(info, start, stop, iwe,pbuf);
658 _rtw_memset(iwe, 0, sizeof(*iwe));
660 iwe->u.data.length = wpa_len;
661 start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
665 _rtw_memset(pbuf, 0, buf_size);
666 p += sprintf(p, "rsn_ie=");
667 for (i = 0; i < rsn_len; i++) {
668 p += sprintf(p, "%02x", rsn_ie[i]);
670 _rtw_memset(iwe, 0, sizeof(*iwe));
671 iwe->cmd = IWEVCUSTOM;
672 iwe->u.data.length = strlen(pbuf);
673 start = iwe_stream_add_point(info, start, stop, iwe,pbuf);
675 _rtw_memset(iwe, 0, sizeof(*iwe));
677 iwe->u.data.length = rsn_len;
678 start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
682 rtw_mfree(pbuf, buf_size);
687 static inline char * iwe_stream_wps_process(_adapter *padapter,
688 struct iw_request_info* info, struct wlan_network *pnetwork,
689 char *start, char *stop,struct iw_event *iwe)
692 uint cnt = 0,total_ielen;
695 u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
697 u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
698 total_ielen= pnetwork->network.IELength - ie_offset;
700 if (pnetwork->network.Reserved[0] == 2) // Probe Request
702 ie_ptr = pnetwork->network.IEs;
703 total_ielen = pnetwork->network.IELength;
705 else // Beacon or Probe Respones
707 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
708 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
710 while(cnt < total_ielen)
712 if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2))
714 wpsie_ptr = &ie_ptr[cnt];
716 iwe->u.data.length = (u16)wps_ielen;
717 start = iwe_stream_add_point(info, start, stop,iwe, wpsie_ptr);
719 cnt+=ie_ptr[cnt+1]+2; //goto next
724 static inline char * iwe_stream_wapi_process(_adapter *padapter,
725 struct iw_request_info* info, struct wlan_network *pnetwork,
726 char *start, char *stop,struct iw_event *iwe)
728 #ifdef CONFIG_WAPI_SUPPORT
731 if (pnetwork->network.Reserved[0] != 2) // Probe Request
734 /* here use static for stack size */
735 static u8 buf_wapi[MAX_WAPI_IE_LEN*2]={0};
736 static u8 wapi_ie[MAX_WAPI_IE_LEN]={0};
740 out_len_wapi=rtw_get_wapi_ie(pnetwork->network.IEs ,pnetwork->network.IELength,wapi_ie,&wapi_len);
741 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
742 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wapi_len=%d \n",wapi_len));
744 DBG_871X("rtw_wx_get_scan: %s ",pnetwork->network.Ssid.Ssid);
745 DBG_871X("rtw_wx_get_scan: ssid = %d ",wapi_len);
751 //_rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2);
752 p += sprintf(p, "wapi_ie=");
753 for (i = 0; i < wapi_len; i++) {
754 p += sprintf(p, "%02x", wapi_ie[i]);
757 _rtw_memset(iwe, 0, sizeof(*iwe));
758 iwe->cmd = IWEVCUSTOM;
759 iwe->u.data.length = strlen(buf_wapi);
760 start = iwe_stream_add_point(info, start, stop, iwe,buf_wapi);
762 _rtw_memset(iwe, 0, sizeof(*iwe));
764 iwe->u.data.length = wapi_len;
765 start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);
768 #endif//#ifdef CONFIG_WAPI_SUPPORT
772 static inline char * iwe_stream_rssi_process(_adapter *padapter,
773 struct iw_request_info* info, struct wlan_network *pnetwork,
774 char *start, char *stop,struct iw_event *iwe)
777 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
779 /* Add quality statistics */
781 iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
782 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
783 | IW_QUAL_NOISE_UPDATED
785 | IW_QUAL_NOISE_INVALID
787 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
792 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
793 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)){
794 ss = padapter->recvpriv.signal_strength;
795 sq = padapter->recvpriv.signal_qual;
797 ss = pnetwork->network.PhyInfo.SignalStrength;
798 sq = pnetwork->network.PhyInfo.SignalQuality;
802 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
803 iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
805 #ifdef CONFIG_SIGNAL_SCALE_MAPPING
806 iwe->u.qual.level = (u8)ss; /* % */
809 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
811 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
813 iwe->u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
818 iwe->u.qual.qual = (u8)sq; // signal quality
820 #ifdef CONFIG_PLATFORM_ROCKCHIPS
821 iwe->u.qual.noise = -100; // noise level suggest by zhf@rockchips
823 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
826 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
827 iwe->u.qual.noise = tmp_noise ;
830 iwe->u.qual.noise = 0; // noise level
832 #endif //CONFIG_PLATFORM_ROCKCHIPS
834 //DBG_871X("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);
836 start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);
840 static inline char * iwe_stream_net_rsv_process(_adapter *padapter,
841 struct iw_request_info* info, struct wlan_network *pnetwork,
842 char *start, char *stop,struct iw_event *iwe)
848 pos = pnetwork->network.Reserved;
850 p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
851 _rtw_memset(iwe, 0, sizeof(*iwe));
852 iwe->cmd = IWEVCUSTOM;
853 iwe->u.data.length = strlen(buf);
854 start = iwe_stream_add_point(info, start, stop,iwe, buf);
859 static char *translate_scan(_adapter *padapter,
860 struct iw_request_info* info, struct wlan_network *pnetwork,
861 char *start, char *stop)
865 _rtw_memset(&iwe, 0, sizeof(iwe));
867 if(_FALSE == search_p2p_wfd_ie(padapter,info,pnetwork,start,stop))
870 start = iwe_stream_mac_addr_proess(padapter,info,pnetwork,start,stop,&iwe);
871 start = iwe_stream_essid_proess(padapter,info,pnetwork,start,stop,&iwe);
872 start = iwe_stream_protocol_process(padapter,info,pnetwork,start,stop,&iwe);
873 if (pnetwork->network.Reserved[0] == 2) // Probe Request
879 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
880 cap = le16_to_cpu(cap);
883 start = iwe_stream_mode_process(padapter,info,pnetwork,start,stop,&iwe,cap);
884 start = iwe_stream_chan_process(padapter,info,pnetwork,start,stop,&iwe);
885 start = iwe_stream_encryption_process(padapter,info,pnetwork,start,stop,&iwe,cap);
886 start = iwe_stream_rate_process(padapter,info,pnetwork,start,stop,&iwe);
887 start = iwe_stream_wpa_wpa2_process(padapter,info,pnetwork,start,stop,&iwe);
888 start = iwe_stream_wps_process(padapter,info,pnetwork,start,stop,&iwe);
889 start = iwe_stream_wapi_process(padapter,info,pnetwork,start,stop,&iwe);
890 start = iwe_stream_rssi_process(padapter,info,pnetwork,start,stop,&iwe);
891 start = iwe_stream_net_rsv_process(padapter,info,pnetwork,start,stop,&iwe);
896 static char *translate_scan(_adapter *padapter,
897 struct iw_request_info* info, struct wlan_network *pnetwork,
898 char *start, char *stop)
902 u32 ht_ielen = 0, vht_ielen = 0;
903 char custom[MAX_CUSTOM_LEN];
905 u16 max_rate=0, rate, ht_cap=_FALSE, vht_cap = _FALSE;
909 u8 bw_40MHz=0, short_GI=0, bw_160MHz=0, vht_highest_rate = 0;
910 u16 mcs_rate=0, vht_data_rate=0;
911 u8 ie_offset = (pnetwork->network.Reserved[0] == 2? 0:12);
912 struct registry_priv *pregpriv = &padapter->registrypriv;
914 if(_FALSE == search_p2p_wfd_ie(padapter,info,pnetwork,start,stop))
919 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
921 _rtw_memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
922 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
925 iwe.cmd = SIOCGIWESSID;
926 iwe.u.data.flags = 1;
927 iwe.u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
928 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
931 if (pnetwork->network.Reserved[0] == 2) // Probe Request
933 p = rtw_get_ie(&pnetwork->network.IEs[0], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength);
937 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength-12);
941 struct rtw_ieee80211_ht_cap *pht_capie;
943 pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
944 _rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
945 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0;
946 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
949 #ifdef CONFIG_80211AC_VHT
951 p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength-ie_offset);
957 bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p+2);
959 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p+2);
961 short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p+2);
963 _rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p+2), 2);
965 vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
966 vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
970 /* Add the protocol name */
971 iwe.cmd = SIOCGIWNAME;
972 if ((rtw_is_cckratesonly_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
975 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
977 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
979 else if ((rtw_is_cckrates_included((u8*)&pnetwork->network.SupportedRates)) == _TRUE)
982 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
984 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
988 if(pnetwork->network.Configuration.DSConfig > 14)
991 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11AC");
992 else if(ht_cap == _TRUE)
993 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11an");
995 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
1000 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
1002 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
1006 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
1009 if (pnetwork->network.Reserved[0] == 2) // Probe Request
1015 iwe.cmd = SIOCGIWMODE;
1016 _rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
1017 cap = le16_to_cpu(cap);
1020 if(cap & (WLAN_CAPABILITY_IBSS |WLAN_CAPABILITY_BSS)){
1021 if (cap & WLAN_CAPABILITY_BSS)
1022 iwe.u.mode = IW_MODE_MASTER;
1024 iwe.u.mode = IW_MODE_ADHOC;
1026 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
1029 if(pnetwork->network.Configuration.DSConfig<1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
1030 pnetwork->network.Configuration.DSConfig = 1;
1032 /* Add frequency/channel */
1033 iwe.cmd = SIOCGIWFREQ;
1034 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
1036 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
1037 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
1039 /* Add encryption capability */
1040 iwe.cmd = SIOCGIWENCODE;
1041 if (cap & WLAN_CAPABILITY_PRIVACY)
1042 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1044 iwe.u.data.flags = IW_ENCODE_DISABLED;
1045 iwe.u.data.length = 0;
1046 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
1048 /*Add basic and extended rates */
1051 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
1052 while(pnetwork->network.SupportedRates[i]!=0)
1054 rate = pnetwork->network.SupportedRates[i]&0x7F;
1055 if (rate > max_rate)
1057 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
1058 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
1062 if(vht_cap == _TRUE) {
1063 max_rate = vht_data_rate;
1065 else if(ht_cap == _TRUE)
1067 if(mcs_rate&0x8000)//MCS15
1069 max_rate = (bw_40MHz) ? ((short_GI)?300:270):((short_GI)?144:130);
1072 else if(mcs_rate&0x0080)//MCS7
1074 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
1078 //DBG_871X("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate);
1079 max_rate = (bw_40MHz) ? ((short_GI)?150:135):((short_GI)?72:65);
1082 max_rate = max_rate*2;//Mbps/2;
1085 iwe.cmd = SIOCGIWRATE;
1086 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1087 iwe.u.bitrate.value = max_rate * 500000;
1088 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
1090 //parsing WPA/WPA2 IE
1091 if (pnetwork->network.Reserved[0] != 2) // Probe Request
1093 u8 buf[MAX_WPA_IE_LEN*2];
1094 u8 wpa_ie[255],rsn_ie[255];
1095 u16 wpa_len=0,rsn_len=0;
1098 out_len=rtw_get_sec_ie(pnetwork->network.IEs ,pnetwork->network.IELength,rsn_ie,&rsn_len,wpa_ie,&wpa_len);
1099 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
1100 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wpa_len=%d rsn_len=%d\n",wpa_len,rsn_len));
1105 _rtw_memset(buf, 0, MAX_WPA_IE_LEN*2);
1106 p += sprintf(p, "wpa_ie=");
1107 for (i = 0; i < wpa_len; i++) {
1108 p += sprintf(p, "%02x", wpa_ie[i]);
1111 if (wpa_len > 100) {
1112 printk("-----------------Len %d----------------\n", wpa_len);
1113 for (i = 0; i < wpa_len; i++) {
1114 printk("%02x ", wpa_ie[i]);
1117 printk("-----------------Len %d----------------\n", wpa_len);
1120 _rtw_memset(&iwe, 0, sizeof(iwe));
1121 iwe.cmd = IWEVCUSTOM;
1122 iwe.u.data.length = strlen(buf);
1123 start = iwe_stream_add_point(info, start, stop, &iwe,buf);
1125 _rtw_memset(&iwe, 0, sizeof(iwe));
1127 iwe.u.data.length = wpa_len;
1128 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
1133 _rtw_memset(buf, 0, MAX_WPA_IE_LEN*2);
1134 p += sprintf(p, "rsn_ie=");
1135 for (i = 0; i < rsn_len; i++) {
1136 p += sprintf(p, "%02x", rsn_ie[i]);
1138 _rtw_memset(&iwe, 0, sizeof(iwe));
1139 iwe.cmd = IWEVCUSTOM;
1140 iwe.u.data.length = strlen(buf);
1141 start = iwe_stream_add_point(info, start, stop, &iwe,buf);
1143 _rtw_memset(&iwe, 0, sizeof(iwe));
1145 iwe.u.data.length = rsn_len;
1146 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
1151 uint cnt = 0,total_ielen;
1155 u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
1156 total_ielen= pnetwork->network.IELength - ie_offset;
1158 if (pnetwork->network.Reserved[0] == 2) // Probe Request
1160 ie_ptr = pnetwork->network.IEs;
1161 total_ielen = pnetwork->network.IELength;
1163 else // Beacon or Probe Respones
1165 ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
1166 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
1169 while(cnt < total_ielen)
1171 if(rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen>2))
1173 wpsie_ptr = &ie_ptr[cnt];
1175 iwe.u.data.length = (u16)wps_ielen;
1176 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
1178 cnt+=ie_ptr[cnt+1]+2; //goto next
1182 #ifdef CONFIG_WAPI_SUPPORT
1183 if (pnetwork->network.Reserved[0] != 2) // Probe Request
1185 sint out_len_wapi=0;
1186 /* here use static for stack size */
1187 static u8 buf_wapi[MAX_WAPI_IE_LEN*2];
1188 static u8 wapi_ie[MAX_WAPI_IE_LEN];
1192 _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN);
1193 _rtw_memset(wapi_ie, 0, MAX_WAPI_IE_LEN);
1195 out_len_wapi=rtw_get_wapi_ie(pnetwork->network.IEs ,pnetwork->network.IELength,wapi_ie,&wapi_len);
1196 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: ssid=%s\n",pnetwork->network.Ssid.Ssid));
1197 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan: wapi_len=%d \n",wapi_len));
1199 DBG_871X("rtw_wx_get_scan: %s ",pnetwork->network.Ssid.Ssid);
1200 DBG_871X("rtw_wx_get_scan: ssid = %d ",wapi_len);
1206 _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2);
1207 p += sprintf(p, "wapi_ie=");
1208 for (i = 0; i < wapi_len; i++) {
1209 p += sprintf(p, "%02x", wapi_ie[i]);
1212 _rtw_memset(&iwe, 0, sizeof(iwe));
1213 iwe.cmd = IWEVCUSTOM;
1214 iwe.u.data.length = strlen(buf_wapi);
1215 start = iwe_stream_add_point(info, start, stop, &iwe,buf_wapi);
1217 _rtw_memset(&iwe, 0, sizeof(iwe));
1219 iwe.u.data.length = wapi_len;
1220 start = iwe_stream_add_point(info, start, stop, &iwe, wapi_ie);
1226 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1229 /* Add quality statistics */
1231 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
1232 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
1233 | IW_QUAL_NOISE_UPDATED
1235 | IW_QUAL_NOISE_INVALID
1237 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1242 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
1243 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)){
1244 ss = padapter->recvpriv.signal_strength;
1245 sq = padapter->recvpriv.signal_qual;
1247 ss = pnetwork->network.PhyInfo.SignalStrength;
1248 sq = pnetwork->network.PhyInfo.SignalQuality;
1252 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
1253 iwe.u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
1255 #ifdef CONFIG_SIGNAL_SCALE_MAPPING
1256 iwe.u.qual.level = (u8)ss; /* % */
1259 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
1261 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
1263 iwe.u.qual.level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, ss);
1268 iwe.u.qual.qual = (u8)sq; // signal quality
1270 #ifdef CONFIG_PLATFORM_ROCKCHIPS
1271 iwe.u.qual.noise = -100; // noise level suggest by zhf@rockchips
1273 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
1276 rtw_hal_get_odm_var(padapter, HAL_ODM_NOISE_MONITOR,&(pnetwork->network.Configuration.DSConfig), &(tmp_noise));
1277 iwe.u.qual.noise = tmp_noise ;
1280 iwe.u.qual.noise = 0; // noise level
1282 #endif //CONFIG_PLATFORM_ROCKCHIPS
1284 //DBG_871X("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);
1286 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
1290 u8 buf[MAX_WPA_IE_LEN];
1294 pos = pnetwork->network.Reserved;
1295 _rtw_memset(buf, 0, MAX_WPA_IE_LEN);
1296 p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
1297 _rtw_memset(&iwe, 0, sizeof(iwe));
1298 iwe.cmd = IWEVCUSTOM;
1299 iwe.u.data.length = strlen(buf);
1300 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
1307 static int wpa_set_auth_algs(struct net_device *dev, u32 value)
1309 _adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
1312 if ((value & AUTH_ALG_SHARED_KEY)&&(value & AUTH_ALG_OPEN_SYSTEM))
1314 DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n",value);
1315 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1316 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
1317 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1319 else if (value & AUTH_ALG_SHARED_KEY)
1321 DBG_871X("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n",value);
1322 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1324 #ifdef CONFIG_PLATFORM_MT53XX
1325 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
1326 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1328 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
1329 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1332 else if(value & AUTH_ALG_OPEN_SYSTEM)
1334 DBG_871X("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
1335 //padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1336 if(padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK)
1338 #ifdef CONFIG_PLATFORM_MT53XX
1339 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
1340 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1342 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1343 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1348 else if(value & AUTH_ALG_LEAP)
1350 DBG_871X("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
1354 DBG_871X("wpa_set_auth_algs, error!\n");
1362 static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1365 u32 wep_key_idx, wep_key_len,wep_total_len;
1366 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1367 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1368 struct security_priv *psecuritypriv = &padapter->securitypriv;
1370 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1375 param->u.crypt.err = 0;
1376 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1378 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
1384 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1385 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1386 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
1389 if (param->u.crypt.idx >= WEP_KEYS
1390 #ifdef CONFIG_IEEE80211W
1391 && param->u.crypt.idx > BIP_MAX_KEYID
1392 #endif //CONFIG_IEEE80211W
1401 #ifdef CONFIG_WAPI_SUPPORT
1402 if (strcmp(param->u.crypt.alg, "SMS4"))
1410 if (strcmp(param->u.crypt.alg, "WEP") == 0)
1412 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
1413 DBG_871X("wpa_set_encryption, crypt.alg = WEP\n");
1415 wep_key_idx = param->u.crypt.idx;
1416 wep_key_len = param->u.crypt.key_len;
1418 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
1424 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1425 /* wep default key has not been set, so use this key index as default key.*/
1427 wep_key_len = wep_key_len <= 5 ? 5 : 13;
1429 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1430 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1431 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1433 if (wep_key_len == 13)
1435 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1436 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1439 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1442 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1444 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1446 psecuritypriv->key_mask |= BIT(wep_key_idx);
1451 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
1453 struct sta_info * psta,*pbcmc_sta;
1454 struct sta_priv * pstapriv = &padapter->stapriv;
1456 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
1458 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1460 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1464 //Jeff: don't disable ieee8021x_blocked while clearing key
1465 if (strcmp(param->u.crypt.alg, "none") != 0)
1466 psta->ieee8021x_blocked = _FALSE;
1468 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1469 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1471 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1474 if(param->u.crypt.set_tx ==1)//pairwise key
1476 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1478 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1480 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1481 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1482 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1484 padapter->securitypriv.busetkipkey=_FALSE;
1485 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1488 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1489 DBG_871X(" ~~~~set sta key:unicastkey\n");
1491 rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
1493 psta->bpairwise_key_installed = _TRUE;
1498 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
1500 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1501 //only TKIP group key need to install this
1502 if(param->u.crypt.key_len > 16)
1504 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1505 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1507 padapter->securitypriv.binstallGrpkey = _TRUE;
1508 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1509 DBG_871X(" ~~~~set sta key:groupkey\n");
1511 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1513 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
1515 #ifdef CONFIG_IEEE80211W
1516 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
1519 //printk("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
1520 //save the IGTK key, length 16 bytes
1521 _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));
1522 /*printk("IGTK key below:\n");
1523 for(no=0;no<16;no++)
1524 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1526 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1527 padapter->securitypriv.binstallBIPkey = _TRUE;
1528 DBG_871X(" ~~~~set sta key:IGKT\n");
1530 #endif //CONFIG_IEEE80211W
1533 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1535 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1542 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1545 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1549 //Jeff: don't disable ieee8021x_blocked while clearing key
1550 if (strcmp(param->u.crypt.alg, "none") != 0)
1551 pbcmc_sta->ieee8021x_blocked = _FALSE;
1553 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1554 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1556 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1560 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1565 #ifdef CONFIG_WAPI_SUPPORT
1566 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1568 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
1569 PRT_WAPI_STA_INFO pWapiSta;
1570 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1571 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1572 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1574 if(param->u.crypt.set_tx == 1)
1576 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1577 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
1579 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
1581 pWapiSta->wapiUsk.bSet = true;
1582 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
1583 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
1584 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1585 pWapiSta->wapiUsk.bTxEnable = true;
1587 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
1588 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
1589 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
1590 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
1591 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
1592 pWapiSta->wapiUskUpdate.bTxEnable = false;
1593 pWapiSta->wapiUskUpdate.bSet = false;
1595 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
1597 //set unicast key for ASUE
1598 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1605 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1606 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
1608 pWapiSta->wapiMsk.bSet = true;
1609 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
1610 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
1611 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1612 pWapiSta->wapiMsk.bTxEnable = false;
1613 if(!pWapiSta->bSetkeyOk)
1614 pWapiSta->bSetkeyOk = true;
1615 pWapiSta->bAuthenticateInProgress = false;
1617 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1619 if (psecuritypriv->sw_decrypt == false)
1621 //set rx broadcast key for ASUE
1622 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1638 static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1640 u8 *buf=NULL, *pos=NULL;
1642 int group_cipher = 0, pairwise_cipher = 0;
1644 u8 null_addr[]= {0,0,0,0,0,0};
1646 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1649 if((ielen > MAX_WPA_IE_LEN) || (pie == NULL)){
1650 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1659 buf = rtw_zmalloc(ielen);
1665 _rtw_memcpy(buf, pie , ielen);
1670 DBG_871X("\n wpa_ie(length:%d):\n", ielen);
1671 for(i=0;i<ielen;i=i+8)
1672 DBG_871X("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
1676 if(ielen < RSN_HEADER_LEN){
1677 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
1683 pos += RSN_HEADER_LEN;
1684 left = ielen - RSN_HEADER_LEN;
1686 if (left >= RSN_SELECTOR_LEN){
1687 pos += RSN_SELECTOR_LEN;
1688 left -= RSN_SELECTOR_LEN;
1691 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie length mismatch, %u too much \n", left));
1697 if(rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1699 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1700 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
1701 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1704 if(rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1706 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
1707 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
1708 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1711 if (group_cipher == 0)
1713 group_cipher = WPA_CIPHER_NONE;
1715 if (pairwise_cipher == 0)
1717 pairwise_cipher = WPA_CIPHER_NONE;
1720 switch(group_cipher)
1722 case WPA_CIPHER_NONE:
1723 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
1724 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1726 case WPA_CIPHER_WEP40:
1727 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
1728 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1730 case WPA_CIPHER_TKIP:
1731 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
1732 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1734 case WPA_CIPHER_CCMP:
1735 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
1736 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1738 case WPA_CIPHER_WEP104:
1739 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
1740 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1744 switch(pairwise_cipher)
1746 case WPA_CIPHER_NONE:
1747 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
1748 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
1750 case WPA_CIPHER_WEP40:
1751 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
1752 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1754 case WPA_CIPHER_TKIP:
1755 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
1756 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1758 case WPA_CIPHER_CCMP:
1759 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
1760 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1762 case WPA_CIPHER_WEP104:
1763 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
1764 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1768 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1771 u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
1773 while( cnt < ielen )
1777 if((eid==_VENDOR_SPECIFIC_IE_)&&(_rtw_memcmp(&buf[cnt+2], wps_oui, 4)==_TRUE))
1779 DBG_871X("SET WPS_IE\n");
1781 padapter->securitypriv.wps_ie_len = ((buf[cnt+1]+2) < MAX_WPS_IE_LEN) ? (buf[cnt+1]+2):MAX_WPS_IE_LEN;
1783 _rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1785 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1788 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1790 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1793 cnt += buf[cnt+1]+2;
1797 cnt += buf[cnt+1]+2; //goto next
1803 //TKIP and AES disallow multicast packets until installing group key
1804 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1805 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1806 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1807 //WPS open need to enable multicast
1808 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
1809 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1811 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1812 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
1813 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
1817 if (buf) rtw_mfree(buf, ielen);
1822 static int rtw_wx_get_name(struct net_device *dev,
1823 struct iw_request_info *info,
1824 union iwreq_data *wrqu, char *extra)
1826 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1830 u8 ht_cap=_FALSE, vht_cap=_FALSE;
1831 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1832 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1833 NDIS_802_11_RATES_EX* prates = NULL;
1835 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("cmd_code=%x\n", info->cmd));
1839 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
1842 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
1848 #ifdef CONFIG_80211AC_VHT
1849 if(pmlmepriv->vhtpriv.vht_option == _TRUE)
1853 prates = &pcur_bss->SupportedRates;
1855 if (rtw_is_cckratesonly_included((u8*)prates) == _TRUE)
1858 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1860 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1862 else if ((rtw_is_cckrates_included((u8*)prates)) == _TRUE)
1865 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1867 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1871 if(pcur_bss->Configuration.DSConfig > 14)
1873 #ifdef CONFIG_80211AC_VHT
1874 if(vht_cap == _TRUE){
1875 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1881 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1883 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1889 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1891 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1897 //prates = &padapter->registrypriv.dev_network.SupportedRates;
1898 //snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1899 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1907 static int rtw_wx_set_freq(struct net_device *dev,
1908 struct iw_request_info *info,
1909 union iwreq_data *wrqu, char *extra)
1912 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1913 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
1914 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1915 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
1916 int exp = 1, freq = 0, div = 0;
1920 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_wx_set_freq\n"));
1922 if (wrqu->freq.m <= 1000) {
1923 if (wrqu->freq.flags == IW_FREQ_AUTO) {
1924 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, wrqu->freq.m) > 0) {
1925 padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1926 DBG_871X("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m);
1928 padapter->mlmeextpriv.cur_channel = 1;
1929 DBG_871X("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__);
1932 padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1933 DBG_871X("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1936 while (wrqu->freq.e) {
1941 freq = wrqu->freq.m;
1943 while (!(freq%10)) {
1948 /* freq unit is MHz here */
1958 /* If freq is invalid, rtw_freq2ch() will return channel 1 */
1959 padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);
1960 DBG_871X("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1963 set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
1970 static int rtw_wx_get_freq(struct net_device *dev,
1971 struct iw_request_info *info,
1972 union iwreq_data *wrqu, char *extra)
1974 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1975 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1976 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1978 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1980 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1982 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1985 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1987 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1993 static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1994 union iwreq_data *wrqu, char *b)
1996 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1997 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1998 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
2003 if(_FAIL == rtw_pwr_wakeup(padapter)) {
2008 if (!rtw_is_hw_init_completed(padapter)) {
2013 /* initial default type */
2014 dev->type = ARPHRD_ETHER;
2018 case IW_MODE_MONITOR:
2019 networkType = Ndis802_11Monitor;
2021 dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
2023 dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
2024 DBG_871X("set_mode = IW_MODE_MONITOR\n");
2028 networkType = Ndis802_11AutoUnknown;
2029 DBG_871X("set_mode = IW_MODE_AUTO\n");
2032 networkType = Ndis802_11IBSS;
2033 DBG_871X("set_mode = IW_MODE_ADHOC\n");
2035 case IW_MODE_MASTER:
2036 networkType = Ndis802_11APMode;
2037 DBG_871X("set_mode = IW_MODE_MASTER\n");
2038 //rtw_setopmode_cmd(padapter, networkType,_TRUE);
2041 networkType = Ndis802_11Infrastructure;
2042 DBG_871X("set_mode = IW_MODE_INFRA\n");
2047 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode]));
2052 if(Ndis802_11APMode == networkType)
2054 rtw_setopmode_cmd(padapter, networkType,_TRUE);
2058 rtw_setopmode_cmd(padapter, Ndis802_11AutoUnknown,_TRUE);
2062 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE){
2069 rtw_setopmode_cmd(padapter, networkType,_TRUE);
2071 if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
2072 rtw_indicate_connect(padapter);
2082 static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
2083 union iwreq_data *wrqu, char *b)
2085 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2086 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2088 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_get_mode \n"));
2092 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
2094 wrqu->mode = IW_MODE_INFRA;
2096 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
2097 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
2100 wrqu->mode = IW_MODE_ADHOC;
2102 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2104 wrqu->mode = IW_MODE_MASTER;
2105 } else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
2106 wrqu->mode = IW_MODE_MONITOR;
2108 wrqu->mode = IW_MODE_AUTO;
2117 static int rtw_wx_set_pmkid(struct net_device *dev,
2118 struct iw_request_info *a,
2119 union iwreq_data *wrqu, char *extra)
2121 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2122 u8 j,blInserted = _FALSE;
2123 int intReturn = _FALSE;
2124 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2125 struct security_priv *psecuritypriv = &padapter->securitypriv;
2126 struct iw_pmksa* pPMK = ( struct iw_pmksa* ) extra;
2127 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
2128 u8 strIssueBssid[ ETH_ALEN ] = { 0x00 };
2134 struct sockaddr bssid;
2135 __u8 pmkid[IW_PMKID_LEN]; //IW_PMKID_LEN=16
2137 There are the BSSID information in the bssid.sa_data array.
2138 If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
2139 If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID/BSSID to driver.
2140 If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID/BSSID from driver.
2143 _rtw_memcpy( strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
2144 if ( pPMK->cmd == IW_PMKSA_ADD )
2146 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n" );
2147 if ( _rtw_memcmp( strIssueBssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
2149 return( intReturn );
2155 blInserted = _FALSE;
2158 for(j=0 ; j<NUM_PMKID_CACHE; j++)
2160 if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
2161 { // BSSID is matched, the same AP => rewrite with new PMKID.
2163 DBG_871X( "[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n" );
2165 _rtw_memcpy( psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
2166 psecuritypriv->PMKIDList[ j ].bUsed = _TRUE;
2167 psecuritypriv->PMKIDIndex = j+1;
2176 DBG_871X( "[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
2177 psecuritypriv->PMKIDIndex );
2179 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
2180 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
2182 psecuritypriv->PMKIDList[ psecuritypriv->PMKIDIndex ].bUsed = _TRUE;
2183 psecuritypriv->PMKIDIndex++ ;
2184 if(psecuritypriv->PMKIDIndex==16)
2186 psecuritypriv->PMKIDIndex =0;
2190 else if ( pPMK->cmd == IW_PMKSA_REMOVE )
2192 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n" );
2194 for(j=0 ; j<NUM_PMKID_CACHE; j++)
2196 if( _rtw_memcmp( psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) ==_TRUE )
2197 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
2198 _rtw_memset( psecuritypriv->PMKIDList[ j ].Bssid, 0x00, ETH_ALEN );
2199 psecuritypriv->PMKIDList[ j ].bUsed = _FALSE;
2204 else if ( pPMK->cmd == IW_PMKSA_FLUSH )
2206 DBG_871X( "[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n" );
2207 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
2208 psecuritypriv->PMKIDIndex = 0;
2211 return( intReturn );
2214 static int rtw_wx_get_sens(struct net_device *dev,
2215 struct iw_request_info *info,
2216 union iwreq_data *wrqu, char *extra)
2218 #ifdef CONFIG_PLATFORM_ROCKCHIPS
2219 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2220 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2223 * 20110311 Commented by Jeff
2224 * For rockchip platform's wpa_driver_wext_get_rssi
2226 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
2227 //wrqu->sens.value=-padapter->recvpriv.signal_strength;
2228 wrqu->sens.value=-padapter->recvpriv.rssi;
2229 //DBG_871X("%s: %d\n", __FUNCTION__, wrqu->sens.value);
2230 wrqu->sens.fixed = 0; /* no auto select */
2234 wrqu->sens.value = 0;
2235 wrqu->sens.fixed = 0; /* no auto select */
2236 wrqu->sens.disabled = 1;
2241 static int rtw_wx_get_range(struct net_device *dev,
2242 struct iw_request_info *info,
2243 union iwreq_data *wrqu, char *extra)
2245 struct iw_range *range = (struct iw_range *)extra;
2246 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2247 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2254 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_range. cmd_code=%x\n", info->cmd));
2256 wrqu->data.length = sizeof(*range);
2257 _rtw_memset(range, 0, sizeof(*range));
2259 /* Let's try to keep this struct in the same order as in
2260 * linux/include/wireless.h
2263 /* TODO: See what values we can set, and remove the ones we can't
2264 * set, or fill them with some default data.
2267 /* ~5 Mb/s real (802.11b) */
2268 range->throughput = 5 * 1000 * 1000;
2270 // TODO: Not used in 802.11b?
2271 // range->min_nwid; /* Minimal NWID we are able to set */
2272 // TODO: Not used in 802.11b?
2273 // range->max_nwid; /* Maximal NWID we are able to set */
2275 /* Old Frequency (backward compat - moved lower ) */
2276 // range->old_num_channels;
2277 // range->old_num_frequency;
2278 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
2280 /* signal level threshold range */
2282 /* Quality of link & SNR stuff */
2283 /* Quality range (link, level, noise)
2284 * If the quality is absolute, it will be in the range [0 ; max_qual],
2285 * if the quality is dBm, it will be in the range [max_qual ; 0].
2286 * Don't forget that we use 8 bit arithmetics...
2288 * If percentage range is 0~100
2289 * Signal strength dbm range logical is -100 ~ 0
2290 * but usually value is -90 ~ -20
2291 * When CONFIG_SIGNAL_SCALE_MAPPING is defined, dbm range is -95 ~ -45
2293 range->max_qual.qual = 100;
2294 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
2295 range->max_qual.level = (u8)-100;
2296 range->max_qual.noise = (u8)-100;
2297 range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2298 range->max_qual.updated |= IW_QUAL_DBM;
2299 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
2300 //percent values between 0 and 100.
2301 range->max_qual.level = 100;
2302 range->max_qual.noise = 100;
2303 range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2304 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
2306 /* This should contain the average/typical values of the quality
2307 * indicator. This should be the threshold between a "good" and
2308 * a "bad" link (example : monitor going from green to orange).
2309 * Currently, user space apps like quality monitors don't have any
2310 * way to calibrate the measurement. With this, they can split
2311 * the range between 0 and max_qual in different quality level
2312 * (using a geometric subdivision centered on the average).
2313 * I expect that people doing the user space apps will feedback
2314 * us on which value we need to put in each driver... */
2315 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
2316 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
2317 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
2318 range->avg_qual.level = (u8)-70;
2319 range->avg_qual.noise = 0;
2320 range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2321 range->avg_qual.updated |= IW_QUAL_DBM;
2322 #else /* !CONFIG_SIGNAL_DISPLAY_DBM */
2323 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
2324 range->avg_qual.level = 30;
2325 range->avg_qual.noise = 100;
2326 range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
2327 #endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
2329 range->num_bitrates = RATE_COUNT;
2331 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
2332 range->bitrate[i] = rtw_rates[i];
2335 range->min_frag = MIN_FRAG_THRESHOLD;
2336 range->max_frag = MAX_FRAG_THRESHOLD;
2340 range->we_version_compiled = WIRELESS_EXT;
2341 range->we_version_source = 16;
2343 // range->retry_capa; /* What retry options are supported */
2344 // range->retry_flags; /* How to decode max/min retry limit */
2345 // range->r_time_flags; /* How to decode max/min retry life */
2346 // range->min_retry; /* Minimal number of retries */
2347 // range->max_retry; /* Maximal number of retries */
2348 // range->min_r_time; /* Minimal retry lifetime */
2349 // range->max_r_time; /* Maximal retry lifetime */
2351 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
2353 // Include only legal frequencies for some countries
2354 if(pmlmeext->channel_set[i].ChannelNum != 0)
2356 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
2357 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
2358 range->freq[val].e = 1;
2362 if (val == IW_MAX_FREQUENCIES)
2366 range->num_channels = val;
2367 range->num_frequency = val;
2369 // Commented by Albert 2009/10/13
2370 // The following code will proivde the security capability to network manager.
2371 // If the driver doesn't provide this capability to network manager,
2372 // the WPA/WPA2 routers can't be choosen in the network manager.
2375 #define IW_SCAN_CAPA_NONE 0x00
2376 #define IW_SCAN_CAPA_ESSID 0x01
2377 #define IW_SCAN_CAPA_BSSID 0x02
2378 #define IW_SCAN_CAPA_CHANNEL 0x04
2379 #define IW_SCAN_CAPA_MODE 0x08
2380 #define IW_SCAN_CAPA_RATE 0x10
2381 #define IW_SCAN_CAPA_TYPE 0x20
2382 #define IW_SCAN_CAPA_TIME 0x40
2385 #if WIRELESS_EXT > 17
2386 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
2387 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
2390 #ifdef IW_SCAN_CAPA_ESSID //WIRELESS_EXT > 21
2391 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |IW_SCAN_CAPA_BSSID|
2392 IW_SCAN_CAPA_CHANNEL|IW_SCAN_CAPA_MODE|IW_SCAN_CAPA_RATE;
2403 //s1. rtw_set_802_11_infrastructure_mode()
2404 //s2. rtw_set_802_11_authentication_mode()
2405 //s3. set_802_11_encryption_mode()
2406 //s4. rtw_set_802_11_bssid()
2407 static int rtw_wx_set_wap(struct net_device *dev,
2408 struct iw_request_info *info,
2409 union iwreq_data *awrq,
2414 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2415 struct sockaddr *temp = (struct sockaddr *)awrq;
2416 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2418 u8 *dst_bssid, *src_bssid;
2419 _queue *queue = &(pmlmepriv->scanned_queue);
2420 struct wlan_network *pnetwork = NULL;
2421 NDIS_802_11_AUTHENTICATION_MODE authmode;
2425 #ifdef CONFIG_CONCURRENT_MODE
2426 if(padapter->iface_type > PRIMARY_IFACE)
2434 #ifdef CONFIG_CONCURRENT_MODE
2435 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2437 DBG_871X("set bssid, but buddy_intf is under scanning or linking\n");
2445 rtw_ps_deny(padapter, PS_DENY_JOIN);
2446 if(_FAIL == rtw_pwr_wakeup(padapter))
2458 if (temp->sa_family != ARPHRD_ETHER){
2463 authmode = padapter->securitypriv.ndisauthtype;
2464 _enter_critical_bh(&queue->lock, &irqL);
2465 phead = get_list_head(queue);
2466 pmlmepriv->pscanned = get_next(phead);
2471 if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE)
2477 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
2479 rtw_set_802_11_bssid(padapter, temp->sa_data);
2492 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2494 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2496 dst_bssid = pnetwork->network.MacAddress;
2498 src_bssid = temp->sa_data;
2500 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE)
2502 if(!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode))
2505 _exit_critical_bh(&queue->lock, &irqL);
2513 _exit_critical_bh(&queue->lock, &irqL);
2515 rtw_set_802_11_authentication_mode(padapter, authmode);
2516 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2517 if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
2524 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2531 static int rtw_wx_get_wap(struct net_device *dev,
2532 struct iw_request_info *info,
2533 union iwreq_data *wrqu, char *extra)
2536 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2537 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2538 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2540 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
2542 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2544 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_wap\n"));
2548 if ( ((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) ||
2549 ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
2550 ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE) )
2553 _rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
2557 _rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
2566 static int rtw_wx_set_mlme(struct net_device *dev,
2567 struct iw_request_info *info,
2568 union iwreq_data *wrqu, char *extra)
2571 /* SIOCSIWMLME data */
2574 __u16 cmd; /* IW_MLME_* */
2576 struct sockaddr addr;
2582 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2583 struct iw_mlme *mlme = (struct iw_mlme *) extra;
2589 DBG_871X("%s\n", __FUNCTION__);
2591 reason = cpu_to_le16(mlme->reason_code);
2594 DBG_871X("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
2599 case IW_MLME_DEAUTH:
2600 if(!rtw_set_802_11_disassociate(padapter))
2604 case IW_MLME_DISASSOC:
2605 if(!rtw_set_802_11_disassociate(padapter))
2617 static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
2618 union iwreq_data *wrqu, char *extra)
2620 u8 _status = _FALSE;
2622 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2623 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
2624 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
2627 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2629 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_set_scan\n"));
2634 DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2637 #ifdef CONFIG_CONCURRENT_MODE
2638 if(padapter->iface_type > PRIMARY_IFACE)
2645 #ifdef CONFIG_MP_INCLUDED
2646 if (padapter->registrypriv.mp_mode == 1)
2648 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
2652 #ifdef CONFIG_CONCURRENT_MODE
2653 if (padapter->pbuddy_adapter) {
2654 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
2656 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
2661 #endif //CONFIG_CONCURRENT_MODE
2664 rtw_ps_deny(padapter, PS_DENY_SCAN);
2665 if(_FAIL == rtw_pwr_wakeup(padapter))
2671 if (rtw_is_drv_stopped(padapter)) {
2672 DBG_871X("%s bDriverStopped=_TRUE\n", __func__);
2682 if (!rtw_is_hw_init_completed(padapter)) {
2687 #ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC
2688 // When Busy Traffic, driver do not site survey. So driver return success.
2689 // wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout.
2690 // modify by thomas 2011-02-22.
2691 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE
2692 #ifdef CONFIG_CONCURRENT_MODE
2693 || rtw_get_buddy_bBusyTraffic(padapter) == _TRUE
2694 #endif //CONFIG_CONCURRENT_MODE
2697 indicate_wx_scan_complete_event(padapter);
2702 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2704 indicate_wx_scan_complete_event(padapter);
2708 #ifdef CONFIG_CONCURRENT_MODE
2709 if (check_buddy_fwstate(padapter,
2710 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2712 indicate_wx_scan_complete_event(padapter);
2718 if ( pwdinfo->p2p_state != P2P_STATE_NONE )
2720 rtw_p2p_set_pre_state( pwdinfo, rtw_p2p_state( pwdinfo ) );
2721 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2722 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2723 rtw_free_network_queue(padapter, _TRUE);
2727 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2729 #if WIRELESS_EXT >= 17
2730 if (wrqu->data.length == sizeof(struct iw_scan_req))
2732 struct iw_scan_req *req = (struct iw_scan_req *)extra;
2734 if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
2736 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2738 _rtw_memcpy(ssid[0].Ssid, req->essid, len);
2739 ssid[0].SsidLength = len;
2741 DBG_871X("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2743 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2745 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
2747 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2750 else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2752 DBG_871X("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2759 if( wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2760 && _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2763 int len = wrqu->data.length -WEXT_CSCAN_HEADER_SIZE;
2764 char *pos = extra+WEXT_CSCAN_HEADER_SIZE;
2769 //DBG_871X("%s COMBO_SCAN header is recognized\n", __FUNCTION__);
2772 section = *(pos++); len-=1;
2775 case WEXT_CSCAN_SSID_SECTION:
2776 //DBG_871X("WEXT_CSCAN_SSID_SECTION\n");
2782 sec_len = *(pos++); len-=1;
2784 if(sec_len>0 && sec_len<=len) {
2785 ssid[ssid_index].SsidLength = sec_len;
2786 _rtw_memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
2787 //DBG_871X("%s COMBO_SCAN with specific ssid:%s, %d\n", __FUNCTION__
2788 // , ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength);
2792 pos+=sec_len; len-=sec_len;
2796 case WEXT_CSCAN_CHANNEL_SECTION:
2797 //DBG_871X("WEXT_CSCAN_CHANNEL_SECTION\n");
2800 case WEXT_CSCAN_ACTV_DWELL_SECTION:
2801 //DBG_871X("WEXT_CSCAN_ACTV_DWELL_SECTION\n");
2804 case WEXT_CSCAN_PASV_DWELL_SECTION:
2805 //DBG_871X("WEXT_CSCAN_PASV_DWELL_SECTION\n");
2808 case WEXT_CSCAN_HOME_DWELL_SECTION:
2809 //DBG_871X("WEXT_CSCAN_HOME_DWELL_SECTION\n");
2812 case WEXT_CSCAN_TYPE_SECTION:
2813 //DBG_871X("WEXT_CSCAN_TYPE_SECTION\n");
2817 case WEXT_CSCAN_NPROBE_SECTION:
2818 DBG_871X("WEXT_CSCAN_NPROBE_SECTION\n");
2823 //DBG_871X("Unknown CSCAN section %c\n", section);
2824 len = 0; // stop parsing
2826 //DBG_871X("len:%d\n", len);
2830 //jeff: it has still some scan paramater to parse, we only do this now...
2831 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
2836 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
2839 if(_status == _FALSE)
2844 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2847 DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2855 static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2856 union iwreq_data *wrqu, char *extra)
2859 _list *plist, *phead;
2860 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2861 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2862 _queue *queue = &(pmlmepriv->scanned_queue);
2863 struct wlan_network *pnetwork = NULL;
2865 char *stop = ev + wrqu->data.length;
2868 u32 wait_for_surveydone;
2870 #ifdef CONFIG_CONCURRENT_MODE
2871 //PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
2872 //struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
2875 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
2877 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_scan\n"));
2878 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
2883 DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
2886 #ifdef CONFIG_CONCURRENT_MODE
2887 if(padapter->iface_type > PRIMARY_IFACE)
2894 if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) {
2900 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2902 wait_for_surveydone = 200;
2907 wait_for_surveydone = 100;
2911 wait_for_surveydone = 100;
2915 #if 1 // Wireless Extension use EAGAIN to try
2916 wait_status = _FW_UNDER_SURVEY
2917 #ifndef CONFIG_ANDROID
2922 while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2927 wait_status = _FW_UNDER_SURVEY
2928 #ifndef CONFIG_ANDROID
2933 while(check_fwstate(pmlmepriv, wait_status) == _TRUE)
2937 if(cnt > wait_for_surveydone )
2941 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2943 phead = get_list_head(queue);
2944 plist = get_next(phead);
2948 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
2951 if((stop - ev) < SCAN_ITEM_SIZE) {
2956 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2958 //report network only if the current channel set contains the channel to which this network belongs
2959 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2960 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
2961 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2964 ev=translate_scan(padapter, a, pnetwork, ev, stop);
2967 plist = get_next(plist);
2971 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2973 wrqu->data.length = ev-extra;
2974 wrqu->data.flags = 0;
2981 DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
2989 //s1. rtw_set_802_11_infrastructure_mode()
2990 //s2. set_802_11_authenticaion_mode()
2991 //s3. set_802_11_encryption_mode()
2992 //s4. rtw_set_802_11_ssid()
2993 static int rtw_wx_set_essid(struct net_device *dev,
2994 struct iw_request_info *a,
2995 union iwreq_data *wrqu, char *extra)
2998 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2999 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3000 _queue *queue = &pmlmepriv->scanned_queue;
3003 struct wlan_network *pnetwork = NULL;
3004 NDIS_802_11_AUTHENTICATION_MODE authmode;
3005 NDIS_802_11_SSID ndis_ssid;
3006 u8 *dst_ssid, *src_ssid;
3013 DBG_871X("DBG_IOCTL %s:%d\n",__FUNCTION__, __LINE__);
3015 #ifdef CONFIG_WEXT_DONT_JOIN_BYSSID
3016 DBG_871X("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);
3020 #ifdef CONFIG_CONCURRENT_MODE
3021 if(padapter->iface_type > PRIMARY_IFACE)
3029 #ifdef CONFIG_CONCURRENT_MODE
3030 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
3032 DBG_871X("set ssid, but buddy_intf is under scanning or linking\n");
3040 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
3041 ("+rtw_wx_set_essid: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
3043 rtw_ps_deny(padapter, PS_DENY_JOIN);
3044 if(_FAIL == rtw_pwr_wakeup(padapter))
3055 #if WIRELESS_EXT <= 20
3056 if ((wrqu->essid.length-1) > IW_ESSID_MAX_SIZE){
3058 if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
3064 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3069 authmode = padapter->securitypriv.ndisauthtype;
3070 DBG_871X("=>%s\n",__FUNCTION__);
3071 if (wrqu->essid.flags && wrqu->essid.length)
3073 // Commented by Albert 20100519
3074 // We got the codes in "set_info" function of iwconfig source code.
3075 // =========================================
3076 // wrq.u.essid.length = strlen(essid) + 1;
3077 // if(we_kernel_version > 20)
3078 // wrq.u.essid.length--;
3079 // =========================================
3080 // That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1.
3081 #if WIRELESS_EXT <= 20
3082 len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
3084 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
3087 if( wrqu->essid.length != 33 )
3088 DBG_871X("ssid=%s, len=%d\n", extra, wrqu->essid.length);
3090 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
3091 ndis_ssid.SsidLength = len;
3092 _rtw_memcpy(ndis_ssid.Ssid, extra, len);
3093 src_ssid = ndis_ssid.Ssid;
3095 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, ("rtw_wx_set_essid: ssid=[%s]\n", src_ssid));
3096 _enter_critical_bh(&queue->lock, &irqL);
3097 phead = get_list_head(queue);
3098 pmlmepriv->pscanned = get_next(phead);
3102 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
3105 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
3107 rtw_set_802_11_ssid(padapter, &ndis_ssid);
3113 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("rtw_wx_set_ssid(): scanned_queue is empty\n"));
3118 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_warning_,
3119 ("rtw_wx_set_essid: scan_q is empty, set ssid to check if scanning again!\n"));
3124 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
3126 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
3128 dst_ssid = pnetwork->network.Ssid.Ssid;
3130 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
3131 ("rtw_wx_set_essid: dst_ssid=%s\n",
3132 pnetwork->network.Ssid.Ssid));
3134 if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
3135 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
3137 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
3138 ("rtw_wx_set_essid: find match, set infra mode\n"));
3140 if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
3142 if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
3146 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
3149 _exit_critical_bh(&queue->lock, &irqL);
3156 _exit_critical_bh(&queue->lock, &irqL);
3157 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
3158 ("set ssid: set_802_11_auth. mode=%d\n", authmode));
3159 rtw_set_802_11_authentication_mode(padapter, authmode);
3160 //set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
3161 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
3169 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
3171 DBG_871X("<=%s, ret %d\n",__FUNCTION__, ret);
3174 DBG_871X("DBG_IOCTL %s:%d return %d\n",__FUNCTION__, __LINE__, ret);
3182 static int rtw_wx_get_essid(struct net_device *dev,
3183 struct iw_request_info *a,
3184 union iwreq_data *wrqu, char *extra)
3187 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3188 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3189 WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
3191 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_wx_get_essid\n"));
3195 if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
3196 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
3198 len = pcur_bss->Ssid.SsidLength;
3200 wrqu->essid.length = len;
3202 _rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
3204 wrqu->essid.flags = 1;
3220 static int rtw_wx_set_rate(struct net_device *dev,
3221 struct iw_request_info *a,
3222 union iwreq_data *wrqu, char *extra)
3225 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3226 u8 datarates[NumRates];
3227 u32 target_rate = wrqu->bitrate.value;
3228 u32 fixed = wrqu->bitrate.fixed;
3230 u8 mpdatarate[NumRates]={11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
3234 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,(" rtw_wx_set_rate \n"));
3235 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("target_rate = %d, fixed = %d\n",target_rate,fixed));
3237 if(target_rate == -1){
3241 target_rate = target_rate/100000;
3243 switch(target_rate){
3287 for(i=0; i<NumRates; i++)
3289 if(ratevalue==mpdatarate[i])
3291 datarates[i] = mpdatarate[i];
3296 datarates[i] = 0xff;
3299 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("datarate_inx=%d\n",datarates[i]));
3302 if( rtw_setdatarate_cmd(padapter, datarates) !=_SUCCESS){
3303 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("rtw_wx_set_rate Fail!!!\n"));
3312 static int rtw_wx_get_rate(struct net_device *dev,
3313 struct iw_request_info *info,
3314 union iwreq_data *wrqu, char *extra)
3318 max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
3323 wrqu->bitrate.fixed = 0; /* no auto select */
3324 wrqu->bitrate.value = max_rate * 100000;
3329 static int rtw_wx_set_rts(struct net_device *dev,
3330 struct iw_request_info *info,
3331 union iwreq_data *wrqu, char *extra)
3333 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3337 if (wrqu->rts.disabled)
3338 padapter->registrypriv.rts_thresh = 2347;
3340 if (wrqu->rts.value < 0 ||
3341 wrqu->rts.value > 2347)
3344 padapter->registrypriv.rts_thresh = wrqu->rts.value;
3347 DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
3355 static int rtw_wx_get_rts(struct net_device *dev,
3356 struct iw_request_info *info,
3357 union iwreq_data *wrqu, char *extra)
3359 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3363 DBG_871X("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
3365 wrqu->rts.value = padapter->registrypriv.rts_thresh;
3366 wrqu->rts.fixed = 0; /* no auto select */
3367 //wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
3374 static int rtw_wx_set_frag(struct net_device *dev,
3375 struct iw_request_info *info,
3376 union iwreq_data *wrqu, char *extra)
3378 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3382 if (wrqu->frag.disabled)
3383 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
3385 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
3386 wrqu->frag.value > MAX_FRAG_THRESHOLD)
3389 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
3392 DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
3400 static int rtw_wx_get_frag(struct net_device *dev,
3401 struct iw_request_info *info,
3402 union iwreq_data *wrqu, char *extra)
3404 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3408 DBG_871X("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
3410 wrqu->frag.value = padapter->xmitpriv.frag_len;
3411 wrqu->frag.fixed = 0; /* no auto select */
3412 //wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
3419 static int rtw_wx_get_retry(struct net_device *dev,
3420 struct iw_request_info *info,
3421 union iwreq_data *wrqu, char *extra)
3423 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3426 wrqu->retry.value = 7;
3427 wrqu->retry.fixed = 0; /* no auto select */
3428 wrqu->retry.disabled = 1;
3435 #define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
3436 #define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
3437 #define IW_ENCODE_MODE 0xF000 /* Modes defined below */
3438 #define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
3439 #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
3440 #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
3441 #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
3442 #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
3443 #define IW_ENCODE_TEMP 0x0400 /* Temporary key */
3445 iwconfig wlan0 key on -> flags = 0x6001 -> maybe it means auto
3446 iwconfig wlan0 key off -> flags = 0x8800
3447 iwconfig wlan0 key open -> flags = 0x2800
3448 iwconfig wlan0 key open 1234567890 -> flags = 0x2000
3449 iwconfig wlan0 key restricted -> flags = 0x4800
3450 iwconfig wlan0 key open [3] 1234567890 -> flags = 0x2003
3451 iwconfig wlan0 key restricted [2] 1234567890 -> flags = 0x4002
3452 iwconfig wlan0 key open [3] -> flags = 0x2803
3453 iwconfig wlan0 key restricted [2] -> flags = 0x4802
3457 static int rtw_wx_set_enc(struct net_device *dev,
3458 struct iw_request_info *info,
3459 union iwreq_data *wrqu, char *keybuf)
3462 u32 keyindex_provided;
3463 NDIS_802_11_WEP wep;
3464 NDIS_802_11_AUTHENTICATION_MODE authmode;
3466 struct iw_point *erq = &(wrqu->encoding);
3467 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3468 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
3469 DBG_871X("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
3471 _rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
3473 key = erq->flags & IW_ENCODE_INDEX;
3477 if (erq->flags & IW_ENCODE_DISABLED)
3479 DBG_871X("EncryptionDisabled\n");
3480 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3481 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3482 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3483 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3484 authmode = Ndis802_11AuthModeOpen;
3485 padapter->securitypriv.ndisauthtype=authmode;
3494 keyindex_provided = 1;
3498 keyindex_provided = 0;
3499 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3500 DBG_871X("rtw_wx_set_enc, key=%d\n", key);
3503 //set authentication mode
3504 if(erq->flags & IW_ENCODE_OPEN)
3506 DBG_871X("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
3507 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3509 #ifdef CONFIG_PLATFORM_MT53XX
3510 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3512 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open;
3515 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3516 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3517 authmode = Ndis802_11AuthModeOpen;
3518 padapter->securitypriv.ndisauthtype=authmode;
3520 else if(erq->flags & IW_ENCODE_RESTRICTED)
3522 DBG_871X("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
3523 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3525 #ifdef CONFIG_PLATFORM_MT53XX
3526 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3528 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Shared;
3531 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
3532 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
3533 authmode = Ndis802_11AuthModeShared;
3534 padapter->securitypriv.ndisauthtype=authmode;
3538 DBG_871X("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
3540 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;//Ndis802_11EncryptionDisabled;
3541 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3542 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3543 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3544 authmode = Ndis802_11AuthModeOpen;
3545 padapter->securitypriv.ndisauthtype=authmode;
3549 if (erq->length > 0)
3551 wep.KeyLength = erq->length <= 5 ? 5 : 13;
3553 wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
3559 if(keyindex_provided == 1)// set key_id only, no given KeyMaterial(erq->length==0).
3561 padapter->securitypriv.dot11PrivacyKeyIndex = key;
3563 DBG_871X("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
3565 switch(padapter->securitypriv.dot11DefKeylen[key])
3568 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
3571 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
3574 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3584 wep.KeyIndex |= 0x80000000;
3586 _rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
3588 if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
3589 if(rf_on == pwrpriv->rf_pwrstate )
3602 static int rtw_wx_get_enc(struct net_device *dev,
3603 struct iw_request_info *info,
3604 union iwreq_data *wrqu, char *keybuf)
3607 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3608 struct iw_point *erq = &(wrqu->encoding);
3609 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3613 if(check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
3615 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE)
3618 erq->flags |= IW_ENCODE_DISABLED;
3624 key = erq->flags & IW_ENCODE_INDEX;
3632 key = padapter->securitypriv.dot11PrivacyKeyIndex;
3635 erq->flags = key + 1;
3637 //if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3639 // erq->flags |= IW_ENCODE_OPEN;
3642 switch(padapter->securitypriv.ndisencryptstatus)
3644 case Ndis802_11EncryptionNotSupported:
3645 case Ndis802_11EncryptionDisabled:
3648 erq->flags |= IW_ENCODE_DISABLED;
3652 case Ndis802_11Encryption1Enabled:
3654 erq->length = padapter->securitypriv.dot11DefKeylen[key];
3658 _rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
3660 erq->flags |= IW_ENCODE_ENABLED;
3662 if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
3664 erq->flags |= IW_ENCODE_OPEN;
3666 else if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
3668 erq->flags |= IW_ENCODE_RESTRICTED;
3674 erq->flags |= IW_ENCODE_DISABLED;
3679 case Ndis802_11Encryption2Enabled:
3680 case Ndis802_11Encryption3Enabled:
3683 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
3689 erq->flags |= IW_ENCODE_DISABLED;
3701 static int rtw_wx_get_power(struct net_device *dev,
3702 struct iw_request_info *info,
3703 union iwreq_data *wrqu, char *extra)
3705 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3707 wrqu->power.value = 0;
3708 wrqu->power.fixed = 0; /* no auto select */
3709 wrqu->power.disabled = 1;
3715 static int rtw_wx_set_gen_ie(struct net_device *dev,
3716 struct iw_request_info *info,
3717 union iwreq_data *wrqu, char *extra)
3720 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3722 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
3727 static int rtw_wx_set_auth(struct net_device *dev,
3728 struct iw_request_info *info,
3729 union iwreq_data *wrqu, char *extra)
3731 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3732 struct iw_param *param = (struct iw_param*)&(wrqu->param);
3733 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3734 struct security_priv *psecuritypriv = &padapter->securitypriv;
3735 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3736 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3737 u32 value = param->value;
3740 switch (param->flags & IW_AUTH_INDEX) {
3742 case IW_AUTH_WPA_VERSION:
3743 #ifdef CONFIG_WAPI_SUPPORT
3744 #ifndef CONFIG_IOCTL_CFG80211
3745 padapter->wapiInfo.bWapiEnable = false;
3746 if(value == IW_AUTH_WAPI_VERSION_1)
3748 padapter->wapiInfo.bWapiEnable = true;
3749 psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
3750 psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
3751 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3752 pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
3753 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3754 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3759 case IW_AUTH_CIPHER_PAIRWISE:
3762 case IW_AUTH_CIPHER_GROUP:
3765 case IW_AUTH_KEY_MGMT:
3766 #ifdef CONFIG_WAPI_SUPPORT
3767 #ifndef CONFIG_IOCTL_CFG80211
3768 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case \n");
3769 if(value == IW_AUTH_KEY_MGMT_WAPI_PSK)
3770 padapter->wapiInfo.bWapiPSK = true;
3772 padapter->wapiInfo.bWapiPSK = false;
3773 DBG_871X("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d \n",padapter->wapiInfo.bWapiPSK);
3777 * ??? does not use these parameters
3781 case IW_AUTH_TKIP_COUNTERMEASURES:
3784 { // wpa_supplicant is enabling the tkip countermeasure.
3785 padapter->securitypriv.btkip_countermeasure = _TRUE;
3788 { // wpa_supplicant is disabling the tkip countermeasure.
3789 padapter->securitypriv.btkip_countermeasure = _FALSE;
3793 case IW_AUTH_DROP_UNENCRYPTED:
3797 * wpa_supplicant calls set_wpa_enabled when the driver
3798 * is loaded and unloaded, regardless of if WPA is being
3799 * used. No other calls are made which can be used to
3800 * determine if encryption will be used or not prior to
3801 * association being expected. If encryption is not being
3802 * used, drop_unencrypted is set to false, else true -- we
3803 * can use this to determine if the CAP_PRIVACY_ON bit should
3807 if(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
3809 break;//it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled,
3810 // then it needn't reset it;
3814 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3815 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
3816 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
3817 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_Open; //open system
3818 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeOpen;
3824 case IW_AUTH_80211_AUTH_ALG:
3826 #if defined(CONFIG_ANDROID) || 1
3828 * It's the starting point of a link layer connection using wpa_supplicant
3830 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3831 LeaveAllPowerSaveMode(padapter);
3832 rtw_disassoc_cmd(padapter, 500, _FALSE);
3833 DBG_871X("%s...call rtw_indicate_disconnect\n ",__FUNCTION__);
3834 rtw_indicate_disconnect(padapter, 0, _FALSE);
3835 rtw_free_assoc_resources(padapter, 1);
3840 ret = wpa_set_auth_algs(dev, (u32)param->value);
3844 case IW_AUTH_WPA_ENABLED:
3847 // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; //802.1x
3849 // padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;//open system
3851 //_disassociate(priv);
3855 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3856 //ieee->ieee802_1x = param->value;
3859 case IW_AUTH_PRIVACY_INVOKED:
3860 //ieee->privacy_invoked = param->value;
3863 #ifdef CONFIG_WAPI_SUPPORT
3864 #ifndef CONFIG_IOCTL_CFG80211
3865 case IW_AUTH_WAPI_ENABLED:
3879 static int rtw_wx_set_enc_ext(struct net_device *dev,
3880 struct iw_request_info *info,
3881 union iwreq_data *wrqu, char *extra)
3885 struct ieee_param *param = NULL;
3886 struct iw_point *pencoding = &wrqu->encoding;
3887 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3890 param_len = sizeof(struct ieee_param) + pext->key_len;
3891 param = (struct ieee_param *)rtw_malloc(param_len);
3895 _rtw_memset(param, 0, param_len);
3897 param->cmd = IEEE_CMD_SET_ENCRYPTION;
3898 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3901 switch (pext->alg) {
3902 case IW_ENCODE_ALG_NONE:
3907 case IW_ENCODE_ALG_WEP:
3910 case IW_ENCODE_ALG_TKIP:
3913 case IW_ENCODE_ALG_CCMP:
3916 #ifdef CONFIG_IEEE80211W
3917 case IW_ENCODE_ALG_AES_CMAC:
3920 #endif //CONFIG_IEEE80211W
3921 #ifdef CONFIG_WAPI_SUPPORT
3922 #ifndef CONFIG_IOCTL_CFG80211
3923 case IW_ENCODE_ALG_SM4:
3925 _rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3926 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
3935 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3937 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3939 param->u.crypt.set_tx = 1;
3942 /* cliW: WEP does not have group key
3943 * just not checking GROUP key setting
3945 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3946 ((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3947 #ifdef CONFIG_IEEE80211W
3948 || (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3949 #endif //CONFIG_IEEE80211W
3952 param->u.crypt.set_tx = 0;
3955 param->u.crypt.idx = (pencoding->flags&0x00FF) -1 ;
3957 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
3959 #ifdef CONFIG_WAPI_SUPPORT
3960 #ifndef CONFIG_IOCTL_CFG80211
3961 if(pext->alg == IW_ENCODE_ALG_SM4)
3962 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3964 #endif //CONFIG_IOCTL_CFG80211
3965 #endif //CONFIG_WAPI_SUPPORT
3966 _rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3971 param->u.crypt.key_len = pext->key_len;
3972 //_rtw_memcpy(param + 1, pext + 1, pext->key_len);
3973 _rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3976 if (pencoding->flags & IW_ENCODE_DISABLED)
3982 ret = wpa_set_encryption(dev, param, param_len);
3987 rtw_mfree((u8*)param, param_len);
3994 static int rtw_wx_get_nick(struct net_device *dev,
3995 struct iw_request_info *info,
3996 union iwreq_data *wrqu, char *extra)
3998 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3999 //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4000 //struct security_priv *psecuritypriv = &padapter->securitypriv;
4004 wrqu->data.length = 14;
4005 wrqu->data.flags = 1;
4006 _rtw_memcpy(extra, "<WIFI@REALTEK>", 14);
4009 //rtw_signal_process(pid, SIGUSR1); //for test
4011 //dump debug info here
4013 u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, and 8021x
4014 u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm.
4015 u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key
4017 u32 ndisencryptstatus;
4020 //DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
4021 // psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
4022 // psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
4024 //DBG_871X("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm);
4025 //DBG_871X("auth_type=0x%x\n", psecuritypriv->ndisauthtype);
4026 //DBG_871X("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus);
4029 DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
4030 DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
4031 DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
4032 DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
4033 DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
4035 DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
4040 DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
4041 DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
4043 DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
4045 DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
4047 DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
4048 DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
4050 DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
4051 DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
4052 DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
4053 DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
4060 static int rtw_wx_read32(struct net_device *dev,
4061 struct iw_request_info *info,
4062 union iwreq_data *wrqu, char *extra)
4075 padapter = (PADAPTER)rtw_netdev_priv(dev);
4081 ptmp = (u8*)rtw_malloc(len);
4085 if (copy_from_user(ptmp, p->pointer, len)) {
4092 sscanf(ptmp, "%d,%x", &bytes, &addr);
4096 data32 = rtw_read8(padapter, addr);
4097 sprintf(extra, "0x%02X", data32);
4100 data32 = rtw_read16(padapter, addr);
4101 sprintf(extra, "0x%04X", data32);
4104 data32 = rtw_read32(padapter, addr);
4105 sprintf(extra, "0x%08X", data32);
4108 DBG_871X(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
4112 DBG_871X(KERN_INFO "%s: addr=0x%08X data=%s\n", __func__, addr, extra);
4115 rtw_mfree(ptmp, len);
4120 static int rtw_wx_write32(struct net_device *dev,
4121 struct iw_request_info *info,
4122 union iwreq_data *wrqu, char *extra)
4124 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
4134 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
4138 rtw_write8(padapter, addr, (u8)data32);
4139 DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
4142 rtw_write16(padapter, addr, (u16)data32);
4143 DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
4146 rtw_write32(padapter, addr, data32);
4147 DBG_871X(KERN_INFO "%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
4150 DBG_871X(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
4157 static int rtw_wx_read_rf(struct net_device *dev,
4158 struct iw_request_info *info,
4159 union iwreq_data *wrqu, char *extra)
4161 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4162 u32 path, addr, data32;
4165 path = *(u32*)extra;
4166 addr = *((u32*)extra + 1);
4167 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
4168 // DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
4171 * Only when wireless private ioctl is at odd order,
4172 * "extra" would be copied to user space.
4174 sprintf(extra, "0x%05x", data32);
4179 static int rtw_wx_write_rf(struct net_device *dev,
4180 struct iw_request_info *info,
4181 union iwreq_data *wrqu, char *extra)
4183 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4184 u32 path, addr, data32;
4187 path = *(u32*)extra;
4188 addr = *((u32*)extra + 1);
4189 data32 = *((u32*)extra + 2);
4190 // DBG_871X("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32);
4191 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
4196 static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
4197 union iwreq_data *wrqu, char *b)
4202 static int dummy(struct net_device *dev, struct iw_request_info *a,
4203 union iwreq_data *wrqu, char *b)
4205 //_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4206 //struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4208 //DBG_871X("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv));
4214 static int rtw_wx_set_channel_plan(struct net_device *dev,
4215 struct iw_request_info *info,
4216 union iwreq_data *wrqu, char *extra)
4218 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4219 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4220 u8 channel_plan_req = (u8) (*((int *)wrqu));
4222 if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req))
4228 static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
4229 struct iw_request_info *a,
4230 union iwreq_data *wrqu, char *b)
4232 #ifdef CONFIG_PLATFORM_MT53XX
4233 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4234 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4236 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
4237 ("WLAN IOCTL: cmd_code=%x, fwstate=0x%x\n",
4238 a->cmd, get_fwstate(pmlmepriv)));
4243 static int rtw_wx_get_sensitivity(struct net_device *dev,
4244 struct iw_request_info *info,
4245 union iwreq_data *wrqu, char *buf)
4247 #ifdef CONFIG_PLATFORM_MT53XX
4248 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4250 // Modified by Albert 20110914
4251 // This is in dbm format for MTK platform.
4252 wrqu->qual.level = padapter->recvpriv.rssi;
4253 DBG_871X(" level = %u\n", wrqu->qual.level );
4258 static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
4259 struct iw_request_info *info,
4260 union iwreq_data *wrqu, char *extra)
4262 #ifdef CONFIG_PLATFORM_MT53XX
4263 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4265 return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
4272 typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
4273 union iwreq_data *wrqu, char *extra);
4276 * For all data larger than 16 octets, we need to use a
4277 * pointer to memory allocated in user space.
4279 static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
4280 union iwreq_data *wrqu, char *extra)
4286 void __user *pointer; /* Pointer to the data (in user space) */
4287 __u16 length; /* number of fields or size in bytes */
4288 __u16 flags; /* Optional params */
4292 #ifdef CONFIG_DRVEXT_MODULE
4294 struct drvext_handler *phandler;
4295 struct drvext_oidparam *poidparam;
4299 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4300 struct iw_point *p = &wrqu->data;
4302 if( (!p->length) || (!p->pointer)){
4304 goto _rtw_drvext_hdl_exit;
4308 bset = (u8)(p->flags&0xFFFF);
4310 pparmbuf = (u8*)rtw_malloc(len);
4311 if (pparmbuf == NULL){
4313 goto _rtw_drvext_hdl_exit;
4318 if (copy_from_user(pparmbuf, p->pointer,len)) {
4319 rtw_mfree(pparmbuf, len);
4321 goto _rtw_drvext_hdl_exit;
4331 poidparam = (struct drvext_oidparam *)pparmbuf;
4333 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("drvext set oid subcode [%d], len[%d], InformationBufferLength[%d]\r\n",
4334 poidparam->subcode, poidparam->len, len));
4338 if ( poidparam->subcode >= MAX_DRVEXT_HANDLERS)
4340 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext handlers\r\n"));
4342 goto _rtw_drvext_hdl_exit;
4346 if ( poidparam->subcode >= MAX_DRVEXT_OID_SUBCODES)
4348 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext subcodes\r\n"));
4350 goto _rtw_drvext_hdl_exit;
4354 phandler = drvextoidhandlers + poidparam->subcode;
4356 if (poidparam->len != phandler->parmsize)
4358 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("no matching drvext param size %d vs %d\r\n",
4359 poidparam->len , phandler->parmsize));
4361 goto _rtw_drvext_hdl_exit;
4365 res = phandler->handler(&padapter->drvextpriv, bset, poidparam->data);
4371 if (bset == 0x00) {//query info
4372 //_rtw_memcpy(p->pointer, pparmbuf, len);
4373 if (copy_to_user(p->pointer, pparmbuf, len))
4381 _rtw_drvext_hdl_exit:
4391 static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
4393 pRW_Reg RegRWStruct;
4394 struct rf_reg_param *prfreg;
4399 DBG_871X("%s\n", __FUNCTION__);
4403 case GEN_MP_IOCTL_SUBCODE(MP_START):
4404 DBG_871X("871x_driver is only for normal mode, can't enter mp mode\n");
4406 case GEN_MP_IOCTL_SUBCODE(READ_REG):
4407 RegRWStruct = (pRW_Reg)pdata;
4408 switch (RegRWStruct->width)
4411 RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
4414 RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
4417 RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
4424 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
4425 RegRWStruct = (pRW_Reg)pdata;
4426 switch (RegRWStruct->width)
4429 rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
4432 rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
4435 rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
4442 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
4444 prfreg = (struct rf_reg_param *)pdata;
4446 path = (u8)prfreg->path;
4447 offset = (u8)prfreg->offset;
4449 value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
4451 prfreg->value = value;
4454 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
4456 prfreg = (struct rf_reg_param *)pdata;
4458 path = (u8)prfreg->path;
4459 offset = (u8)prfreg->offset;
4460 value = prfreg->value;
4462 rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
4465 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
4466 DBG_871X("==> trigger gpio 0\n");
4467 rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
4469 #ifdef CONFIG_BT_COEXIST
4470 case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):
4471 DBG_871X("==> set dm_bt_coexist:%x\n",*(u8 *)pdata);
4472 rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
4474 case GEN_MP_IOCTL_SUBCODE(DEL_BA):
4475 DBG_871X("==> delete ba:%x\n",*(u8 *)pdata);
4476 rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
4479 #ifdef DBG_CONFIG_ERROR_DETECT
4480 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
4481 *pdata = rtw_hal_sreset_get_wifi_status(padapter);
4491 static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
4492 union iwreq_data *wrqu, char *extra)
4495 u32 BytesRead, BytesWritten, BytesNeeded;
4496 struct oid_par_priv oid_par;
4497 struct mp_ioctl_handler *phandler;
4498 struct mp_ioctl_param *poidparam;
4501 u8 *pparmbuf = NULL, bset;
4502 PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
4503 struct iw_point *p = &wrqu->data;
4505 //DBG_871X("+rtw_mp_ioctl_hdl\n");
4507 //mutex_lock(&ioctl_mutex);
4509 if ((!p->length) || (!p->pointer)) {
4511 goto _rtw_mp_ioctl_hdl_exit;
4515 bset = (u8)(p->flags & 0xFFFF);
4517 pparmbuf = (u8*)rtw_malloc(len);
4518 if (pparmbuf == NULL){
4520 goto _rtw_mp_ioctl_hdl_exit;
4523 if (copy_from_user(pparmbuf, p->pointer, len)) {
4525 goto _rtw_mp_ioctl_hdl_exit;
4528 poidparam = (struct mp_ioctl_param *)pparmbuf;
4529 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
4530 ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n",
4531 poidparam->subcode, poidparam->len, len));
4533 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
4534 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n"));
4536 goto _rtw_mp_ioctl_hdl_exit;
4539 //DBG_871X("%s: %d\n", __func__, poidparam->subcode);
4540 #ifdef CONFIG_MP_INCLUDED
4541 if (padapter->registrypriv.mp_mode == 1)
4543 phandler = mp_ioctl_hdl + poidparam->subcode;
4545 if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize))
4547 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
4548 ("no matching drvext param size %d vs %d\r\n",
4549 poidparam->len, phandler->paramsize));
4551 goto _rtw_mp_ioctl_hdl_exit;
4554 if (phandler->handler)
4556 oid_par.adapter_context = padapter;
4557 oid_par.oid = phandler->oid;
4558 oid_par.information_buf = poidparam->data;
4559 oid_par.information_buf_len = poidparam->len;
4566 oid_par.bytes_rw = &BytesRead;
4567 oid_par.bytes_needed = &BytesNeeded;
4568 oid_par.type_of_oid = SET_OID;
4570 oid_par.bytes_rw = &BytesWritten;
4571 oid_par.bytes_needed = &BytesNeeded;
4572 oid_par.type_of_oid = QUERY_OID;
4575 status = phandler->handler(&oid_par);
4577 //todo:check status, BytesNeeded, etc.
4580 DBG_871X("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",
4581 poidparam->subcode, phandler->oid, phandler->handler);
4583 goto _rtw_mp_ioctl_hdl_exit;
4589 rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
4592 if (bset == 0x00) {//query info
4593 if (copy_to_user(p->pointer, pparmbuf, len))
4599 goto _rtw_mp_ioctl_hdl_exit;
4602 _rtw_mp_ioctl_hdl_exit:
4605 rtw_mfree(pparmbuf, len);
4607 //mutex_unlock(&ioctl_mutex);
4612 static int rtw_get_ap_info(struct net_device *dev,
4613 struct iw_request_info *info,
4614 union iwreq_data *wrqu, char *extra)
4616 int bssid_match, ret = 0;
4617 u32 cnt=0, wpa_ielen;
4619 _list *plist, *phead;
4620 unsigned char *pbuf;
4623 struct wlan_network *pnetwork = NULL;
4624 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4625 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4626 _queue *queue = &(pmlmepriv->scanned_queue);
4627 struct iw_point *pdata = &wrqu->data;
4629 DBG_871X("+rtw_get_aplist_info\n");
4631 if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
4636 while((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) == _TRUE)
4645 //pdata->length = 0;//?
4647 if(pdata->length>=32)
4649 if(copy_from_user(data, pdata->pointer, 32))
4661 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4663 phead = get_list_head(queue);
4664 plist = get_next(phead);
4668 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
4672 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4674 //if(hwaddr_aton_i(pdata->pointer, bssid))
4675 if(hwaddr_aton_i(data, bssid))
4677 DBG_871X("Invalid BSSID '%s'.\n", (u8*)data);
4678 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4683 if(_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)//BSSID match, then check if supporting wpa/wpa2
4685 DBG_871X("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
4687 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
4688 if(pbuf && (wpa_ielen>0))
4694 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength-12);
4695 if(pbuf && (wpa_ielen>0))
4703 plist = get_next(plist);
4707 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4709 if(pdata->length>=34)
4711 if(copy_to_user((u8*)pdata->pointer+32, (u8*)&pdata->flags, 1))
4724 static int rtw_set_pid(struct net_device *dev,
4725 struct iw_request_info *info,
4726 union iwreq_data *wrqu, char *extra)
4730 _adapter *padapter = rtw_netdev_priv(dev);
4731 int *pdata = (int *)wrqu;
4734 if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
4740 if(selector < 3 && selector >=0) {
4741 padapter->pid[selector] = *(pdata+1);
4742 #ifdef CONFIG_GLOBAL_UI_PID
4743 ui_pid[selector] = *(pdata+1);
4745 DBG_871X("%s set pid[%d]=%d\n", __FUNCTION__, selector ,padapter->pid[selector]);
4748 DBG_871X("%s selector %d error\n", __FUNCTION__, selector);
4756 static int rtw_wps_start(struct net_device *dev,
4757 struct iw_request_info *info,
4758 union iwreq_data *wrqu, char *extra)
4762 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4763 struct iw_point *pdata = &wrqu->data;
4764 u32 u32wps_start = 0;
4765 unsigned int uintRet = 0;
4767 if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) {
4772 uintRet = copy_from_user( ( void* ) &u32wps_start, pdata->pointer, 4 );
4773 if ( u32wps_start == 0 )
4775 u32wps_start = *extra;
4778 DBG_871X( "[%s] wps_start = %d\n", __FUNCTION__, u32wps_start );
4780 if ( u32wps_start == 1 ) // WPS Start
4782 rtw_led_control(padapter, LED_CTL_START_WPS);
4784 else if ( u32wps_start == 2 ) // WPS Stop because of wps success
4786 rtw_led_control(padapter, LED_CTL_STOP_WPS);
4788 else if ( u32wps_start == 3 ) // WPS Stop because of wps fail
4790 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
4793 #ifdef CONFIG_INTEL_WIDI
4794 process_intel_widi_wps_status(padapter, u32wps_start);
4795 #endif //CONFIG_INTEL_WIDI
4804 static int rtw_wext_p2p_enable(struct net_device *dev,
4805 struct iw_request_info *info,
4806 union iwreq_data *wrqu, char *extra)
4810 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4811 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4812 struct iw_point *pdata = &wrqu->data;
4813 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4814 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4815 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
4818 init_role = P2P_ROLE_DISABLE;
4819 else if(*extra == '1')
4820 init_role = P2P_ROLE_DEVICE;
4821 else if(*extra == '2')
4822 init_role = P2P_ROLE_CLIENT;
4823 else if(*extra == '3')
4824 init_role = P2P_ROLE_GO;
4826 if(_FAIL == rtw_p2p_enable(padapter, init_role))
4832 //set channel/bandwidth
4833 if(init_role != P2P_ROLE_DISABLE)
4835 u8 channel, ch_offset;
4838 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN))
4840 // Stay at the listen state and wait for discovery.
4841 channel = pwdinfo->listen_channel;
4842 pwdinfo->operating_channel = pwdinfo->listen_channel;
4843 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4844 bwmode = CHANNEL_WIDTH_20;
4846 #ifdef CONFIG_CONCURRENT_MODE
4847 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
4849 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4850 //struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
4851 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
4852 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4854 _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
4855 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
4857 pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
4858 // How about the ch_offset and bwmode ??
4862 pwdinfo->operating_channel = pwdinfo->listen_channel;
4865 channel = pbuddy_mlmeext->cur_channel;
4866 ch_offset = pbuddy_mlmeext->cur_ch_offset;
4867 bwmode = pbuddy_mlmeext->cur_bwmode;
4872 pwdinfo->operating_channel = pmlmeext->cur_channel;
4874 channel = pwdinfo->operating_channel;
4875 ch_offset = pmlmeext->cur_ch_offset;
4876 bwmode = pmlmeext->cur_bwmode;
4879 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
4887 static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
4888 struct iw_request_info *info,
4889 union iwreq_data *wrqu, char *extra)
4893 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4894 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4895 struct iw_point *pdata = &wrqu->data;
4896 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4898 DBG_871X( "[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen( extra ) );
4899 _rtw_memcpy( pwdinfo->nego_ssid, extra, strlen( extra ) );
4900 pwdinfo->nego_ssidlen = strlen( extra );
4907 static int rtw_p2p_set_intent(struct net_device *dev,
4908 struct iw_request_info *info,
4909 union iwreq_data *wrqu, char *extra)
4912 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4913 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4914 u8 intent = pwdinfo->intent;
4916 extra[ wrqu->data.length ] = 0x00;
4918 intent = rtw_atoi( extra );
4922 pwdinfo->intent= intent;
4929 DBG_871X( "[%s] intent = %d\n", __FUNCTION__, intent);
4935 static int rtw_p2p_set_listen_ch(struct net_device *dev,
4936 struct iw_request_info *info,
4937 union iwreq_data *wrqu, char *extra)
4941 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4942 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4943 u8 listen_ch = pwdinfo->listen_channel; // Listen channel number
4945 extra[ wrqu->data.length ] = 0x00;
4946 listen_ch = rtw_atoi( extra );
4948 if ( ( listen_ch == 1 ) || ( listen_ch == 6 ) || ( listen_ch == 11 ) )
4950 pwdinfo->listen_channel = listen_ch;
4951 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4958 DBG_871X( "[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel );
4964 static int rtw_p2p_set_op_ch(struct net_device *dev,
4965 struct iw_request_info *info,
4966 union iwreq_data *wrqu, char *extra)
4968 // Commented by Albert 20110524
4969 // This function is used to set the operating channel if the driver will become the group owner
4972 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4973 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4974 u8 op_ch = pwdinfo->operating_channel; // Operating channel number
4976 extra[ wrqu->data.length ] = 0x00;
4978 op_ch = ( u8 ) rtw_atoi( extra );
4981 pwdinfo->operating_channel = op_ch;
4988 DBG_871X( "[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel );
4995 static int rtw_p2p_profilefound(struct net_device *dev,
4996 struct iw_request_info *info,
4997 union iwreq_data *wrqu, char *extra)
5001 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5002 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5004 // Comment by Albert 2010/10/13
5005 // Input data format:
5007 // Ex: 1XX:XX:XX:XX:XX:XXYYSSID
5008 // 0 => Reflush the profile record list.
5009 // 1 => Add the profile list
5010 // XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 )
5011 // YY => SSID Length
5012 // SSID => SSID for persistence group
5014 DBG_871X( "[%s] In value = %s, len = %d \n", __FUNCTION__, extra, wrqu->data.length -1);
5017 // The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function.
5018 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5020 if ( extra[ 0 ] == '0' )
5022 // Remove all the profile information of wifidirect_info structure.
5023 _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
5024 pwdinfo->profileindex = 0;
5028 if ( pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM )
5036 // Add this profile information into pwdinfo->profileinfo
5037 // Ex: 1XX:XX:XX:XX:XX:XXYYSSID
5038 for( jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3 )
5040 pwdinfo->profileinfo[ pwdinfo->profileindex ].peermac[ jj ] = key_2char2num(extra[ kk ], extra[ kk+ 1 ]);
5043 //pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[ 19 ] - '0' );
5044 //_rtw_memcpy( pwdinfo->profileinfo[ pwdinfo->profileindex ].ssid, &extra[ 20 ], pwdinfo->profileinfo[ pwdinfo->profileindex ].ssidlen );
5045 pwdinfo->profileindex++;
5054 static int rtw_p2p_setDN(struct net_device *dev,
5055 struct iw_request_info *info,
5056 union iwreq_data *wrqu, char *extra)
5060 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5061 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5064 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
5065 _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
5066 _rtw_memcpy( pwdinfo->device_name, extra, wrqu->data.length - 1 );
5067 pwdinfo->device_name_len = wrqu->data.length - 1;
5074 static int rtw_p2p_get_status(struct net_device *dev,
5075 struct iw_request_info *info,
5076 union iwreq_data *wrqu, char *extra)
5080 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5081 struct iw_point *pdata = &wrqu->data;
5082 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5083 #ifdef CONFIG_CONCURRENT_MODE
5084 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5085 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5086 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5087 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5090 if ( padapter->bShowGetP2PState )
5092 DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
5093 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
5094 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
5097 // Commented by Albert 2010/10/12
5098 // Because of the output size limitation, I had removed the "Role" information.
5099 // About the "Role" information, we will use the new private IOCTL to get the "Role" information.
5100 sprintf( extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo) );
5101 wrqu->data.length = strlen( extra );
5107 // Commented by Albert 20110520
5108 // This function will return the config method description
5109 // This config method description will show us which config method the remote P2P device is intented to use
5110 // by sending the provisioning discovery request frame.
5112 static int rtw_p2p_get_req_cm(struct net_device *dev,
5113 struct iw_request_info *info,
5114 union iwreq_data *wrqu, char *extra)
5118 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5119 struct iw_point *pdata = &wrqu->data;
5120 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5122 sprintf( extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
5123 wrqu->data.length = strlen( extra );
5129 static int rtw_p2p_get_role(struct net_device *dev,
5130 struct iw_request_info *info,
5131 union iwreq_data *wrqu, char *extra)
5135 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5136 struct iw_point *pdata = &wrqu->data;
5137 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5140 DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
5141 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
5142 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
5144 sprintf( extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo) );
5145 wrqu->data.length = strlen( extra );
5151 static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
5152 struct iw_request_info *info,
5153 union iwreq_data *wrqu, char *extra)
5157 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5158 struct iw_point *pdata = &wrqu->data;
5159 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5162 DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
5163 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
5164 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
5166 sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
5167 pwdinfo->p2p_peer_interface_addr[ 0 ], pwdinfo->p2p_peer_interface_addr[ 1 ], pwdinfo->p2p_peer_interface_addr[ 2 ],
5168 pwdinfo->p2p_peer_interface_addr[ 3 ], pwdinfo->p2p_peer_interface_addr[ 4 ], pwdinfo->p2p_peer_interface_addr[ 5 ]);
5169 wrqu->data.length = strlen( extra );
5174 static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
5175 struct iw_request_info *info,
5176 union iwreq_data *wrqu, char *extra)
5181 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5182 struct iw_point *pdata = &wrqu->data;
5183 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5185 DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
5186 pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ],
5187 pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
5188 pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
5189 sprintf( extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
5190 pwdinfo->rx_prov_disc_info.peerDevAddr[ 0 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 1 ],
5191 pwdinfo->rx_prov_disc_info.peerDevAddr[ 2 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 3 ],
5192 pwdinfo->rx_prov_disc_info.peerDevAddr[ 4 ], pwdinfo->rx_prov_disc_info.peerDevAddr[ 5 ]);
5193 wrqu->data.length = strlen( extra );
5198 static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
5199 struct iw_request_info *info,
5200 union iwreq_data *wrqu, char *extra)
5205 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5206 struct iw_point *pdata = &wrqu->data;
5207 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5209 DBG_871X( "[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
5210 pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ],
5211 pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
5212 pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
5213 sprintf( extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
5214 pwdinfo->p2p_peer_device_addr[ 0 ], pwdinfo->p2p_peer_device_addr[ 1 ],
5215 pwdinfo->p2p_peer_device_addr[ 2 ], pwdinfo->p2p_peer_device_addr[ 3 ],
5216 pwdinfo->p2p_peer_device_addr[ 4 ], pwdinfo->p2p_peer_device_addr[ 5 ]);
5217 wrqu->data.length = strlen( extra );
5222 static int rtw_p2p_get_groupid(struct net_device *dev,
5223 struct iw_request_info *info,
5224 union iwreq_data *wrqu, char *extra)
5229 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5230 struct iw_point *pdata = &wrqu->data;
5231 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5233 sprintf( extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
5234 pwdinfo->groupid_info.go_device_addr[ 0 ], pwdinfo->groupid_info.go_device_addr[ 1 ],
5235 pwdinfo->groupid_info.go_device_addr[ 2 ], pwdinfo->groupid_info.go_device_addr[ 3 ],
5236 pwdinfo->groupid_info.go_device_addr[ 4 ], pwdinfo->groupid_info.go_device_addr[ 5 ],
5237 pwdinfo->groupid_info.ssid);
5238 wrqu->data.length = strlen( extra );
5243 static int rtw_p2p_get_op_ch(struct net_device *dev,
5244 struct iw_request_info *info,
5245 union iwreq_data *wrqu, char *extra)
5250 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5251 struct iw_point *pdata = &wrqu->data;
5252 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5255 DBG_871X( "[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
5257 sprintf( extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel );
5258 wrqu->data.length = strlen( extra );
5263 static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
5264 struct iw_request_info *info,
5265 union iwreq_data *wrqu, char *extra, char *subcmd)
5269 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5270 u8 peerMAC[ETH_ALEN] = { 0x00 };
5271 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5273 _list * plist,*phead;
5274 _queue *queue = &(pmlmepriv->scanned_queue);
5275 struct wlan_network *pnetwork = NULL;
5277 u16 attr_content = 0;
5278 uint attr_contentlen = 0;
5279 u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5281 // Commented by Albert 20110727
5282 // The input data is the MAC address which the application wants to know its WPS config method.
5283 // After knowing its WPS config method, the application can decide the config method for provisioning discovery.
5284 // Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05
5286 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5288 macstr2num(peerMAC, subcmd);
5290 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5292 phead = get_list_head(queue);
5293 plist = get_next(phead);
5297 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5299 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5300 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5305 // The mac address is matched.
5307 if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5309 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
5310 if (attr_contentlen)
5312 attr_content = be16_to_cpu(attr_content);
5313 sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
5321 plist = get_next(plist);
5325 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5329 sprintf(attr_content_str, "\n\nM=0000");
5332 wrqu->data.length = strlen(attr_content_str);
5333 _rtw_memcpy(extra, attr_content_str, wrqu->data.length);
5340 static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
5341 struct iw_request_info *info,
5342 union iwreq_data *wrqu, char *extra)
5346 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5347 struct iw_point *pdata = &wrqu->data;
5348 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5350 DBG_871X( "[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
5352 sprintf( extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport );
5353 DBG_871X( "[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
5355 wrqu->data.length = strlen( extra );
5360 static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
5361 struct iw_request_info *info,
5362 union iwreq_data *wrqu, char *extra)
5366 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5367 struct iw_point *pdata = &wrqu->data;
5368 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5370 sprintf( extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc );
5371 DBG_871X( "[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc );
5373 wrqu->data.length = strlen( extra );
5374 pwdinfo->wfd_info->wfd_pc = _FALSE; // Reset the WFD preferred connection to P2P
5379 static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
5380 struct iw_request_info *info,
5381 union iwreq_data *wrqu, char *extra)
5385 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5386 struct iw_point *pdata = &wrqu->data;
5387 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5389 sprintf( extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail );
5390 DBG_871X( "[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail );
5392 wrqu->data.length = strlen( extra );
5393 pwdinfo->wfd_info->peer_session_avail = _TRUE; // Reset the WFD session available
5397 #endif /* CONFIG_WFD */
5399 static int rtw_p2p_get_go_device_address(struct net_device *dev,
5400 struct iw_request_info *info,
5401 union iwreq_data *wrqu, char *extra, char *subcmd)
5405 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5406 u8 peerMAC[ETH_ALEN] = { 0x00 };
5407 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5409 _list *plist, *phead;
5410 _queue *queue = &(pmlmepriv->scanned_queue);
5411 struct wlan_network *pnetwork = NULL;
5414 uint p2pielen = 0, attr_contentlen = 0;
5415 u8 attr_content[100] = { 0x00 };
5416 u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5418 // Commented by Albert 20121209
5419 // The input data is the GO's interface address which the application wants to know its device address.
5420 // Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05
5422 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5424 macstr2num(peerMAC, subcmd);
5426 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5428 phead = get_list_head(queue);
5429 plist = get_next(phead);
5433 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5435 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5436 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5438 // Commented by Albert 2011/05/18
5439 // Match the device address located in the P2P IE
5440 // This is for the case that the P2P device address is not the same as the P2P interface address.
5442 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5446 // The P2P Device ID attribute is included in the Beacon frame.
5447 // The P2P Device Info attribute is included in the probe response frame.
5449 _rtw_memset(attr_content, 0x00, 100);
5450 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen))
5452 // Handle the P2P Device ID attribute of Beacon first
5456 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen))
5458 // Handle the P2P Device Info attribute of probe response
5463 //Get the next P2P IE
5464 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5469 plist = get_next(plist);
5473 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5477 sprintf(go_devadd_str, "\n\ndev_add=NULL");
5480 sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
5481 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
5484 wrqu->data.length = strlen(go_devadd_str);
5485 _rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
5491 static int rtw_p2p_get_device_type(struct net_device *dev,
5492 struct iw_request_info *info,
5493 union iwreq_data *wrqu, char *extra, char *subcmd)
5497 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5498 u8 peerMAC[ETH_ALEN] = { 0x00 };
5499 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5501 _list *plist, *phead;
5502 _queue *queue = &(pmlmepriv->scanned_queue);
5503 struct wlan_network *pnetwork = NULL;
5505 u8 dev_type[8] = { 0x00 };
5506 uint dev_type_len = 0;
5507 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
5509 // Commented by Albert 20121209
5510 // The input data is the MAC address which the application wants to know its device type.
5511 // Such user interface could know the device type.
5512 // Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05
5514 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5516 macstr2num(peerMAC, subcmd);
5518 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5520 phead = get_list_head(queue);
5521 plist = get_next(phead);
5525 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5527 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5528 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5533 // The mac address is matched.
5535 if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5537 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
5542 _rtw_memcpy(&type, dev_type, 2);
5543 type = be16_to_cpu(type);
5544 sprintf(dev_type_str, "\n\nN=%.2d", type);
5551 plist = get_next(plist);
5555 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5559 sprintf(dev_type_str, "\n\nN=00");
5562 wrqu->data.length = strlen(dev_type_str);
5563 _rtw_memcpy(extra, dev_type_str, wrqu->data.length);
5569 static int rtw_p2p_get_device_name(struct net_device *dev,
5570 struct iw_request_info *info,
5571 union iwreq_data *wrqu, char *extra, char *subcmd)
5575 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5576 u8 peerMAC[ETH_ALEN] = { 0x00 };
5577 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5579 _list *plist, *phead;
5580 _queue *queue = &(pmlmepriv->scanned_queue);
5581 struct wlan_network *pnetwork = NULL;
5583 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
5585 u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5587 // Commented by Albert 20121225
5588 // The input data is the MAC address which the application wants to know its device name.
5589 // Such user interface could show peer device's device name instead of ssid.
5590 // Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05
5592 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5594 macstr2num(peerMAC, subcmd);
5596 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5598 phead = get_list_head(queue);
5599 plist = get_next(phead);
5603 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5605 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5606 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5611 // The mac address is matched.
5613 if ( (wpsie=rtw_get_wps_ie_from_scan_queue( &pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0])) )
5615 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
5618 sprintf(dev_name_str, "\n\nN=%s", dev_name);
5625 plist = get_next(plist);
5629 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5633 sprintf(dev_name_str, "\n\nN=0000");
5636 wrqu->data.length = strlen(dev_name_str);
5637 _rtw_memcpy(extra, dev_name_str, wrqu->data.length);
5643 static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
5644 struct iw_request_info *info,
5645 union iwreq_data *wrqu, char *extra, char *subcmd)
5649 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5650 u8 peerMAC[ETH_ALEN] = { 0x00 };
5651 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5653 _list *plist, *phead;
5654 _queue *queue = &(pmlmepriv->scanned_queue);
5655 struct wlan_network *pnetwork = NULL;
5658 uint p2pielen = 0, attr_contentlen = 0;
5659 u8 attr_content[2] = { 0x00 };
5660 u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
5662 // Commented by Ouden 20121226
5663 // The application wants to know P2P initation procedure is support or not.
5664 // Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05
5666 DBG_871X("[%s] data = %s\n", __FUNCTION__, subcmd);
5668 macstr2num(peerMAC, subcmd);
5670 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5672 phead = get_list_head(queue);
5673 plist = get_next(phead);
5677 if (rtw_end_of_queue_search(phead, plist) == _TRUE) break;
5679 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5680 if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN))
5682 // Commented by Albert 20121226
5683 // Match the device address located in the P2P IE
5684 // This is for the case that the P2P device address is not the same as the P2P interface address.
5686 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5690 //_rtw_memset( attr_content, 0x00, 2);
5691 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen))
5693 // Handle the P2P capability attribute
5699 //Get the next P2P IE
5700 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5705 plist = get_next(plist);
5709 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5713 sprintf(inv_proc_str, "\nIP=-1");
5716 if ((attr_content[0] & 0x20) == 0x20)
5717 sprintf(inv_proc_str, "\nIP=1");
5719 sprintf(inv_proc_str, "\nIP=0");
5722 wrqu->data.length = strlen(inv_proc_str);
5723 _rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
5729 static int rtw_p2p_connect(struct net_device *dev,
5730 struct iw_request_info *info,
5731 union iwreq_data *wrqu, char *extra)
5735 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5736 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5737 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
5739 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5740 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5742 _list *plist, *phead;
5743 _queue *queue = &(pmlmepriv->scanned_queue);
5744 struct wlan_network *pnetwork = NULL;
5745 uint uintPeerChannel = 0;
5746 #ifdef CONFIG_CONCURRENT_MODE
5747 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5748 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5749 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5750 #endif // CONFIG_CONCURRENT_MODE
5752 // Commented by Albert 20110304
5753 // The input data contains two informations.
5754 // 1. First information is the MAC address which wants to formate with
5755 // 2. Second information is the WPS PINCode or "pbc" string for push button method
5756 // Format: 00:E0:4C:00:00:05
5757 // Format: 00:E0:4C:00:00:05
5759 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5761 if ( pwdinfo->p2p_state == P2P_STATE_NONE )
5763 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5767 #ifdef CONFIG_INTEL_WIDI
5768 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
5769 DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ );
5772 #endif //CONFIG_INTEL_WIDI
5774 if ( pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO )
5779 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5781 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);
5791 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5794 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5795 if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
5797 if (pnetwork->network.Configuration.DSConfig != 0)
5798 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5799 else if (pwdinfo->nego_req_info.peer_ch != 0)
5800 uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch;
5802 /* Unexpected case */
5803 uintPeerChannel = 0;
5804 DBG_871X("%s uintPeerChannel = 0\n", __func__);
5809 plist = get_next(plist);
5813 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5815 if ( uintPeerChannel )
5817 #ifdef CONFIG_CONCURRENT_MODE
5818 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5820 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5822 #endif // CONFIG_CONCURRENT_MODE
5824 _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
5825 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5827 pwdinfo->nego_req_info.peer_channel_num[ 0 ] = uintPeerChannel;
5828 _rtw_memcpy( pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN );
5829 pwdinfo->nego_req_info.benable = _TRUE;
5831 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5832 if ( rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK )
5834 // Restore to the listen state if the current p2p state is not nego OK
5835 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN );
5838 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5839 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
5841 #ifdef CONFIG_CONCURRENT_MODE
5842 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5844 // Have to enter the power saving with the AP
5845 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
5847 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
5849 #endif // CONFIG_CONCURRENT_MODE
5851 DBG_871X( "[%s] Start PreTx Procedure!\n", __FUNCTION__ );
5852 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
5853 #ifdef CONFIG_CONCURRENT_MODE
5854 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
5856 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT );
5860 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5863 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT );
5864 #endif // CONFIG_CONCURRENT_MODE
5869 DBG_871X( "[%s] Not Found in Scanning Queue~\n", __FUNCTION__ );
5870 #ifdef CONFIG_INTEL_WIDI
5871 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5872 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
5873 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
5874 rtw_free_network_queue(padapter, _TRUE);
5876 * For WiDi, if we can't find candidate device in scanning queue,
5877 * driver will do scanning itself
5879 _enter_critical_bh(&pmlmepriv->lock, &irqL);
5880 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
5881 _exit_critical_bh(&pmlmepriv->lock, &irqL);
5882 #endif //CONFIG_INTEL_WIDI
5889 static int rtw_p2p_invite_req(struct net_device *dev,
5890 struct iw_request_info *info,
5891 union iwreq_data *wrqu, char *extra)
5895 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5896 struct iw_point *pdata = &wrqu->data;
5897 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5899 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
5900 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5901 _list *plist, *phead;
5902 _queue *queue = &(pmlmepriv->scanned_queue);
5903 struct wlan_network *pnetwork = NULL;
5904 uint uintPeerChannel = 0;
5905 u8 attr_content[50] = { 0x00 }, _status = 0;
5907 uint p2pielen = 0, attr_contentlen = 0;
5909 struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info;
5910 #ifdef CONFIG_CONCURRENT_MODE
5911 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5912 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5913 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5914 #endif // CONFIG_CONCURRENT_MODE
5916 // Commented by Albert 20120321
5917 // The input data contains two informations.
5918 // 1. First information is the P2P device address which you want to send to.
5919 // 2. Second information is the group id which combines with GO's mac address, space and GO's ssid.
5920 // Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy"
5921 // Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy
5923 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
5925 if ( wrqu->data.length <= 37 )
5927 DBG_871X( "[%s] Wrong format!\n", __FUNCTION__ );
5931 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5933 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
5938 // Reset the content of struct tx_invite_req_info
5939 pinvite_req_info->benable = _FALSE;
5940 _rtw_memset( pinvite_req_info->go_bssid, 0x00, ETH_ALEN );
5941 _rtw_memset( pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN );
5942 pinvite_req_info->ssidlen = 0x00;
5943 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
5944 _rtw_memset( pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN );
5945 pinvite_req_info->token = 3;
5948 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
5950 pinvite_req_info->peer_macaddr[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
5953 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5955 phead = get_list_head(queue);
5956 plist = get_next(phead);
5960 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
5963 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5965 // Commented by Albert 2011/05/18
5966 // Match the device address located in the P2P IE
5967 // This is for the case that the P2P device address is not the same as the P2P interface address.
5969 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5971 // The P2P Device ID attribute is included in the Beacon frame.
5972 // The P2P Device Info attribute is included in the probe response frame.
5974 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
5976 // Handle the P2P Device ID attribute of Beacon first
5977 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5979 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5983 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
5985 // Handle the P2P Device Info attribute of probe response
5986 if ( _rtw_memcmp( attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN ) )
5988 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5995 plist = get_next(plist);
5999 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6002 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) {
6003 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
6007 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
6012 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
6013 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
6015 u16 wfd_devinfo_field = 0;
6017 // Commented by Albert 20120319
6018 // The first two bytes are the WFD device information field of WFD device information subelement.
6019 // In big endian format.
6020 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6021 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
6023 pwfd_info->peer_session_avail = _TRUE;
6027 pwfd_info->peer_session_avail = _FALSE;
6032 if ( _FALSE == pwfd_info->peer_session_avail )
6034 DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
6038 #endif /* CONFIG_WFD */
6040 if ( uintPeerChannel )
6042 #ifdef CONFIG_CONCURRENT_MODE
6043 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6045 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6047 #endif // CONFIG_CONCURRENT_MODE
6049 // Store the GO's bssid
6050 for( jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3 )
6052 pinvite_req_info->go_bssid[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
6055 // Store the GO's ssid
6056 pinvite_req_info->ssidlen = wrqu->data.length - 36;
6057 _rtw_memcpy( pinvite_req_info->go_ssid, &extra[ 36 ], (u32) pinvite_req_info->ssidlen );
6058 pinvite_req_info->benable = _TRUE;
6059 pinvite_req_info->peer_ch = uintPeerChannel;
6061 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6062 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
6064 #ifdef CONFIG_CONCURRENT_MODE
6065 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6067 // Have to enter the power saving with the AP
6068 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
6070 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
6074 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6077 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6080 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
6082 #ifdef CONFIG_CONCURRENT_MODE
6083 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6085 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT );
6089 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
6092 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT );
6093 #endif // CONFIG_CONCURRENT_MODE
6099 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
6107 static int rtw_p2p_set_persistent(struct net_device *dev,
6108 struct iw_request_info *info,
6109 union iwreq_data *wrqu, char *extra)
6113 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6114 struct iw_point *pdata = &wrqu->data;
6115 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6117 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
6118 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6119 _list *plist, *phead;
6120 _queue *queue = &(pmlmepriv->scanned_queue);
6121 struct wlan_network *pnetwork = NULL;
6122 uint uintPeerChannel = 0;
6123 u8 attr_content[50] = { 0x00 }, _status = 0;
6125 uint p2pielen = 0, attr_contentlen = 0;
6127 struct tx_invite_req_info* pinvite_req_info = &pwdinfo->invitereq_info;
6128 #ifdef CONFIG_CONCURRENT_MODE
6129 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
6130 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
6131 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
6132 #endif // CONFIG_CONCURRENT_MODE
6134 // Commented by Albert 20120328
6135 // The input data is 0 or 1
6136 // 0: disable persistent group functionality
6137 // 1: enable persistent group founctionality
6139 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6141 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
6143 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6148 if ( extra[ 0 ] == '0' ) // Disable the persistent group function.
6150 pwdinfo->persistent_supported = _FALSE;
6152 else if ( extra[ 0 ] == '1' ) // Enable the persistent group function.
6154 pwdinfo->persistent_supported = _TRUE;
6158 pwdinfo->persistent_supported = _FALSE;
6161 printk( "[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported );
6169 static int hexstr2bin(const char *hex, u8 *buf, size_t len)
6173 const char *ipos = hex;
6176 for (i = 0; i < len; i++) {
6177 a = hex2byte_i(ipos);
6186 static int uuid_str2bin(const char *str, u8 *bin)
6194 if (hexstr2bin(pos, opos, 4))
6199 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
6204 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
6209 if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
6214 if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
6220 static int rtw_p2p_set_wps_uuid(struct net_device *dev,
6221 struct iw_request_info *info,
6222 union iwreq_data *wrqu, char *extra)
6226 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6227 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6229 DBG_871X("[%s] data = %s\n", __FUNCTION__, extra);
6231 if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))
6233 pwdinfo->external_uuid = 1;
6235 pwdinfo->external_uuid = 0;
6243 static int rtw_p2p_set_pc(struct net_device *dev,
6244 struct iw_request_info *info,
6245 union iwreq_data *wrqu, char *extra)
6249 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6250 struct iw_point *pdata = &wrqu->data;
6251 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6252 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
6254 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
6255 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6256 _list *plist, *phead;
6257 _queue *queue = &(pmlmepriv->scanned_queue);
6258 struct wlan_network *pnetwork = NULL;
6259 u8 attr_content[50] = { 0x00 }, _status = 0;
6261 uint p2pielen = 0, attr_contentlen = 0;
6263 uint uintPeerChannel = 0;
6264 #ifdef CONFIG_CONCURRENT_MODE
6265 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
6266 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
6267 #endif // CONFIG_CONCURRENT_MODE
6269 struct wifi_display_info* pwfd_info = pwdinfo->wfd_info;
6271 // Commented by Albert 20120512
6272 // 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit)
6273 // Format: 00:E0:4C:00:00:05
6275 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6277 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
6279 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6283 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
6285 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
6288 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6290 phead = get_list_head(queue);
6291 plist = get_next(phead);
6295 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
6298 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
6300 // Commented by Albert 2011/05/18
6301 // Match the device address located in the P2P IE
6302 // This is for the case that the P2P device address is not the same as the P2P interface address.
6304 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
6306 // The P2P Device ID attribute is included in the Beacon frame.
6307 // The P2P Device Info attribute is included in the probe response frame.
6308 printk( "[%s] Got P2P IE\n", __FUNCTION__ );
6309 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
6311 // Handle the P2P Device ID attribute of Beacon first
6312 printk( "[%s] P2P_ATTR_DEVICE_ID \n", __FUNCTION__ );
6313 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6315 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6319 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
6321 // Handle the P2P Device Info attribute of probe response
6322 printk( "[%s] P2P_ATTR_DEVICE_INFO \n", __FUNCTION__ );
6323 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6325 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6332 plist = get_next(plist);
6336 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6337 printk( "[%s] channel = %d\n", __FUNCTION__, uintPeerChannel );
6339 if ( uintPeerChannel )
6344 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
6349 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
6350 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
6352 u16 wfd_devinfo_field = 0;
6354 // Commented by Albert 20120319
6355 // The first two bytes are the WFD device information field of WFD device information subelement.
6356 // In big endian format.
6357 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6358 if ( wfd_devinfo_field & WFD_DEVINFO_PC_TDLS )
6360 pwfd_info->wfd_pc = _TRUE;
6364 pwfd_info->wfd_pc = _FALSE;
6371 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
6380 static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
6381 struct iw_request_info *info,
6382 union iwreq_data *wrqu, char *extra)
6386 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6387 struct iw_point *pdata = &wrqu->data;
6388 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6389 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
6391 // Commented by Albert 20120328
6392 // The input data is 0 or 1
6393 // 0: specify to Miracast source device
6394 // 1 or others: specify to Miracast sink device (display device)
6396 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6398 if ( extra[ 0 ] == '0' ) // Set to Miracast source device.
6400 pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
6402 else // Set to Miracast sink device.
6404 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
6413 static int rtw_p2p_set_wfd_enable(struct net_device *dev,
6414 struct iw_request_info *info,
6415 union iwreq_data *wrqu, char *extra)
6417 // Commented by Kurt 20121206
6418 // This function is used to set wfd enabled
6421 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6422 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6425 rtw_wfd_enable(padapter, 0);
6426 else if (*extra == '1')
6427 rtw_wfd_enable(padapter, 1);
6429 DBG_871X( "[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable );
6435 static int rtw_p2p_set_driver_iface(struct net_device *dev,
6436 struct iw_request_info *info,
6437 union iwreq_data *wrqu, char *extra)
6439 // Commented by Kurt 20121206
6440 // This function is used to set driver iface is WEXT or CFG80211
6442 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6443 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6447 pwdinfo->driver_interface = DRIVER_WEXT;
6448 DBG_871X( "[%s] driver_interface = WEXT\n", __FUNCTION__);
6450 else if(*extra == '2')
6452 pwdinfo->driver_interface = DRIVER_CFG80211;
6453 DBG_871X( "[%s] driver_interface = CFG80211\n", __FUNCTION__);
6460 // To set the WFD session available to enable or disable
6461 static int rtw_p2p_set_sa(struct net_device *dev,
6462 struct iw_request_info *info,
6463 union iwreq_data *wrqu, char *extra)
6467 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6468 struct iw_point *pdata = &wrqu->data;
6469 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6470 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
6472 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6476 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6481 if ( extra[ 0 ] == '0' ) // Disable the session available.
6483 pwdinfo->session_available = _FALSE;
6485 else if ( extra[ 0 ] == '1' ) // Enable the session available.
6487 pwdinfo->session_available = _TRUE;
6491 pwdinfo->session_available = _FALSE;
6494 printk( "[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available );
6501 #endif /* CONFIG_WFD */
6503 static int rtw_p2p_prov_disc(struct net_device *dev,
6504 struct iw_request_info *info,
6505 union iwreq_data *wrqu, char *extra)
6508 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6509 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6510 u8 peerMAC[ ETH_ALEN ] = { 0x00 };
6512 u8 peerMACStr[ ETH_ALEN * 2 ] = { 0x00 };
6513 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6514 _list *plist, *phead;
6515 _queue *queue = &(pmlmepriv->scanned_queue);
6516 struct wlan_network *pnetwork = NULL;
6517 uint uintPeerChannel = 0;
6518 u8 attr_content[100] = { 0x00 }, _status = 0;
6520 uint p2pielen = 0, attr_contentlen = 0;
6522 #ifdef CONFIG_CONCURRENT_MODE
6523 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
6524 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
6525 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
6526 #endif // CONFIG_CONCURRENT_MODE
6528 // Commented by Albert 20110301
6529 // The input data contains two informations.
6530 // 1. First information is the MAC address which wants to issue the provisioning discovery request frame.
6531 // 2. Second information is the WPS configuration method which wants to discovery
6532 // Format: 00:E0:4C:00:00:05_display
6533 // Format: 00:E0:4C:00:00:05_keypad
6534 // Format: 00:E0:4C:00:00:05_pbc
6535 // Format: 00:E0:4C:00:00:05_label
6537 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6539 if ( pwdinfo->p2p_state == P2P_STATE_NONE )
6541 DBG_871X( "[%s] WiFi Direct is disable!\n", __FUNCTION__ );
6546 #ifdef CONFIG_INTEL_WIDI
6547 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
6548 DBG_871X( "[%s] WiFi is under survey!\n", __FUNCTION__ );
6551 #endif //CONFIG_INTEL_WIDI
6553 // Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request.
6554 _rtw_memset( pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN );
6555 _rtw_memset( pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN );
6556 _rtw_memset( &pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof( NDIS_802_11_SSID ) );
6557 pwdinfo->tx_prov_disc_info.peer_channel_num[ 0 ] = 0;
6558 pwdinfo->tx_prov_disc_info.peer_channel_num[ 1 ] = 0;
6559 pwdinfo->tx_prov_disc_info.benable = _FALSE;
6562 for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
6564 peerMAC[ jj ] = key_2char2num( extra[kk], extra[kk+ 1] );
6567 if ( _rtw_memcmp( &extra[ 18 ], "display", 7 ) )
6569 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
6571 else if ( _rtw_memcmp( &extra[ 18 ], "keypad", 7 ) )
6573 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
6575 else if ( _rtw_memcmp( &extra[ 18 ], "pbc", 3 ) )
6577 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6579 else if ( _rtw_memcmp( &extra[ 18 ], "label", 5 ) )
6581 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
6585 DBG_871X( "[%s] Unknown WPS config methodn", __FUNCTION__ );
6589 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6591 phead = get_list_head(queue);
6592 plist = get_next(phead);
6596 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
6599 if( uintPeerChannel != 0 )
6602 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
6604 // Commented by Albert 2011/05/18
6605 // Match the device address located in the P2P IE
6606 // This is for the case that the P2P device address is not the same as the P2P interface address.
6608 p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
6612 // The P2P Device ID attribute is included in the Beacon frame.
6613 // The P2P Device Info attribute is included in the probe response frame.
6615 if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen) )
6617 // Handle the P2P Device ID attribute of Beacon first
6618 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6620 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6624 else if ( rtw_get_p2p_attr_content( p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen) )
6626 // Handle the P2P Device Info attribute of probe response
6627 if ( _rtw_memcmp( attr_content, peerMAC, ETH_ALEN ) )
6629 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6634 //Get the next P2P IE
6635 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
6640 #ifdef CONFIG_INTEL_WIDI
6641 // Some Intel WiDi source may not provide P2P IE,
6642 // so we could only compare mac addr by 802.11 Source Address
6643 if( pmlmepriv->widi_state == INTEL_WIDI_STATE_WFD_CONNECTION
6644 && uintPeerChannel == 0 )
6646 if ( _rtw_memcmp( pnetwork->network.MacAddress, peerMAC, ETH_ALEN ) )
6648 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
6652 #endif //CONFIG_INTEL_WIDI
6654 plist = get_next(plist);
6658 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
6660 if ( uintPeerChannel )
6663 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
6664 struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
6668 wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
6673 DBG_871X( "[%s] Found WFD IE!\n", __FUNCTION__ );
6674 wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
6676 u16 wfd_devinfo_field = 0;
6678 // Commented by Albert 20120319
6679 // The first two bytes are the WFD device information field of WFD device information subelement.
6680 // In big endian format.
6681 wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
6682 if ( wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL )
6684 pwfd_info->peer_session_avail = _TRUE;
6688 pwfd_info->peer_session_avail = _FALSE;
6693 if ( _FALSE == pwfd_info->peer_session_avail )
6695 DBG_871X( "[%s] WFD Session not avaiable!\n", __FUNCTION__ );
6699 #endif /* CONFIG_WFD */
6701 DBG_871X( "[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel );
6702 #ifdef CONFIG_CONCURRENT_MODE
6703 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6705 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
6707 #endif // CONFIG_CONCURRENT_MODE
6708 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN );
6709 _rtw_memcpy( pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN );
6710 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = ( u16 ) uintPeerChannel;
6711 pwdinfo->tx_prov_disc_info.benable = _TRUE;
6712 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6713 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
6715 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
6717 _rtw_memcpy( &pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof( NDIS_802_11_SSID ) );
6719 else if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
6721 _rtw_memcpy( pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
6722 pwdinfo->tx_prov_disc_info.ssid.SsidLength= P2P_WILDCARD_SSID_LEN;
6725 #ifdef CONFIG_CONCURRENT_MODE
6726 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6728 // Have to enter the power saving with the AP
6729 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
6731 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
6735 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6738 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
6741 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
6743 #ifdef CONFIG_CONCURRENT_MODE
6744 if ( check_fwstate( pbuddy_mlmepriv, _FW_LINKED ) )
6746 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT );
6750 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6753 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
6754 #endif // CONFIG_CONCURRENT_MODE
6759 DBG_871X( "[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__ );
6760 #ifdef CONFIG_INTEL_WIDI
6761 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
6762 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
6763 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
6764 rtw_free_network_queue(padapter, _TRUE);
6765 _enter_critical_bh(&pmlmepriv->lock, &irqL);
6766 rtw_sitesurvey_cmd(padapter, NULL, 0, NULL, 0);
6767 _exit_critical_bh(&pmlmepriv->lock, &irqL);
6768 #endif //CONFIG_INTEL_WIDI
6776 // Added by Albert 20110328
6777 // This function is used to inform the driver the user had specified the pin code value or pbc
6780 static int rtw_p2p_got_wpsinfo(struct net_device *dev,
6781 struct iw_request_info *info,
6782 union iwreq_data *wrqu, char *extra)
6786 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6787 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
6790 DBG_871X( "[%s] data = %s\n", __FUNCTION__, extra );
6791 // Added by Albert 20110328
6792 // if the input data is P2P_NO_WPSINFO -> reset the wpsinfo
6793 // if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device.
6794 // if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself.
6795 // if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC
6797 if ( *extra == '0' )
6799 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6801 else if ( *extra == '1' )
6803 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
6805 else if ( *extra == '2' )
6807 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
6809 else if ( *extra == '3' )
6811 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
6815 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
6824 static int rtw_p2p_set(struct net_device *dev,
6825 struct iw_request_info *info,
6826 union iwreq_data *wrqu, char *extra)
6832 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6833 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6834 struct iw_point *pdata = &wrqu->data;
6835 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6836 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6838 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
6840 if ( _rtw_memcmp( extra, "enable=", 7 ) )
6842 rtw_wext_p2p_enable( dev, info, wrqu, &extra[7] );
6844 else if ( _rtw_memcmp( extra, "setDN=", 6 ) )
6846 wrqu->data.length -= 6;
6847 rtw_p2p_setDN( dev, info, wrqu, &extra[6] );
6849 else if ( _rtw_memcmp( extra, "profilefound=", 13 ) )
6851 wrqu->data.length -= 13;
6852 rtw_p2p_profilefound( dev, info, wrqu, &extra[13] );
6854 else if ( _rtw_memcmp( extra, "prov_disc=", 10 ) )
6856 wrqu->data.length -= 10;
6857 rtw_p2p_prov_disc( dev, info, wrqu, &extra[10] );
6859 else if ( _rtw_memcmp( extra, "nego=", 5 ) )
6861 wrqu->data.length -= 5;
6862 rtw_p2p_connect( dev, info, wrqu, &extra[5] );
6864 else if ( _rtw_memcmp( extra, "intent=", 7 ) )
6866 // Commented by Albert 2011/03/23
6867 // The wrqu->data.length will include the null character
6868 // So, we will decrease 7 + 1
6869 wrqu->data.length -= 8;
6870 rtw_p2p_set_intent( dev, info, wrqu, &extra[7] );
6872 else if ( _rtw_memcmp( extra, "ssid=", 5 ) )
6874 wrqu->data.length -= 5;
6875 rtw_p2p_set_go_nego_ssid( dev, info, wrqu, &extra[5] );
6877 else if ( _rtw_memcmp( extra, "got_wpsinfo=", 12 ) )
6879 wrqu->data.length -= 12;
6880 rtw_p2p_got_wpsinfo( dev, info, wrqu, &extra[12] );
6882 else if ( _rtw_memcmp( extra, "listen_ch=", 10 ) )
6884 // Commented by Albert 2011/05/24
6885 // The wrqu->data.length will include the null character
6886 // So, we will decrease (10 + 1)
6887 wrqu->data.length -= 11;
6888 rtw_p2p_set_listen_ch( dev, info, wrqu, &extra[10] );
6890 else if ( _rtw_memcmp( extra, "op_ch=", 6 ) )
6892 // Commented by Albert 2011/05/24
6893 // The wrqu->data.length will include the null character
6894 // So, we will decrease (6 + 1)
6895 wrqu->data.length -= 7;
6896 rtw_p2p_set_op_ch( dev, info, wrqu, &extra[6] );
6898 else if ( _rtw_memcmp( extra, "invite=", 7 ) )
6900 wrqu->data.length -= 8;
6901 rtw_p2p_invite_req( dev, info, wrqu, &extra[7] );
6903 else if ( _rtw_memcmp( extra, "persistent=", 11 ) )
6905 wrqu->data.length -= 11;
6906 rtw_p2p_set_persistent( dev, info, wrqu, &extra[11] );
6908 else if ( _rtw_memcmp ( extra, "uuid=", 5) )
6910 wrqu->data.length -= 5;
6911 ret = rtw_p2p_set_wps_uuid( dev, info, wrqu, &extra[5] );
6915 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
6916 if (_rtw_memcmp(extra, "sa=", 3)) {
6917 /* sa: WFD Session Available information */
6918 wrqu->data.length -= 3;
6919 rtw_p2p_set_sa(dev, info, wrqu, &extra[3]);
6920 } else if (_rtw_memcmp(extra, "pc=", 3)) {
6921 /* pc: WFD Preferred Connection */
6922 wrqu->data.length -= 3;
6923 rtw_p2p_set_pc(dev, info, wrqu, &extra[3]);
6924 } else if (_rtw_memcmp(extra, "wfd_type=", 9)) {
6925 wrqu->data.length -= 9;
6926 rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]);
6927 } else if (_rtw_memcmp(extra, "wfd_enable=", 11)) {
6928 wrqu->data.length -= 11;
6929 rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]);
6930 } else if (_rtw_memcmp(extra, "driver_iface=", 13)) {
6931 wrqu->data.length -= 13;
6932 rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]);
6935 #endif /* CONFIG_WFD */
6943 static int rtw_p2p_get(struct net_device *dev,
6944 struct iw_request_info *info,
6945 union iwreq_data *wrqu, char *extra)
6952 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6953 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6954 struct iw_point *pdata = &wrqu->data;
6955 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
6956 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6958 if ( padapter->bShowGetP2PState )
6960 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
6963 if ( _rtw_memcmp( wrqu->data.pointer, "status", 6 ) )
6965 rtw_p2p_get_status( dev, info, wrqu, extra );
6967 else if ( _rtw_memcmp( wrqu->data.pointer, "role", 4 ) )
6969 rtw_p2p_get_role( dev, info, wrqu, extra);
6971 else if ( _rtw_memcmp( wrqu->data.pointer, "peer_ifa", 8 ) )
6973 rtw_p2p_get_peer_ifaddr( dev, info, wrqu, extra);
6975 else if ( _rtw_memcmp( wrqu->data.pointer, "req_cm", 6 ) )
6977 rtw_p2p_get_req_cm( dev, info, wrqu, extra);
6979 else if ( _rtw_memcmp( wrqu->data.pointer, "peer_deva", 9 ) )
6981 // Get the P2P device address when receiving the provision discovery request frame.
6982 rtw_p2p_get_peer_devaddr( dev, info, wrqu, extra);
6984 else if ( _rtw_memcmp( wrqu->data.pointer, "group_id", 8 ) )
6986 rtw_p2p_get_groupid( dev, info, wrqu, extra);
6988 else if ( _rtw_memcmp( wrqu->data.pointer, "inv_peer_deva", 13 ) )
6990 // Get the P2P device address when receiving the P2P Invitation request frame.
6991 rtw_p2p_get_peer_devaddr_by_invitation( dev, info, wrqu, extra);
6993 else if ( _rtw_memcmp( wrqu->data.pointer, "op_ch", 5 ) )
6995 rtw_p2p_get_op_ch( dev, info, wrqu, extra);
6999 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
7000 if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9))
7001 rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra);
7002 else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6))
7003 rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra);
7004 else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6))
7005 rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra);
7007 #endif /* CONFIG_WFD */
7015 static int rtw_p2p_get2(struct net_device *dev,
7016 struct iw_request_info *info,
7017 union iwreq_data *wrqu, char *extra)
7024 int length = wrqu->data.length;
7025 char *buffer = (u8 *)rtw_malloc(length);
7033 if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length))
7039 DBG_871X("[%s] buffer = %s\n", __FUNCTION__, buffer);
7041 if (_rtw_memcmp(buffer, "wpsCM=", 6))
7043 ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
7044 } else if (_rtw_memcmp(buffer, "devN=", 5))
7046 ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
7047 } else if (_rtw_memcmp(buffer, "dev_type=", 9))
7049 ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
7050 } else if (_rtw_memcmp(buffer, "go_devadd=", 10))
7052 ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
7053 } else if (_rtw_memcmp(buffer, "InvProc=", 8))
7055 ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
7058 snprintf(extra, sizeof("Command not found."), "Command not found.");
7059 wrqu->data.length = strlen(extra);
7065 rtw_mfree(buffer, length);
7074 static int rtw_cta_test_start(struct net_device *dev,
7075 struct iw_request_info *info,
7076 union iwreq_data *wrqu, char *extra)
7079 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7080 DBG_871X("%s %s\n", __func__, extra);
7081 if (!strcmp(extra, "1"))
7082 padapter->in_cta_test = 1;
7084 padapter->in_cta_test = 0;
7086 if(padapter->in_cta_test)
7088 u32 v = rtw_read32(padapter, REG_RCR);
7089 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN );//| RCR_ADF
7090 rtw_write32(padapter, REG_RCR, v);
7091 DBG_871X("enable RCR_ADF\n");
7095 u32 v = rtw_read32(padapter, REG_RCR);
7096 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN ;//| RCR_ADF
7097 rtw_write32(padapter, REG_RCR, v);
7098 DBG_871X("disable RCR_ADF\n");
7104 extern int rtw_change_ifname(_adapter *padapter, const char *ifname);
7105 static int rtw_rereg_nd_name(struct net_device *dev,
7106 struct iw_request_info *info,
7107 union iwreq_data *wrqu, char *extra)
7110 _adapter *padapter = rtw_netdev_priv(dev);
7111 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
7112 char new_ifname[IFNAMSIZ];
7114 if(rereg_priv->old_ifname[0] == 0) {
7116 #ifdef CONFIG_CONCURRENT_MODE
7117 if (padapter->isprimary)
7118 reg_ifname = padapter->registrypriv.ifname;
7121 reg_ifname = padapter->registrypriv.if2name;
7123 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
7124 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
7127 //DBG_871X("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length);
7128 if(wrqu->data.length > IFNAMSIZ)
7131 if ( copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ) ) {
7135 if( 0 == strcmp(rereg_priv->old_ifname, new_ifname) ) {
7139 DBG_871X("%s new_ifname:%s\n", __FUNCTION__, new_ifname);
7140 if( 0 != (ret = rtw_change_ifname(padapter, new_ifname)) ) {
7144 if(_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {
7145 padapter->ledpriv.bRegUseLed= rereg_priv->old_bRegUseLed;
7146 rtw_hal_sw_led_init(padapter);
7147 //rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
7150 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
7151 rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
7153 if(_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {
7155 DBG_871X("%s disable\n", __FUNCTION__);
7156 // free network queue for Android's timming issue
7157 rtw_free_network_queue(padapter, _TRUE);
7160 rtw_led_control(padapter, LED_CTL_POWER_OFF);
7161 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
7162 padapter->ledpriv.bRegUseLed= _FALSE;
7163 rtw_hal_sw_led_deinit(padapter);
7165 // the interface is being "disabled", we can do deeper IPS
7166 //rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
7167 //rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
7175 #include <rtw_iol.h>
7178 #ifdef DBG_CMD_QUEUE
7181 static int rtw_dbg_port(struct net_device *dev,
7182 struct iw_request_info *info,
7183 union iwreq_data *wrqu, char *extra)
7187 u8 major_cmd, minor_cmd;
7189 u32 extra_arg, *pdata, val32;
7190 struct sta_info *psta;
7191 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7192 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7193 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7194 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7195 struct security_priv *psecuritypriv = &padapter->securitypriv;
7196 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
7197 struct sta_priv *pstapriv = &padapter->stapriv;
7200 pdata = (u32*)&wrqu->data;
7203 arg = (u16)(val32&0x0000ffff);
7204 major_cmd = (u8)(val32>>24);
7205 minor_cmd = (u8)((val32>>16)&0x00ff);
7207 extra_arg = *(pdata+1);
7211 case 0x70://read_reg
7215 DBG_871X("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
7218 DBG_871X("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
7221 DBG_871X("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
7225 case 0x71://write_reg
7229 rtw_write8(padapter, arg, extra_arg);
7230 DBG_871X("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
7233 rtw_write16(padapter, arg, extra_arg);
7234 DBG_871X("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
7237 rtw_write32(padapter, arg, extra_arg);
7238 DBG_871X("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
7243 DBG_871X("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
7245 case 0x73://write_bb
7246 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
7247 DBG_871X("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
7250 DBG_871X("read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg,rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
7252 case 0x75://write_rf
7253 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
7254 DBG_871X("write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n",minor_cmd,arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
7260 case 0x00: //normal mode,
7261 padapter->recvpriv.is_signal_dbg = 0;
7263 case 0x01: //dbg mode
7264 padapter->recvpriv.is_signal_dbg = 1;
7265 extra_arg = extra_arg>100?100:extra_arg;
7266 padapter->recvpriv.signal_strength_dbg=extra_arg;
7270 case 0x78: //IOL test
7274 case 0x04: //LLT table initialization test
7276 u8 page_boundary = 0xf9;
7278 struct xmit_frame *xmit_frame;
7280 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7285 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
7288 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500,0) )
7293 case 0x05: //blink LED test
7297 u32 blink_delay_ms = 200;
7301 struct xmit_frame *xmit_frame;
7303 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7308 for(i=0;i<blink_num;i++){
7309 #ifdef CONFIG_IOL_NEW_GENERATION
7310 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00,0xff);
7311 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
7312 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08,0xff);
7313 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
7315 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
7316 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
7317 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
7318 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
7321 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms*blink_num*2)+200,0) )
7327 case 0x06: //continuous wirte byte test
7330 u16 start_value = 0;
7331 u32 write_num = extra_arg;
7336 struct xmit_frame *xmit_frame;
7338 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7343 for(i=0;i<write_num;i++){
7344 #ifdef CONFIG_IOL_NEW_GENERATION
7345 rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value,0xFF);
7347 rtw_IOL_append_WB_cmd(xmit_frame, reg, i+start_value);
7350 if(_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
7354 if(start_value+write_num-1 == (final=rtw_read8(padapter, reg)) ) {
7355 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
7357 DBG_871X("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
7362 case 0x07: //continuous wirte word test
7365 u16 start_value = 200;
7366 u32 write_num = extra_arg;
7372 struct xmit_frame *xmit_frame;
7374 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7379 for(i=0;i<write_num;i++){
7380 #ifdef CONFIG_IOL_NEW_GENERATION
7381 rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value,0xFFFF);
7383 rtw_IOL_append_WW_cmd(xmit_frame, reg, i+start_value);
7386 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
7390 if(start_value+write_num-1 == (final=rtw_read16(padapter, reg)) ) {
7391 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
7393 DBG_871X("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
7398 case 0x08: //continuous wirte dword test
7401 u32 start_value = 0x110000c7;
7402 u32 write_num = extra_arg;
7408 struct xmit_frame *xmit_frame;
7410 if((xmit_frame=rtw_IOL_accquire_xmit_frame(padapter)) == NULL) {
7415 for(i=0;i<write_num;i++){
7416 #ifdef CONFIG_IOL_NEW_GENERATION
7417 rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value,0xFFFFFFFF);
7419 rtw_IOL_append_WD_cmd(xmit_frame, reg, i+start_value);
7422 if(_SUCCESS !=rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000,0))
7427 if(start_value+write_num-1 == (final=rtw_read32(padapter, reg)) ) {
7428 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
7430 DBG_871X("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
7440 * dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
7441 * dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
7443 u8 value = extra_arg & 0x0f;
7444 u8 sign = minor_cmd;
7445 u16 write_value = 0;
7447 DBG_871X("%s set RESP_TXAGC to %s %u\n", __func__, sign?"minus":"plus", value);
7450 value = value | 0x10;
7452 write_value = value | (value << 5);
7453 rtw_write16(padapter, 0x6d9, write_value);
7457 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
7458 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
7464 DBG_871X("fwstate=0x%x\n", get_fwstate(pmlmepriv));
7467 DBG_871X("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
7468 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
7469 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
7472 DBG_871X("pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
7473 DBG_871X("DrvBcnEarly=%d\n", pmlmeext->DrvBcnEarly);
7474 DBG_871X("DrvBcnTimeOut=%d\n", pmlmeext->DrvBcnTimeOut);
7477 DBG_871X("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
7478 #ifdef CONFIG_80211N_HT
7479 DBG_871X("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
7480 #endif //CONFIG_80211N_HT
7483 DBG_871X("cur_ch=%d\n", pmlmeext->cur_channel);
7484 DBG_871X("cur_bw=%d\n", pmlmeext->cur_bwmode);
7485 DBG_871X("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
7487 DBG_871X("oper_ch=%d\n", rtw_get_oper_ch(padapter));
7488 DBG_871X("oper_bw=%d\n", rtw_get_oper_bw(padapter));
7489 DBG_871X("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
7493 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
7496 DBG_871X("SSID=%s\n", cur_network->network.Ssid.Ssid);
7497 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
7498 DBG_871X("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
7499 DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7500 DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7501 #ifdef CONFIG_80211N_HT
7502 DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
7503 DBG_871X("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
7504 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
7505 DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7506 #endif //CONFIG_80211N_HT
7508 sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
7512 DBG_871X("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
7520 DBG_871X("bSurpriseRemoved=%s, bDriverStopped=%s\n"
7521 , rtw_is_surprise_removed(padapter)?"True":"False"
7522 , rtw_is_drv_stopped(padapter)?"True":"False");
7526 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7527 struct recv_priv *precvpriv = &padapter->recvpriv;
7529 DBG_871X("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
7530 ", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
7531 ", free_recvframe_cnt=%d\n",
7532 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
7533 pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
7534 precvpriv->free_recvframe_cnt);
7535 #ifdef CONFIG_USB_HCI
7536 DBG_871X("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt)));
7543 _list *plist, *phead;
7545 #ifdef CONFIG_AP_MODE
7546 DBG_871X("sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
7548 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7550 for(i=0; i< NUM_STA; i++)
7552 phead = &(pstapriv->sta_hash[i]);
7553 plist = get_next(phead);
7555 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
7557 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
7559 plist = get_next(plist);
7561 if(extra_arg == psta->aid)
7563 DBG_871X("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
7564 DBG_871X("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
7565 DBG_871X("state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
7566 #ifdef CONFIG_80211N_HT
7567 DBG_871X("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
7568 DBG_871X("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n", psta->bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
7569 DBG_871X("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
7570 DBG_871X("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
7571 #endif //CONFIG_80211N_HT
7573 #ifdef CONFIG_AP_MODE
7574 DBG_871X("capability=0x%x\n", psta->capability);
7575 DBG_871X("flags=0x%x\n", psta->flags);
7576 DBG_871X("wpa_psk=0x%x\n", psta->wpa_psk);
7577 DBG_871X("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
7578 DBG_871X("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
7579 DBG_871X("qos_info=0x%x\n", psta->qos_info);
7581 DBG_871X("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
7583 sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
7589 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
7594 case 0x0b: //Enable=1, Disable=0 driver control vrtl_carrier_sense.
7596 //u8 driver_vcs_en; //Enable=1, Disable=0 driver control vrtl_carrier_sense.
7597 //u8 driver_vcs_type;//force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1.
7600 DBG_871X("disable driver ctrl vcs\n");
7601 padapter->driver_vcs_en = 0;
7604 DBG_871X("enable driver ctrl vcs = %d\n", extra_arg);
7605 padapter->driver_vcs_en = 1;
7608 padapter->driver_vcs_type = 1;
7610 padapter->driver_vcs_type = extra_arg;
7614 case 0x0c://dump rx/tx packet
7617 DBG_871X("dump rx packet (%d)\n",extra_arg);
7618 //pHalData->bDumpRxPkt =extra_arg;
7619 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
7622 DBG_871X("dump tx packet (%d)\n",extra_arg);
7623 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
7630 DBG_871X("disable driver ctrl rx_ampdu_factor\n");
7631 padapter->driver_rx_ampdu_factor = 0xFF;
7635 DBG_871X("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
7637 if(extra_arg > 0x03)
7638 padapter->driver_rx_ampdu_factor = 0xFF;
7640 padapter->driver_rx_ampdu_factor = extra_arg;
7644 #ifdef DBG_CONFIG_ERROR_DETECT
7648 DBG_871X("###### silent reset test.......#####\n");
7649 rtw_hal_sreset_reset(padapter);
7651 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7652 struct sreset_priv *psrtpriv = &pHalData->srestpriv;
7653 psrtpriv->dbg_trigger_point = extra_arg;
7660 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
7661 DBG_871X("==>silent resete cnts:%d\n",pwrpriv->ips_enter_cnts);
7667 case 0x10:// driver version display
7668 dump_drv_version(RTW_DBGDUMP);
7670 case 0x11://dump linked status
7673 pre_mode=padapter->bLinkInfoDump;
7674 // linked_info_dump(padapter,extra_arg);
7675 if(extra_arg==1 || (extra_arg==0 && pre_mode==1) ) //not consider pwr_saving 0:
7677 padapter->bLinkInfoDump = extra_arg;
7680 else if( (extra_arg==2 ) || (extra_arg==0 && pre_mode==2))//consider power_saving
7682 //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable")
7683 linked_info_dump(padapter,extra_arg);
7690 #ifdef CONFIG_80211N_HT
7691 case 0x12: //set rx_stbc
7693 struct registry_priv *pregpriv = &padapter->registrypriv;
7694 // 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g
7695 //default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ
7696 if( pregpriv && (extra_arg == 0 || extra_arg == 1|| extra_arg == 2 || extra_arg == 3))
7698 pregpriv->rx_stbc= extra_arg;
7699 DBG_871X("set rx_stbc=%d\n",pregpriv->rx_stbc);
7702 DBG_871X("get rx_stbc=%d\n",pregpriv->rx_stbc);
7706 case 0x13: //set ampdu_enable
7708 struct registry_priv *pregpriv = &padapter->registrypriv;
7709 // 0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec)
7710 if( pregpriv && extra_arg < 3 )
7712 pregpriv->ampdu_enable= extra_arg;
7713 DBG_871X("set ampdu_enable=%d\n",pregpriv->ampdu_enable);
7716 DBG_871X("get ampdu_enable=%d\n",pregpriv->ampdu_enable);
7721 case 0x14: //get wifi_spec
7723 struct registry_priv *pregpriv = &padapter->registrypriv;
7724 DBG_871X("get wifi_spec=%d\n",pregpriv->wifi_spec);
7731 rtw_odm_dbg_comp_msg(RTW_DBGDUMP,padapter);
7734 u64 dbg_comp = (u64)extra_arg;
7735 rtw_odm_dbg_comp_set(padapter, dbg_comp);
7739 #ifdef DBG_FIXED_CHAN
7742 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7743 printk("===> Fixed channel to %d \n",extra_arg);
7744 pmlmeext->fixed_chan = extra_arg;
7751 printk("===> Switch USB Mode %d \n",extra_arg);
7752 rtw_hal_set_hwreg(padapter, HW_VAR_USB_MODE, (u8 *)&extra_arg);
7755 #ifdef CONFIG_80211N_HT
7758 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7760 // BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx,
7761 // BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx
7763 DBG_871X("driver disable LDPC\n");
7764 pregistrypriv->ldpc_cap = 0x00;
7767 DBG_871X("driver set LDPC cap = 0x%x\n", extra_arg);
7768 pregistrypriv->ldpc_cap = (u8)(extra_arg&0x33);
7774 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7776 // BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx,
7777 // BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx
7779 DBG_871X("driver disable STBC\n");
7780 pregistrypriv->stbc_cap = 0x00;
7783 DBG_871X("driver set STBC cap = 0x%x\n", extra_arg);
7784 pregistrypriv->stbc_cap = (u8)(extra_arg&0x33);
7788 #endif //CONFIG_80211N_HT
7791 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7794 DBG_871X("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
7795 init_mlme_default_rate_set(padapter);
7796 #ifdef CONFIG_80211N_HT
7797 pregistrypriv->ht_enable = (u8)rtw_ht_enable;
7798 #endif //CONFIG_80211N_HT
7805 DBG_871X("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
7807 max_rx_rate = (u8)extra_arg;
7809 if(max_rx_rate < 0xc) // max_rx_rate < MSC0 -> B or G -> disable HT
7811 #ifdef CONFIG_80211N_HT
7812 pregistrypriv->ht_enable = 0;
7813 #endif //CONFIG_80211N_HT
7814 for(i=0; i<NumRates; i++)
7816 if(pmlmeext->datarate[i] > max_rx_rate)
7817 pmlmeext->datarate[i] = 0xff;
7821 #ifdef CONFIG_80211N_HT
7822 else if(max_rx_rate < 0x1c) // mcs0~mcs15
7826 for(i=0; i<((max_rx_rate+1)-0xc); i++)
7827 mcs_bitmap |= BIT(i);
7829 set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
7831 #endif //CONFIG_80211N_HT
7835 case 0x1c: //enable/disable driver control AMPDU Density for peer sta's rx
7838 DBG_871X("disable driver ctrl ampdu density\n");
7839 padapter->driver_ampdu_spacing = 0xFF;
7843 DBG_871X("enable driver ctrl ampdu density = %d\n", extra_arg);
7845 if(extra_arg > 0x07)
7846 padapter->driver_ampdu_spacing = 0xFF;
7848 padapter->driver_ampdu_spacing = extra_arg;
7852 #ifdef CONFIG_BACKGROUND_NOISE_MONITOR
7855 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7856 PDM_ODM_T pDM_Odm = &pHalData->odmpriv;
7857 u8 chan = rtw_get_oper_ch(padapter);
7858 DBG_871X("===========================================\n");
7859 ODM_InbandNoise_Monitor(pDM_Odm,_TRUE,0x1e,100);
7860 DBG_871X("channel(%d),noise_a = %d, noise_b = %d , noise_all:%d \n",
7861 chan,pDM_Odm->noise_level.noise[ODM_RF_PATH_A],
7862 pDM_Odm->noise_level.noise[ODM_RF_PATH_B],
7863 pDM_Odm->noise_level.noise_all);
7864 DBG_871X("===========================================\n");
7871 DBG_871X("turn %s the bNotifyChannelChange Variable\n",(extra_arg==1)?"on":"off");
7872 padapter->bNotifyChannelChange = extra_arg;
7878 DBG_871X("turn %s the bShowGetP2PState Variable\n",(extra_arg==1)?"on":"off");
7879 padapter->bShowGetP2PState = extra_arg;
7880 #endif // CONFIG_P2P
7883 #ifdef CONFIG_GPIO_API
7884 case 0x25: //Get GPIO register
7887 * dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
7891 DBG_871X("Read GPIO Value extra_arg = %d\n",extra_arg);
7892 value = rtw_hal_get_gpio(padapter,extra_arg);
7893 DBG_871X("Read GPIO Value = %d\n",value);
7896 case 0x26: //Set GPIO direction
7899 /* dbg 0x7f26000x [y], Set gpio direction,
7900 * x: gpio_num,4~7 y: indicate direction, 0~1
7904 DBG_871X("Set GPIO Direction! arg = %d ,extra_arg=%d\n",arg ,extra_arg);
7905 value = rtw_hal_config_gpio(padapter, arg, extra_arg);
7906 DBG_871X("Set GPIO Direction %s \n",(value==-1)?"Fail!!!":"Success");
7909 case 0x27: //Set GPIO output direction value
7912 * dbg 0x7f27000x [y], Set gpio output direction value,
7913 * x: gpio_num,4~7 y: indicate direction, 0~1
7917 DBG_871X("Set GPIO Value! arg = %d ,extra_arg=%d\n",arg ,extra_arg);
7918 value = rtw_hal_set_gpio_output_value(padapter,arg,extra_arg);
7919 DBG_871X("Set GPIO Value %s \n",(value==-1)?"Fail!!!":"Success");
7923 #ifdef DBG_CMD_QUEUE
7926 dump_cmd_id = extra_arg;
7927 DBG_871X("dump_cmd_id:%d\n",dump_cmd_id);
7930 #endif //DBG_CMD_QUEUE
7933 if((extra_arg & 0x7F)> 0x3F) extra_arg = 0xFF;
7934 DBG_871X("chang data rate to :0x%02x\n",extra_arg);
7935 padapter->fix_rate = extra_arg;
7938 case 0xdd://registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg
7941 mac_reg_dump(RTW_DBGDUMP, padapter);
7943 else if(extra_arg==1){
7944 bb_reg_dump(RTW_DBGDUMP, padapter);
7946 else if(extra_arg==2){
7947 rf_reg_dump(RTW_DBGDUMP, padapter);
7954 DBG_871X(" === please control /proc to trun on/off PHYDM func === \n");
7959 rtw_write8(padapter, 0xc50, arg);
7960 DBG_871X("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7961 rtw_write8(padapter, 0xc58, arg);
7962 DBG_871X("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7965 DBG_871X("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
7966 DBG_871X("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
7970 DBG_871X("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
7971 DBG_871X("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
7972 DBG_871X("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
7973 DBG_871X("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
7974 DBG_871X("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
7976 DBG_871X("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
7981 DBG_871X("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
7982 DBG_871X("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
7984 DBG_871X("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
7986 DBG_871X("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
7988 DBG_871X("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
7989 DBG_871X("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
7991 DBG_871X("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
7992 DBG_871X("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
7993 DBG_871X("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
7994 DBG_871X("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
8000 DBG_871X("error dbg cmd!\n");
8009 static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
8013 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8016 case IEEE_PARAM_WPA_ENABLED:
8018 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X; //802.1x
8020 //ret = ieee80211_wpa_enable(ieee, value);
8022 switch((value)&0xff)
8025 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; //WPA_PSK
8026 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
8029 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; //WPA2_PSK
8030 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
8034 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_info_,("wpa_set_param:padapter->securitypriv.ndisauthtype=%d\n", padapter->securitypriv.ndisauthtype));
8038 case IEEE_PARAM_TKIP_COUNTERMEASURES:
8039 //ieee->tkip_countermeasures=value;
8042 case IEEE_PARAM_DROP_UNENCRYPTED:
8046 * wpa_supplicant calls set_wpa_enabled when the driver
8047 * is loaded and unloaded, regardless of if WPA is being
8048 * used. No other calls are made which can be used to
8049 * determine if encryption will be used or not prior to
8050 * association being expected. If encryption is not being
8051 * used, drop_unencrypted is set to false, else true -- we
8052 * can use this to determine if the CAP_PRIVACY_ON bit should
8057 struct ieee80211_security sec = {
8058 .flags = SEC_ENABLED,
8061 ieee->drop_unencrypted = value;
8062 /* We only change SEC_LEVEL for open mode. Others
8063 * are set by ipw_wpa_set_encryption.
8066 sec.flags |= SEC_LEVEL;
8067 sec.level = SEC_LEVEL_0;
8070 sec.flags |= SEC_LEVEL;
8071 sec.level = SEC_LEVEL_1;
8073 if (ieee->set_security)
8074 ieee->set_security(ieee->dev, &sec);
8079 case IEEE_PARAM_PRIVACY_INVOKED:
8081 //ieee->privacy_invoked=value;
8085 case IEEE_PARAM_AUTH_ALGS:
8087 ret = wpa_set_auth_algs(dev, value);
8091 case IEEE_PARAM_IEEE_802_1X:
8093 //ieee->ieee802_1x=value;
8097 case IEEE_PARAM_WPAX_SELECT:
8099 // added for WPA2 mixed mode
8100 //DBG_871X(KERN_WARNING "------------------------>wpax value = %x\n", value);
8102 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
8103 ieee->wpax_type_set = 1;
8104 ieee->wpax_type_notify = value;
8105 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
8125 static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
8128 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8132 case IEEE_MLME_STA_DEAUTH:
8134 if(!rtw_set_802_11_disassociate(padapter))
8139 case IEEE_MLME_STA_DISASSOC:
8141 if(!rtw_set_802_11_disassociate(padapter))
8155 static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
8157 struct ieee_param *param;
8160 //down(&ieee->wx_sem);
8162 if (p->length < sizeof(struct ieee_param) || !p->pointer){
8167 param = (struct ieee_param *)rtw_malloc(p->length);
8174 if (copy_from_user(param, p->pointer, p->length))
8176 rtw_mfree((u8*)param, p->length);
8181 switch (param->cmd) {
8183 case IEEE_CMD_SET_WPA_PARAM:
8184 ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
8187 case IEEE_CMD_SET_WPA_IE:
8188 //ret = wpa_set_wpa_ie(dev, param, p->length);
8189 ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char*)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
8192 case IEEE_CMD_SET_ENCRYPTION:
8193 ret = wpa_set_encryption(dev, param, p->length);
8197 ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
8201 DBG_871X("Unknown WPA supplicant request: %d\n", param->cmd);
8207 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
8210 rtw_mfree((u8 *)param, p->length);
8214 //up(&ieee->wx_sem);
8220 #ifdef CONFIG_AP_MODE
8221 static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
8224 u32 wep_key_idx, wep_key_len,wep_total_len;
8225 NDIS_802_11_WEP *pwep = NULL;
8226 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
8227 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8228 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8229 struct security_priv* psecuritypriv=&(padapter->securitypriv);
8230 struct sta_priv *pstapriv = &padapter->stapriv;
8232 DBG_871X("%s\n", __FUNCTION__);
8234 param->u.crypt.err = 0;
8235 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
8237 //sizeof(struct ieee_param) = 64 bytes;
8238 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
8239 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
8245 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8246 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8247 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8249 if (param->u.crypt.idx >= WEP_KEYS
8250 #ifdef CONFIG_IEEE80211W
8251 && param->u.crypt.idx > BIP_MAX_KEYID
8252 #endif /* CONFIG_IEEE80211W */
8261 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8265 DBG_871X("rtw_set_encryption(), sta has already been removed or never been added\n");
8270 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
8272 //todo:clear default encryption keys
8274 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
8275 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
8276 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
8277 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
8279 DBG_871X("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
8285 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
8287 DBG_871X("r871x_set_encryption, crypt.alg = WEP\n");
8289 wep_key_idx = param->u.crypt.idx;
8290 wep_key_len = param->u.crypt.key_len;
8292 DBG_871X("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
8294 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
8301 if (wep_key_len > 0)
8303 wep_key_len = wep_key_len <= 5 ? 5 : 13;
8304 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
8305 pwep =(NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
8307 DBG_871X(" r871x_set_encryption: pwep allocate fail !!!\n");
8311 _rtw_memset(pwep, 0, wep_total_len);
8313 pwep->KeyLength = wep_key_len;
8314 pwep->Length = wep_total_len;
8318 pwep->KeyIndex = wep_key_idx;
8320 _rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
8322 if(param->u.crypt.set_tx)
8324 DBG_871X("wep, set_tx=1\n");
8326 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
8327 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
8328 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
8329 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
8331 if(pwep->KeyLength==13)
8333 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
8334 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
8338 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
8340 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
8342 psecuritypriv->dot11DefKeylen[wep_key_idx]=pwep->KeyLength;
8344 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
8348 DBG_871X("wep, set_tx=0\n");
8350 //don't update "psecuritypriv->dot11PrivacyAlgrthm" and
8351 //"psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam
8353 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
8355 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
8357 rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
8365 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
8367 if(param->u.crypt.set_tx ==1)
8369 if(strcmp(param->u.crypt.alg, "WEP") == 0)
8371 DBG_871X("%s, set group_key, WEP\n", __FUNCTION__);
8373 _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));
8375 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
8376 if(param->u.crypt.key_len==13)
8378 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
8382 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
8384 DBG_871X("%s, set group_key, TKIP\n", __FUNCTION__);
8386 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
8388 _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));
8390 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
8392 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
8393 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
8395 psecuritypriv->busetkipkey = _TRUE;
8398 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
8400 DBG_871X("%s, set group_key, CCMP\n", __FUNCTION__);
8402 psecuritypriv->dot118021XGrpPrivacy = _AES_;
8404 _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));
8406 #ifdef CONFIG_IEEE80211W
8407 else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
8410 DBG_871X("BIP key_len=%d , index=%d\n", param->u.crypt.key_len, param->u.crypt.idx);
8411 /* save the IGTK key, length 16 bytes */
8412 _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));
8413 /* DBG_871X("IGTK key below:\n");
8414 for(no=0;no<16;no++)
8415 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
8417 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
8418 padapter->securitypriv.binstallBIPkey = _TRUE;
8419 DBG_871X(" ~~~~set sta key:IGKT\n");
8422 #endif /* CONFIG_IEEE80211W */
8425 DBG_871X("%s, set group_key, none\n", __FUNCTION__);
8427 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
8430 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
8432 psecuritypriv->binstallGrpkey = _TRUE;
8434 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
8436 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
8438 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
8441 pbcmc_sta->ieee8021x_blocked = _FALSE;
8442 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
8451 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
8453 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
8455 if(param->u.crypt.set_tx ==1)
8457 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
8459 if(strcmp(param->u.crypt.alg, "WEP") == 0)
8461 DBG_871X("%s, set pairwise key, WEP\n", __FUNCTION__);
8463 psta->dot118021XPrivacy = _WEP40_;
8464 if(param->u.crypt.key_len==13)
8466 psta->dot118021XPrivacy = _WEP104_;
8469 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
8471 DBG_871X("%s, set pairwise key, TKIP\n", __FUNCTION__);
8473 psta->dot118021XPrivacy = _TKIP_;
8475 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
8477 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
8478 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
8480 psecuritypriv->busetkipkey = _TRUE;
8483 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
8486 DBG_871X("%s, set pairwise key, CCMP\n", __FUNCTION__);
8488 psta->dot118021XPrivacy = _AES_;
8492 DBG_871X("%s, set pairwise key, none\n", __FUNCTION__);
8494 psta->dot118021XPrivacy = _NO_PRIVACY_;
8497 rtw_ap_set_pairwise_key(padapter, psta);
8499 psta->ieee8021x_blocked = _FALSE;
8501 psta->bpairwise_key_installed = _TRUE;
8506 if(strcmp(param->u.crypt.alg, "WEP") == 0)
8508 _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));
8510 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
8511 if(param->u.crypt.key_len==13)
8513 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
8516 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
8518 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
8520 _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));
8522 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
8524 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
8525 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
8527 psecuritypriv->busetkipkey = _TRUE;
8530 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
8532 psecuritypriv->dot118021XGrpPrivacy = _AES_;
8534 _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));
8538 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
8541 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
8543 psecuritypriv->binstallGrpkey = _TRUE;
8545 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
8547 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
8549 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
8552 pbcmc_sta->ieee8021x_blocked = _FALSE;
8553 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
8566 rtw_mfree((u8 *)pwep, wep_total_len);
8573 static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
8576 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8577 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8578 struct sta_priv *pstapriv = &padapter->stapriv;
8579 unsigned char *pbuf = param->u.bcn_ie.buf;
8582 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8584 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8587 _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
8589 if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
8590 pstapriv->max_num_sta = NUM_STA;
8593 if(rtw_check_beacon_data(padapter, pbuf, (len-12-2)) == _SUCCESS)// 12 = param header, 2:no packed
8603 static int rtw_hostapd_sta_flush(struct net_device *dev)
8606 //_list *phead, *plist;
8608 //struct sta_info *psta = NULL;
8609 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8610 //struct sta_priv *pstapriv = &padapter->stapriv;
8612 DBG_871X("%s\n", __FUNCTION__);
8614 flush_all_cam_entry(padapter); //clear CAM
8616 ret = rtw_sta_flush(padapter, _TRUE);
8622 static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
8626 struct sta_info *psta = NULL;
8627 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8628 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8629 struct sta_priv *pstapriv = &padapter->stapriv;
8631 DBG_871X("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
8633 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8638 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8639 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8640 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8646 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8649 DBG_871X("rtw_add_sta(), free has been added psta=%p\n", psta);
8650 //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8651 rtw_free_stainfo(padapter, psta);
8652 //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
8657 //psta = rtw_alloc_stainfo(pstapriv, param->sta_addr);
8658 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8661 int flags = param->u.add_sta.flags;
8663 //DBG_871X("rtw_add_sta(), init sta's variables, psta=%p\n", psta);
8665 psta->aid = param->u.add_sta.aid;//aid=1~2007
8667 _rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
8671 if(WLAN_STA_WME&flags)
8672 psta->qos_option = 1;
8674 psta->qos_option = 0;
8676 if(pmlmepriv->qospriv.qos_option == 0)
8677 psta->qos_option = 0;
8680 #ifdef CONFIG_80211N_HT
8681 //chec 802.11n ht cap.
8682 if(WLAN_STA_HT&flags)
8684 psta->htpriv.ht_option = _TRUE;
8685 psta->qos_option = 1;
8686 _rtw_memcpy((void*)&psta->htpriv.ht_cap, (void*)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8690 psta->htpriv.ht_option = _FALSE;
8693 if(pmlmepriv->htpriv.ht_option == _FALSE)
8694 psta->htpriv.ht_option = _FALSE;
8698 update_sta_info_apmode(padapter, psta);
8711 static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
8715 struct sta_info *psta = NULL;
8716 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8717 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8718 struct sta_priv *pstapriv = &padapter->stapriv;
8720 DBG_871X("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
8722 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8727 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8728 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8729 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8734 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8739 //DBG_871X("free psta=%p, aid=%d\n", psta, psta->aid);
8741 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8742 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
8744 rtw_list_delete(&psta->asoc_list);
8745 pstapriv->asoc_list_cnt--;
8746 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
8749 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
8751 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
8758 DBG_871X("rtw_del_sta(), sta has already been removed or never been added\n");
8768 static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
8771 struct sta_info *psta = NULL;
8772 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8773 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8774 struct sta_priv *pstapriv = &padapter->stapriv;
8775 struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
8776 struct sta_data *psta_data = (struct sta_data *)param_ex->data;
8778 DBG_871X("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
8780 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8785 if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
8786 param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
8787 param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
8792 psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
8801 u8 tx_supp_rates[16];
8802 u32 tx_supp_rates_len;
8803 struct rtw_ieee80211_ht_cap ht_cap;
8812 psta_data->aid = (u16)psta->aid;
8813 psta_data->capability = psta->capability;
8814 psta_data->flags = psta->flags;
8818 no_short_slot_time_set : BIT(1)
8819 no_short_preamble_set : BIT(2)
8820 no_ht_gf_set : BIT(3)
8822 ht_20mhz_set : BIT(5)
8825 psta_data->sta_set =((psta->nonerp_set) |
8826 (psta->no_short_slot_time_set <<1) |
8827 (psta->no_short_preamble_set <<2) |
8828 (psta->no_ht_gf_set <<3) |
8829 (psta->no_ht_set <<4) |
8830 (psta->ht_20mhz_set <<5));
8832 psta_data->tx_supp_rates_len = psta->bssratelen;
8833 _rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
8834 #ifdef CONFIG_80211N_HT
8835 _rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
8836 #endif //CONFIG_80211N_HT
8837 psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
8838 psta_data->rx_bytes = psta->sta_stats.rx_bytes;
8839 psta_data->rx_drops = psta->sta_stats.rx_drops;
8841 psta_data->tx_pkts = psta->sta_stats.tx_pkts;
8842 psta_data->tx_bytes = psta->sta_stats.tx_bytes;
8843 psta_data->tx_drops = psta->sta_stats.tx_drops;
8856 static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
8859 struct sta_info *psta = NULL;
8860 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8861 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8862 struct sta_priv *pstapriv = &padapter->stapriv;
8864 DBG_871X("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
8866 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
8871 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
8872 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
8873 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
8878 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
8881 if((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC))
8886 wpa_ie_len = psta->wpa_ie[1];
8888 copy_len = ((wpa_ie_len+2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)):(wpa_ie_len+2);
8890 param->u.wpa_ie.len = copy_len;
8892 _rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
8897 DBG_871X("sta's wpa_ie is NONE\n");
8909 static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
8912 unsigned char wps_oui[4]={0x0,0x50,0xf2,0x04};
8913 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8914 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8915 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8916 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8919 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8921 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8924 ie_len = len-12-2;// 12 = param header, 2:no packed
8927 if(pmlmepriv->wps_beacon_ie)
8929 rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
8930 pmlmepriv->wps_beacon_ie = NULL;
8935 pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
8936 pmlmepriv->wps_beacon_ie_len = ie_len;
8937 if ( pmlmepriv->wps_beacon_ie == NULL) {
8938 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8942 _rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
8944 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
8946 pmlmeext->bstart_bss = _TRUE;
8955 static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
8958 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8959 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8962 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
8964 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
8967 ie_len = len-12-2;// 12 = param header, 2:no packed
8970 if(pmlmepriv->wps_probe_resp_ie)
8972 rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
8973 pmlmepriv->wps_probe_resp_ie = NULL;
8978 pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
8979 pmlmepriv->wps_probe_resp_ie_len = ie_len;
8980 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
8981 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8984 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
8992 static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
8995 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8996 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8999 DBG_871X("%s, len=%d\n", __FUNCTION__, len);
9001 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
9004 ie_len = len-12-2;// 12 = param header, 2:no packed
9007 if(pmlmepriv->wps_assoc_resp_ie)
9009 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
9010 pmlmepriv->wps_assoc_resp_ie = NULL;
9015 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
9016 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
9017 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
9018 DBG_871X("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9022 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
9030 static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
9033 _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
9034 struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
9035 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
9036 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
9039 char ssid[NDIS_802_11_LENGTH_SSID + 1];
9041 u8 ignore_broadcast_ssid;
9043 if(check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
9046 if (param->u.bcn_ie.reserved[0] != 0xea)
9049 mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
9051 ie_len = len-12-2;// 12 = param header, 2:no packed
9052 ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
9054 if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
9055 WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
9056 WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
9058 _rtw_memcpy(ssid, ssid_ie+2, ssid_len);
9059 ssid[ssid_len] = 0x0;
9062 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
9064 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
9065 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
9067 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
9068 pbss_network->Ssid.SsidLength = ssid_len;
9069 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
9070 pbss_network_ext->Ssid.SsidLength = ssid_len;
9073 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
9074 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
9075 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
9078 DBG_871X(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
9079 ignore_broadcast_ssid, ssid, ssid_len);
9084 static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
9087 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9088 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9090 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
9093 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
9094 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
9095 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
9100 ret = rtw_acl_remove_sta(padapter, param->sta_addr);
9106 static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
9109 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9110 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9112 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
9115 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
9116 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
9117 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
9122 ret = rtw_acl_add_sta(padapter, param->sta_addr);
9128 static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
9131 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9132 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9134 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
9137 rtw_set_macaddr_acl(padapter, param->u.mlme.command);
9142 static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
9144 struct ieee_param *param;
9146 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9148 //DBG_871X("%s\n", __FUNCTION__);
9151 * this function is expect to call in master mode, which allows no power saving
9152 * so, we just check hw_init_completed
9155 if (!rtw_is_hw_init_completed(padapter)) {
9161 //if (p->length < sizeof(struct ieee_param) || !p->pointer){
9167 param = (struct ieee_param *)rtw_malloc(p->length);
9174 if (copy_from_user(param, p->pointer, p->length))
9176 rtw_mfree((u8*)param, p->length);
9181 //DBG_871X("%s, cmd=%d\n", __FUNCTION__, param->cmd);
9185 case RTL871X_HOSTAPD_FLUSH:
9187 ret = rtw_hostapd_sta_flush(dev);
9191 case RTL871X_HOSTAPD_ADD_STA:
9193 ret = rtw_add_sta(dev, param);
9197 case RTL871X_HOSTAPD_REMOVE_STA:
9199 ret = rtw_del_sta(dev, param);
9203 case RTL871X_HOSTAPD_SET_BEACON:
9205 ret = rtw_set_beacon(dev, param, p->length);
9209 case RTL871X_SET_ENCRYPTION:
9211 ret = rtw_set_encryption(dev, param, p->length);
9215 case RTL871X_HOSTAPD_GET_WPAIE_STA:
9217 ret = rtw_get_sta_wpaie(dev, param);
9221 case RTL871X_HOSTAPD_SET_WPS_BEACON:
9223 ret = rtw_set_wps_beacon(dev, param, p->length);
9227 case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
9229 ret = rtw_set_wps_probe_resp(dev, param, p->length);
9233 case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
9235 ret = rtw_set_wps_assoc_resp(dev, param, p->length);
9239 case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
9241 ret = rtw_set_hidden_ssid(dev, param, p->length);
9245 case RTL871X_HOSTAPD_GET_INFO_STA:
9247 ret = rtw_ioctl_get_sta_data(dev, param, p->length);
9251 case RTL871X_HOSTAPD_SET_MACADDR_ACL:
9253 ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
9257 case RTL871X_HOSTAPD_ACL_ADD_STA:
9259 ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
9263 case RTL871X_HOSTAPD_ACL_REMOVE_STA:
9265 ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
9270 DBG_871X("Unknown hostapd request: %d\n", param->cmd);
9276 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
9280 rtw_mfree((u8 *)param, p->length);
9289 static int rtw_wx_set_priv(struct net_device *dev,
9290 struct iw_request_info *info,
9291 union iwreq_data *awrq,
9295 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
9304 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9305 struct iw_point *dwrq = (struct iw_point*)awrq;
9307 //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_, ("+rtw_wx_set_priv\n"));
9308 if(dwrq->length == 0)
9312 if (!(ext = rtw_vmalloc(len)))
9315 if (copy_from_user(ext, dwrq->pointer, len)) {
9316 rtw_vmfree(ext, len);
9321 //RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_notice_,
9322 // ("rtw_wx_set_priv: %s req=%s\n",
9323 // dev->name, ext));
9325 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
9326 if (!(ext_dbg = rtw_vmalloc(len)))
9328 rtw_vmfree(ext, len);
9332 _rtw_memcpy(ext_dbg, ext, len);
9335 //added for wps2.0 @20110524
9336 if(dwrq->flags == 0x8766 && len > 8)
9339 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9340 u8 *probereq_wpsie = ext;
9341 int probereq_wpsie_len = len;
9342 u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
9344 if((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
9345 (_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) ==_TRUE))
9347 cp_sz = probereq_wpsie_len>MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN:probereq_wpsie_len;
9349 if(pmlmepriv->wps_probe_req_ie)
9351 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
9352 pmlmepriv->wps_probe_req_ie_len = 0;
9353 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
9354 pmlmepriv->wps_probe_req_ie = NULL;
9357 pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
9358 if ( pmlmepriv->wps_probe_req_ie == NULL) {
9359 printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9365 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
9366 pmlmepriv->wps_probe_req_ie_len = cp_sz;
9374 if( len >= WEXT_CSCAN_HEADER_SIZE
9375 && _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
9377 ret = rtw_wx_set_scan(dev, info, awrq, ext);
9381 #ifdef CONFIG_ANDROID
9382 //DBG_871X("rtw_wx_set_priv: %s req=%s\n", dev->name, ext);
9384 i = rtw_android_cmdstr_to_num(ext);
9387 case ANDROID_WIFI_CMD_START :
9388 indicate_wx_custom_event(padapter, "START");
9390 case ANDROID_WIFI_CMD_STOP :
9391 indicate_wx_custom_event(padapter, "STOP");
9393 case ANDROID_WIFI_CMD_RSSI :
9395 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9396 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
9398 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
9399 sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
9405 case ANDROID_WIFI_CMD_LINKSPEED :
9407 u16 mbps = rtw_get_cur_max_rate(padapter)/10;
9408 sprintf(ext, "LINKSPEED %d", mbps);
9411 case ANDROID_WIFI_CMD_MACADDR :
9412 sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
9414 case ANDROID_WIFI_CMD_SCAN_ACTIVE :
9416 //rtw_set_scan_mode(padapter, SCAN_ACTIVE);
9420 case ANDROID_WIFI_CMD_SCAN_PASSIVE :
9422 //rtw_set_scan_mode(padapter, SCAN_PASSIVE);
9427 case ANDROID_WIFI_CMD_COUNTRY :
9429 char country_code[10];
9430 sscanf(ext, "%*s %s", country_code);
9431 rtw_set_country(padapter, country_code);
9436 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
9437 DBG_871X("%s: %s unknowned req=%s\n", __FUNCTION__,
9438 dev->name, ext_dbg);
9445 if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext)+1)) ) )
9448 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
9449 DBG_871X("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
9450 dev->name, ext_dbg ,ext, dwrq->length, (u16)(strlen(ext)+1));
9452 #endif //end of CONFIG_ANDROID
9457 rtw_vmfree(ext, len);
9458 #ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
9459 rtw_vmfree(ext_dbg, len);
9462 //DBG_871X("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n",
9468 #ifdef CONFIG_WOWLAN
9469 static int rtw_wowlan_ctrl(struct net_device *dev,
9470 struct iw_request_info *info,
9471 union iwreq_data *wrqu, char *extra)
9473 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9474 struct wowlan_ioctl_param poidparam;
9475 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
9476 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9477 struct net_device *pnetdev = padapter->pnetdev;
9478 #ifdef CONFIG_CONCURRENT_MODE
9479 struct net_device *pbuddy_netdev = padapter->pbuddy_adapter->pnetdev;
9481 struct sta_info *psta = NULL;
9483 u32 start_time = rtw_get_current_time();
9484 poidparam.subcode = 0;
9486 DBG_871X("+rtw_wowlan_ctrl: %s\n", extra);
9488 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
9489 check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
9490 #ifdef CONFIG_PNO_SUPPORT
9491 pwrctrlpriv->wowlan_pno_enable = _TRUE;
9493 DBG_871X("[%s] WARNING: Please Connect With AP First!!\n", __func__);
9494 goto _rtw_wowlan_ctrl_exit_free;
9495 #endif //CONFIG_PNO_SUPPORT
9498 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
9499 rtw_scan_abort(padapter);
9501 if (_rtw_memcmp(extra, "enable", 6)) {
9503 padapter->registrypriv.mp_mode = 1;
9505 rtw_suspend_common(padapter);
9507 } else if (_rtw_memcmp(extra, "disable", 7)) {
9508 #ifdef CONFIG_USB_HCI
9509 RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
9510 RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
9512 rtw_resume_common(padapter);
9514 #ifdef CONFIG_PNO_SUPPORT
9515 pwrctrlpriv->wowlan_pno_enable = _FALSE;
9516 #endif //CONFIG_PNO_SUPPORT
9518 padapter->registrypriv.mp_mode = 0;
9520 DBG_871X("[%s] Invalid Parameter.\n", __func__);
9521 goto _rtw_wowlan_ctrl_exit_free;
9523 //mutex_lock(&ioctl_mutex);
9524 _rtw_wowlan_ctrl_exit_free:
9525 DBG_871X("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
9526 DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__,
9527 rtw_get_passing_time_ms(start_time));
9528 _rtw_wowlan_ctrl_exit:
9532 static bool rtw_wowlan_parser_pattern_cmd(u8 *input, char *pattern,
9533 int *pattern_len, char *bit_mask)
9535 char *cp = NULL, *end = NULL;
9537 int pos = 0, mask_pos = 0, res = 0;
9540 cp = strchr(input, '=');
9549 cp = strchr(input, ':');
9552 len = strlen(input) - strlen(cp);
9559 if (bit_mask && (strcmp(input, "-") == 0 ||
9560 strcmp(input, "xx") == 0 ||
9561 strcmp(input, "--") == 0)) {
9562 /* skip this byte and leave mask bit unset */
9565 strncpy(member, input, len);
9566 if (!rtw_check_pattern_valid(member, sizeof(member))) {
9567 DBG_871X("%s:[ERROR] pattern is invalid!!\n",
9572 res = sscanf(member, "%02hhx", &hex);
9576 bit_mask[mask_pos] |= 1 << (pos % 8);
9585 (*pattern_len) = pos;
9593 * IP filter This pattern if for a frame containing a ip packet:
9594 * 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
9596 * A: Ethernet destination address
9597 * B: Ethernet source address
9598 * C: Ethernet protocol type
9599 * D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20)
9601 * F: IP source address ( 192.168.0.4: C0:A8:00:2C )
9602 * G: IP destination address ( 192.168.0.4: C0:A8:00:2C )
9603 * H: Source port (1024: 04:00)
9604 * I: Destination port (1024: 04:00)
9607 static int rtw_wowlan_set_pattern(struct net_device *dev,
9608 struct iw_request_info *info,
9609 union iwreq_data *wrqu, char *extra)
9611 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9612 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
9613 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9614 struct wowlan_ioctl_param poidparam;
9615 int ret = 0, len = 0, i = 0;
9616 u32 start_time = rtw_get_current_time();
9617 u8 input[wrqu->data.length];
9620 poidparam.subcode = 0;
9622 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
9623 check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
9625 DBG_871X("Please Connect With AP First!!\n");
9626 goto _rtw_wowlan_set_pattern_exit;
9629 if (wrqu->data.length <= 0) {
9631 DBG_871X("ERROR: parameter length <= 0\n");
9632 goto _rtw_wowlan_set_pattern_exit;
9635 if (copy_from_user(input,
9636 wrqu->data.pointer, wrqu->data.length))
9638 /* leave PS first */
9639 rtw_ps_deny(padapter, PS_DENY_IOCTL);
9640 LeaveAllPowerSaveModeDirect(padapter);
9641 if (strncmp(input, "pattern=", 8) == 0) {
9642 if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_NUM) {
9643 DBG_871X("WARNING: priv-pattern is full(%d)\n",
9645 DBG_871X("WARNING: please clean priv-pattern first\n");
9647 goto _rtw_wowlan_set_pattern_exit;
9649 index = pwrpriv->wowlan_pattern_idx;
9651 ret = rtw_wowlan_parser_pattern_cmd(input,
9652 pwrpriv->patterns[index].content,
9653 &pwrpriv->patterns[index].len,
9654 pwrpriv->patterns[index].mask);
9657 pwrpriv->wowlan_pattern_idx++;
9658 pwrpriv->wowlan_pattern = _TRUE;
9661 } else if (strncmp(input, "clean", 5) == 0) {
9662 poidparam.subcode = WOWLAN_PATTERN_CLEAN;
9663 rtw_hal_set_hwreg(padapter,
9664 HW_VAR_WOWLAN, (u8 *)&poidparam);
9665 pwrpriv->wowlan_pattern = _FALSE;
9666 } else if (strncmp(input, "show", 4) == 0) {
9667 for (i = 0 ; i < MAX_WKFM_NUM ; i++) {
9668 DBG_871X("=======[%d]=======\n", i);
9669 rtw_read_from_frame_mask(padapter, i);
9672 DBG_871X("********[RTK priv-patterns]*********\n");
9673 for (i = 0 ; i < MAX_WKFM_NUM ; i++)
9674 rtw_dump_priv_pattern(padapter, i);
9676 DBG_871X("ERROR: incorrect parameter!\n");
9679 rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
9681 _rtw_wowlan_set_pattern_exit:
9684 #endif //CONFIG_WOWLAN
9686 #ifdef CONFIG_AP_WOWLAN
9687 static int rtw_ap_wowlan_ctrl(struct net_device *dev,
9688 struct iw_request_info *info,
9689 union iwreq_data *wrqu, char *extra)
9691 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9692 struct wowlan_ioctl_param poidparam;
9693 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
9694 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9695 struct sta_info *psta = NULL;
9697 u32 start_time = rtw_get_current_time();
9698 poidparam.subcode = 0;
9700 DBG_871X("+rtw_ap_wowlan_ctrl: %s\n", extra);
9702 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
9703 DBG_871X("[%s] It is not AP mode!!\n", __func__);
9704 goto _rtw_ap_wowlan_ctrl_exit_free;
9707 if (_rtw_memcmp(extra, "enable", 6)) {
9709 pwrctrlpriv->wowlan_ap_mode = _TRUE;
9711 rtw_suspend_common(padapter);
9712 } else if (_rtw_memcmp(extra, "disable", 7)) {
9713 #ifdef CONFIG_USB_HCI
9714 RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
9715 RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
9717 rtw_resume_common(padapter);
9719 DBG_871X("[%s] Invalid Parameter.\n", __func__);
9720 goto _rtw_ap_wowlan_ctrl_exit_free;
9722 //mutex_lock(&ioctl_mutex);
9723 _rtw_ap_wowlan_ctrl_exit_free:
9724 DBG_871X("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
9725 DBG_871X_LEVEL(_drv_always_, "%s in %d ms\n", __func__,
9726 rtw_get_passing_time_ms(start_time));
9727 _rtw_ap_wowlan_ctrl_exit:
9730 #endif //CONFIG_AP_WOWLAN
9732 static int rtw_pm_set(struct net_device *dev,
9733 struct iw_request_info *info,
9734 union iwreq_data *wrqu, char *extra)
9738 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
9740 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
9742 if ( _rtw_memcmp( extra, "lps=", 4 ) )
9744 sscanf(extra+4, "%u", &mode);
9745 ret = rtw_pm_set_lps(padapter,mode);
9747 else if ( _rtw_memcmp( extra, "ips=", 4 ) )
9749 sscanf(extra+4, "%u", &mode);
9750 ret = rtw_pm_set_ips(padapter,mode);
9759 static int rtw_mp_efuse_get(struct net_device *dev,
9760 struct iw_request_info *info,
9761 union iwreq_data *wdata, char *extra)
9763 PADAPTER padapter = rtw_netdev_priv(dev);
9764 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
9766 PEFUSE_HAL pEfuseHal;
9767 struct iw_point *wrqu;
9769 u8 *PROMContent = pHalData->efuse_eeprom_data;
9770 u8 ips_mode = IPS_NUM; // init invalid value
9771 u8 lps_mode = PS_MODE_NUM; // init invalid value
9772 struct pwrctrl_priv *pwrctrlpriv ;
9775 char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
9776 u16 i=0, j=0, mapLen=0, addr=0, cnts=0;
9777 u16 max_available_len = 0, raw_cursize = 0, raw_maxsize = 0;
9780 u8 org_fw_iol = padapter->registrypriv.fw_iol;// 0:Disable, 1:enable, 2:by usb speed
9783 wrqu = (struct iw_point*)wdata;
9784 pwrctrlpriv = adapter_to_pwrctl(padapter);
9785 pEfuseHal = &pHalData->EfuseHal;
9788 data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9794 rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
9795 if (rawdata == NULL)
9801 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9807 lps_mode = pwrctrlpriv->power_mgnt;//keep org value
9808 rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
9812 ips_mode = pwrctrlpriv->ips_mode;//keep org value
9813 rtw_pm_set_ips(padapter,IPS_NONE);
9817 DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
9820 //mac 16 "00e04c871200" rmap,00,2
9821 while ((token = strsep(&pch, ",")) != NULL)
9828 padapter->registrypriv.fw_iol = 0;// 0:Disable, 1:enable, 2:by usb speed
9831 if(strcmp(tmp[0], "status") == 0){
9832 sprintf(extra, "Load File efuse=%s,Load File MAC=%s"
9833 , pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK"
9834 , pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK"
9838 else if (strcmp(tmp[0], "drvmap") == 0)
9840 mapLen = EFUSE_MAP_SIZE;
9842 sprintf(extra, "\n");
9843 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9845 // DBG_871X("0x%02x\t", i);
9846 sprintf(extra, "%s0x%02x\t", extra, i);
9847 for (j=0; j<8; j++) {
9848 // DBG_871X("%02X ", data[i+j]);
9849 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9852 sprintf(extra, "%s\t", extra);
9854 // DBG_871X("%02X ", data[i+j]);
9855 sprintf(extra, "%s%02X ", extra, PROMContent[i+j]);
9858 sprintf(extra,"%s\n",extra);
9862 else if (strcmp(tmp[0], "realmap") == 0)
9864 mapLen = EFUSE_MAP_SIZE;
9865 if (rtw_efuse_mask_map_read(padapter, EFUSE_WIFI , mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL)
9867 DBG_871X("%s: read realmap Fail!!\n", __FUNCTION__);
9872 // DBG_871X("OFFSET\tVALUE(hex)\n");
9873 sprintf(extra, "\n");
9874 for (i = 0; i < EFUSE_MAP_SIZE; i += 16)
9876 // DBG_871X("0x%02x\t", i);
9877 sprintf(extra, "%s0x%02x\t", extra, i);
9878 for (j=0; j<8; j++) {
9879 // DBG_871X("%02X ", data[i+j]);
9880 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9883 sprintf(extra, "%s\t", extra);
9885 // DBG_871X("%02X ", data[i+j]);
9886 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseInitMap[i+j]);
9889 sprintf(extra,"%s\n",extra);
9893 else if (strcmp(tmp[0], "rmap") == 0)
9895 if ((tmp[1]==NULL) || (tmp[2]==NULL))
9897 DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9903 addr = simple_strtoul(tmp[1], &ptmp, 16);
9904 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
9906 cnts = simple_strtoul(tmp[2], &ptmp, 10);
9909 DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9913 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
9915 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (PVOID)&max_available_len, _FALSE);
9916 if ((addr + cnts) > max_available_len)
9918 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9923 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL)
9925 DBG_871X("%s: rtw_efuse_mask_map_read error!\n", __func__);
9930 // DBG_871X("%s: data={", __FUNCTION__);
9932 for (i=0; i<cnts; i++) {
9933 // DBG_871X("0x%02x ", data[i]);
9934 sprintf(extra, "%s0x%02X ", extra, data[i]);
9938 else if (strcmp(tmp[0], "realraw") == 0)
9941 mapLen = EFUSE_MAX_SIZE;
9942 DBG_871X("EFUSE_MAX_SIZE = %d\n", EFUSE_MAX_SIZE);
9944 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
9945 DBG_871X("%s: rtw_efuse_access Fail!!\n", __func__);
9953 _rtw_memset(extra,'\0',strlen(extra));
9955 sprintf(extra, "\n0x00\t");
9957 for (i = 0; i < mapLen ; i++) {
9958 sprintf(extra, "%s%02X", extra, rawdata[i]);
9959 if ((i & 0xF) == 0xF) {
9960 sprintf(extra, "%s\n", extra);
9961 sprintf(extra, "%s0x%02x\t", extra, i+1);
9962 } else if ((i & 0x7) == 0x7) {
9963 sprintf(extra, "%s \t", extra);
9965 sprintf(extra, "%s ", extra);
9969 } else if (strcmp(tmp[0], "realrawb") == 0) {
9971 mapLen = EFUSE_MAX_SIZE;
9972 DBG_871X("EFUSE_MAX_SIZE =%d\n", EFUSE_MAX_SIZE);
9973 if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL)
9975 DBG_871X("%s: rtw_efuse_access Fail!!\n", __FUNCTION__);
9979 _rtw_memset(extra,'\0',strlen(extra));
9980 // DBG_871X("%s: realraw={\n", __FUNCTION__);
9981 sprintf(extra, "\n0x00\t");
9982 for (i= 512; i< mapLen; i++)
9984 // DBG_871X("%02X", rawdata[i]);
9985 sprintf(extra, "%s%02X", extra, rawdata[i]);
9986 if ((i & 0xF) == 0xF) {
9988 sprintf(extra, "%s\n", extra);
9989 sprintf(extra, "%s0x%02x\t", extra, i+1);
9991 else if ((i & 0x7) == 0x7){
9993 sprintf(extra, "%s \t", extra);
9996 sprintf(extra, "%s ", extra);
10001 else if (strcmp(tmp[0], "mac") == 0)
10003 if (hal_efuse_macaddr_offset(padapter) == -1) {
10008 addr = hal_efuse_macaddr_offset(padapter);
10011 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10012 if ((addr + cnts) > max_available_len) {
10013 DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10018 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL)
10020 DBG_871X("%s: rtw_efuse_mask_map_read error!\n", __func__);
10025 // DBG_871X("%s: MAC address={", __FUNCTION__);
10027 for (i=0; i<cnts; i++)
10029 // DBG_871X("%02X", data[i]);
10030 sprintf(extra, "%s%02X", extra, data[i]);
10034 sprintf(extra,"%s:",extra);
10037 // DBG_871X("}\n");
10039 else if (strcmp(tmp[0], "vidpid") == 0)
10041 #ifdef CONFIG_RTL8188E
10042 #ifdef CONFIG_USB_HCI
10043 addr = EEPROM_VID_88EU;
10045 #ifdef CONFIG_PCI_HCI
10046 addr = EEPROM_VID_88EE;
10048 #endif // CONFIG_RTL8188E
10050 #ifdef CONFIG_RTL8192E
10051 #ifdef CONFIG_USB_HCI
10052 addr = EEPROM_VID_8192EU;
10054 #ifdef CONFIG_PCI_HCI
10055 addr = EEPROM_VID_8192EE;
10057 #endif // CONFIG_RTL8192E
10058 #ifdef CONFIG_RTL8723B
10059 addr = EEPROM_VID_8723BU;
10060 #endif // CONFIG_RTL8192E
10062 #ifdef CONFIG_RTL8188F
10063 addr = EEPROM_VID_8188FU;
10064 #endif /* CONFIG_RTL8188F */
10066 #ifdef CONFIG_RTL8703B
10067 #ifdef CONFIG_USB_HCI
10068 addr = EEPROM_VID_8703BU;
10070 #endif /* CONFIG_RTL8703B */
10074 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10075 if ((addr + cnts) > max_available_len) {
10076 DBG_871X("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10080 if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL)
10082 DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
10087 // DBG_871X("%s: {VID,PID}={", __FUNCTION__);
10089 for (i=0; i<cnts; i++)
10091 // DBG_871X("0x%02x", data[i]);
10092 sprintf(extra, "%s0x%02X", extra, data[i]);
10096 sprintf(extra,"%s,",extra);
10099 // DBG_871X("}\n");
10100 } else if (strcmp(tmp[0], "ableraw") == 0) {
10101 efuse_GetCurrentSize(padapter, &raw_cursize);
10102 raw_maxsize = efuse_GetMaxSize(padapter);
10103 sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
10104 } else if (strcmp(tmp[0], "btableraw") == 0) {
10105 efuse_bt_GetCurrentSize(padapter, &raw_cursize);
10106 raw_maxsize = efuse_bt_GetMaxSize(padapter);
10107 sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
10108 } else if (strcmp(tmp[0], "btfmap") == 0) {
10110 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10112 mapLen = EFUSE_BT_MAX_MAP_LEN;
10113 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
10115 DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
10120 // DBG_871X("OFFSET\tVALUE(hex)\n");
10121 sprintf(extra, "\n");
10122 for (i=0; i<512; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF
10124 // DBG_871X("0x%03x\t", i);
10125 sprintf(extra, "%s0x%03x\t", extra, i);
10126 for (j=0; j<8; j++) {
10127 // DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
10128 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
10131 sprintf(extra,"%s\t",extra);
10132 for (; j<16; j++) {
10133 // DBG_871X("%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
10134 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
10137 sprintf(extra, "%s\n", extra);
10141 else if (strcmp(tmp[0],"btbmap") == 0)
10143 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10145 mapLen = EFUSE_BT_MAX_MAP_LEN;
10146 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL)
10148 DBG_871X("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
10153 // DBG_871X("OFFSET\tVALUE(hex)\n");
10154 sprintf(extra, "\n");
10155 for (i=512; i<1024 ; i+=16)
10157 // DBG_871X("0x%03x\t", i);
10158 sprintf(extra, "%s0x%03x\t", extra, i);
10159 for (j=0; j<8; j++)
10161 // DBG_871X("%02X ", data[i+j]);
10162 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
10165 sprintf(extra,"%s\t",extra);
10166 for (; j<16; j++) {
10167 // DBG_871X("%02X ", data[i+j]);
10168 sprintf(extra, "%s%02X ", extra, pEfuseHal->BTEfuseInitMap[i+j]);
10171 sprintf(extra, "%s\n", extra);
10175 else if (strcmp(tmp[0],"btrmap") == 0)
10177 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10183 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10186 addr = simple_strtoul(tmp[1], &ptmp, 16);
10187 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10189 cnts = simple_strtoul(tmp[2], &ptmp, 10);
10192 DBG_871X("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
10196 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10198 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10199 if ((addr + cnts) > max_available_len) {
10200 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10205 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL)
10207 DBG_871X("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
10213 // DBG_871X("%s: bt efuse data={", __FUNCTION__);
10214 for (i=0; i<cnts; i++)
10216 // DBG_871X("0x%02x ", data[i]);
10217 sprintf(extra, "%s 0x%02X ", extra, data[i]);
10219 // DBG_871X("}\n");
10220 DBG_871X(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
10222 else if (strcmp(tmp[0], "btffake") == 0)
10224 // DBG_871X("OFFSET\tVALUE(hex)\n");
10225 sprintf(extra, "\n");
10226 for (i=0; i<512; i+=16)
10228 // DBG_871X("0x%03x\t", i);
10229 sprintf(extra, "%s0x%03x\t", extra, i);
10230 for (j=0; j<8; j++) {
10231 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10232 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10235 sprintf(extra, "%s\t", extra);
10236 for (; j<16; j++) {
10237 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10238 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10241 sprintf(extra, "%s\n", extra);
10245 else if (strcmp(tmp[0],"btbfake") == 0)
10247 // DBG_871X("OFFSET\tVALUE(hex)\n");
10248 sprintf(extra, "\n");
10249 for (i=512; i<1024; i+=16)
10251 // DBG_871X("0x%03x\t", i);
10252 sprintf(extra, "%s0x%03x\t", extra, i);
10253 for (j=0; j<8; j++) {
10254 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10255 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10258 sprintf(extra, "%s\t", extra);
10259 for (; j<16; j++) {
10260 // DBG_871X("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10261 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10264 sprintf(extra, "%s\n", extra);
10268 else if (strcmp(tmp[0],"wlrfkmap")== 0)
10270 // DBG_871X("OFFSET\tVALUE(hex)\n");
10271 sprintf(extra, "\n");
10272 for (i=0; i<EFUSE_MAP_SIZE; i+=16)
10274 // DBG_871X("\t0x%02x\t", i);
10275 sprintf(extra, "%s0x%02x\t", extra, i);
10276 for (j=0; j<8; j++) {
10277 // DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
10278 sprintf(extra, "%s%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
10281 sprintf(extra, "%s\t", extra);
10282 for (; j<16; j++) {
10283 // DBG_871X("%02X ", pEfuseHal->fakeEfuseModifiedMap[i+j]);
10284 sprintf(extra, "%s %02X", extra, pEfuseHal->fakeEfuseModifiedMap[i+j]);
10287 sprintf(extra, "%s\n", extra);
10292 else if (strcmp(tmp[0],"wlrfkrmap")== 0)
10294 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10296 DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
10301 addr = simple_strtoul(tmp[1], &ptmp, 16);
10302 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
10304 cnts = simple_strtoul(tmp[2], &ptmp, 10);
10307 DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
10311 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10313 // DBG_871X("%s: data={", __FUNCTION__);
10315 for (i=0; i<cnts; i++) {
10316 DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
10317 sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeEfuseModifiedMap[addr+i]);
10320 else if (strcmp(tmp[0],"btrfkrmap")== 0)
10322 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10324 DBG_871X("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
10329 addr = simple_strtoul(tmp[1], &ptmp, 16);
10330 DBG_871X("%s: addr=%x\n", __FUNCTION__, addr);
10332 cnts = simple_strtoul(tmp[2], &ptmp, 10);
10335 DBG_871X("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
10339 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10341 // DBG_871X("%s: data={", __FUNCTION__);
10343 for (i=0; i<cnts; i++) {
10344 DBG_871X("wlrfkrmap = 0x%02x \n", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
10345 sprintf(extra, "%s0x%02X ", extra, pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
10350 sprintf(extra, "Command not found!");
10355 rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
10357 rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
10359 wrqu->length = strlen(extra);
10361 if (padapter->registrypriv.mp_mode == 0)
10364 rtw_pm_set_ips(padapter, ips_mode);
10365 #endif // CONFIG_IPS
10368 rtw_pm_set_lps(padapter, lps_mode);
10369 #endif // CONFIG_LPS
10373 padapter->registrypriv.fw_iol = org_fw_iol;// 0:Disable, 1:enable, 2:by usb speed
10378 static int rtw_mp_efuse_set(struct net_device *dev,
10379 struct iw_request_info *info,
10380 union iwreq_data *wdata, char *extra)
10382 struct iw_point *wrqu;
10384 struct pwrctrl_priv *pwrctrlpriv ;
10385 PHAL_DATA_TYPE pHalData;
10386 PEFUSE_HAL pEfuseHal;
10388 u8 ips_mode = IPS_NUM; // init invalid value
10389 u8 lps_mode = PS_MODE_NUM; // init invalid value
10390 u32 i=0,j=0, jj, kk;
10391 u8 *setdata = NULL;
10392 u8 *ShadowMapBT = NULL;
10393 u8 *ShadowMapWiFi = NULL;
10394 u8 *setrawdata = NULL;
10395 char *pch, *ptmp, *token, *tmp[3]={0x00,0x00,0x00};
10396 u16 addr = 0xFF, cnts = 0, BTStatus = 0 , max_available_len = 0;
10399 wrqu = (struct iw_point*)wdata;
10400 padapter = rtw_netdev_priv(dev);
10401 pwrctrlpriv = adapter_to_pwrctl(padapter);
10402 pHalData = GET_HAL_DATA(padapter);
10403 pEfuseHal = &pHalData->EfuseHal;
10406 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
10409 setdata = rtw_zmalloc(1024);
10410 if (setdata == NULL)
10415 ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
10416 if (ShadowMapBT == NULL)
10421 ShadowMapWiFi = rtw_malloc(EFUSE_MAP_SIZE);
10422 if (ShadowMapWiFi == NULL)
10427 setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
10428 if (setrawdata == NULL)
10435 lps_mode = pwrctrlpriv->power_mgnt;//keep org value
10436 rtw_pm_set_lps(padapter,PS_MODE_ACTIVE);
10440 ips_mode = pwrctrlpriv->ips_mode;//keep org value
10441 rtw_pm_set_ips(padapter,IPS_NONE);
10445 DBG_871X("%s: in=%s\n", __FUNCTION__, extra);
10448 while ((token = strsep(&pch, ",")) != NULL)
10456 // wmap,addr,00e04c871200
10457 if (strcmp(tmp[0], "wmap") == 0)
10459 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10466 // unknown bug workaround, need to fix later
10468 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10470 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10472 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10474 rtw_read8(padapter, EFUSE_CTRL);
10477 addr = simple_strtoul(tmp[1], &ptmp, 16);
10480 cnts = strlen(tmp[2]);
10493 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10494 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10495 DBG_871X("%s: map data=%s\n", __FUNCTION__, tmp[2]);
10497 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10499 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10502 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10504 if ((addr + cnts) > max_available_len) {
10505 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10510 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10512 DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10517 DBG_871X("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__);
10518 if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS)
10520 if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
10522 DBG_871X("%s: WiFi write map afterf compare success\n", __FUNCTION__);
10523 sprintf(extra, "WiFi write map compare OK\n");
10529 sprintf(extra, "WiFi write map compare FAIL\n");
10530 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
10536 else if (strcmp(tmp[0], "wraw") == 0)
10538 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10544 addr = simple_strtoul( tmp[1], &ptmp, 16 );
10547 cnts = strlen(tmp[2]);
10560 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10561 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10562 DBG_871X("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
10564 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10566 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10569 if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL)
10571 DBG_871X("%s: rtw_efuse_access error!!\n", __FUNCTION__);
10576 else if (strcmp(tmp[0], "mac") == 0)
10586 if (hal_efuse_macaddr_offset(padapter) == -1) {
10591 addr = hal_efuse_macaddr_offset(padapter);
10592 cnts = strlen(tmp[1]);
10606 DBG_871X("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
10611 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10612 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10613 DBG_871X("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
10615 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10617 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10620 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10622 if ((addr + cnts) > max_available_len) {
10623 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10628 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10630 DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10635 else if (strcmp(tmp[0], "vidpid") == 0)
10644 #ifdef CONFIG_RTL8188E
10645 #ifdef CONFIG_USB_HCI
10646 addr = EEPROM_VID_88EU;
10648 #ifdef CONFIG_PCI_HCI
10649 addr = EEPROM_VID_88EE;
10651 #endif // CONFIG_RTL8188E
10653 #ifdef CONFIG_RTL8192E
10654 #ifdef CONFIG_USB_HCI
10655 addr = EEPROM_VID_8192EU;
10657 #ifdef CONFIG_PCI_HCI
10658 addr = EEPROM_VID_8192EE;
10660 #endif // CONFIG_RTL8188E
10662 #ifdef CONFIG_RTL8723B
10663 addr = EEPROM_VID_8723BU;
10666 #ifdef CONFIG_RTL8188F
10667 addr = EEPROM_VID_8188FU;
10670 #ifdef CONFIG_RTL8703B
10671 #ifdef CONFIG_USB_HCI
10672 addr = EEPROM_VID_8703BU;
10673 #endif /* CONFIG_USB_HCI */
10674 #endif /* CONFIG_RTL8703B */
10676 cnts = strlen(tmp[1]);
10689 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10690 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10691 DBG_871X("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
10693 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10695 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk+1]);
10698 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10699 if ((addr + cnts) > max_available_len) {
10700 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10705 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10707 DBG_871X("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
10712 else if (strcmp(tmp[0], "wldumpfake") == 0)
10714 if (rtw_efuse_mask_map_read(padapter, 0, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) {
10715 DBG_871X("%s: WiFi hw efuse dump to Fake map success\n", __func__);
10717 DBG_871X("%s: WiFi hw efuse dump to Fake map Fail\n", __func__);
10721 else if (strcmp(tmp[0], "btwmap") == 0)
10723 rtw_write8(padapter, 0xa3, 0x05); //For 8723AB ,8821S ?
10724 BTStatus=rtw_read8(padapter, 0xa0);
10725 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10726 if (BTStatus != 0x04)
10728 sprintf(extra, "BT Status not Active Write FAIL\n");
10732 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10737 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10740 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10742 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10744 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10746 rtw_read8(padapter, EFUSE_CTRL);
10748 addr = simple_strtoul(tmp[1], &ptmp, 16);
10751 cnts = strlen(tmp[2]);
10764 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10765 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10766 DBG_871X("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
10768 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10770 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10772 #ifdef CONFIG_RTL8703B
10773 if (cnts == 1 && addr == 0x189) {
10774 setdata[1] = setdata[0];
10778 DBG_871X("addr 0x%x ,setdata=0x%X 0x%X\n", addr, setdata[0], setdata[1]);
10779 } else if (cnts == 1 && addr == 0x161) {
10780 setdata[1] = setdata[0];
10784 DBG_871X("addr 0x%x ,setdata=0x%X 0x%X\n", addr, setdata[0], setdata[1]);
10788 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (PVOID)&max_available_len, _FALSE);
10789 if ((addr + cnts) > max_available_len) {
10790 DBG_871X("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
10795 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL)
10797 DBG_871X("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
10802 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp \n", __FUNCTION__);
10803 if ( (rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT ) == _SUCCESS ) )
10805 if (_rtw_memcmp((void*)ShadowMapBT ,(void*)setdata,cnts))
10807 DBG_871X("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10808 sprintf(extra, "BT write map compare OK");
10814 sprintf(extra, "BT write map compare FAIL");
10815 DBG_871X("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10821 else if (strcmp(tmp[0], "btwfake") == 0)
10823 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10829 addr = simple_strtoul(tmp[1], &ptmp, 16);
10832 cnts = strlen(tmp[2]);
10845 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
10846 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
10847 DBG_871X("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
10849 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
10851 pEfuseHal->fakeBTEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
10854 else if (strcmp(tmp[0], "btdumpfake") == 0)
10856 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) {
10857 DBG_871X("%s: BT read all map success\n", __FUNCTION__);
10859 DBG_871X("%s: BT read all map Fail!\n", __FUNCTION__);
10863 else if (strcmp(tmp[0], "btfk2map") == 0)
10865 rtw_write8(padapter, 0xa3, 0x05);
10866 BTStatus=rtw_read8(padapter, 0xa0);
10867 DBG_871X("%s: btwmap before read 0xa0 BT Status =0x%x \n", __FUNCTION__,BTStatus);
10868 if (BTStatus != 0x04)
10870 sprintf(extra, "BT Status not Active Write FAIL\n");
10874 BTEfuse_PowerSwitch(padapter,1,_TRUE);
10877 rtw_write8(padapter, EFUSE_CTRL+1, (addr & 0xff));
10879 rtw_write8(padapter, EFUSE_CTRL+2, ((addr >> 8) & 0x03));
10881 rtw_write8(padapter, EFUSE_CTRL+3, 0x72);
10883 rtw_read8(padapter, EFUSE_CTRL);
10885 _rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
10887 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10889 DBG_871X("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
10894 DBG_871X("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
10895 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10897 printk("0x%02x\t", i);
10898 for (j=0; j<8; j++) {
10899 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10903 for (; j<16; j++) {
10904 printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
10911 DBG_871X("%s: rtw_BT_efuse_map_read _rtw_memcmp \n", __FUNCTION__);
10912 if ( (rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS ) )
10914 if (_rtw_memcmp((void*)pEfuseHal->fakeBTEfuseModifiedMap,(void*)pEfuseHal->fakeBTEfuseInitMap,EFUSE_BT_MAX_MAP_LEN))
10916 sprintf(extra, "BT write map compare OK");
10917 DBG_871X("%s: BT write map afterf compare success BTStatus=0x%x \n", __FUNCTION__,BTStatus);
10923 sprintf(extra, "BT write map compare FAIL");
10924 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
10926 DBG_871X("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__,i);
10929 if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)
10931 DBG_871X("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
10933 for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16)
10935 printk("0x%02x\t", i);
10936 for (j=0; j<8; j++) {
10937 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10940 for (; j<16; j++) {
10941 printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i+j]);
10947 DBG_871X("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__,BTStatus);
10954 else if (strcmp(tmp[0], "wlfk2map") == 0)
10956 if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAP_SIZE, pEfuseHal->fakeEfuseModifiedMap) == _FAIL)
10958 DBG_871X("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
10963 DBG_871X("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __func__);
10964 if (rtw_efuse_mask_map_read(padapter, 0x00, EFUSE_MAP_SIZE, ShadowMapWiFi) == _SUCCESS)
10966 if (_rtw_memcmp((void*)ShadowMapWiFi ,(void*)setdata,cnts))
10968 DBG_871X("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
10969 sprintf(extra, "WiFi write map compare OK\n");
10975 sprintf(extra, "WiFi write map compare FAIL\n");
10976 DBG_871X("%s: WiFi write map compare Fail\n", __FUNCTION__);
10982 else if (strcmp(tmp[0], "wlwfake") == 0)
10984 if ((tmp[1]==NULL) || (tmp[2]==NULL))
10990 addr = simple_strtoul(tmp[1], &ptmp, 16);
10993 cnts = strlen(tmp[2]);
11006 DBG_871X("%s: addr=0x%X\n", __FUNCTION__, addr);
11007 DBG_871X("%s: cnts=%d\n", __FUNCTION__, cnts);
11008 DBG_871X("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
11010 for (jj=0, kk=0; jj<cnts; jj++, kk+=2)
11012 pEfuseHal->fakeEfuseModifiedMap[addr+jj] = key_2char2num(tmp[2][kk], tmp[2][kk+1]);
11014 _rtw_memset(extra, '\0', strlen(extra));
11015 sprintf(extra, "wlwfake OK\n");
11020 rtw_mfree(setdata, 1024);
11022 rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
11024 rtw_mfree(ShadowMapWiFi, EFUSE_MAP_SIZE);
11026 rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
11028 wrqu->length = strlen(extra);
11030 if (padapter->registrypriv.mp_mode == 0)
11033 rtw_pm_set_ips(padapter, ips_mode);
11034 #endif // CONFIG_IPS
11037 rtw_pm_set_lps(padapter, lps_mode);
11038 #endif // CONFIG_LPS
11045 #ifdef CONFIG_MP_INCLUDED
11047 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
11048 #define DBG_MP_SDIO_INDIRECT_ACCESS 1
11049 static int rtw_mp_sd_iread(struct net_device *dev
11050 , struct iw_request_info *info
11051 , struct iw_point *wrqu
11056 unsigned long addr;
11058 PADAPTER padapter = rtw_netdev_priv(dev);
11060 if (wrqu->length > 16) {
11061 DBG_871X(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
11066 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
11067 DBG_871X(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
11072 _rtw_memset(extra, 0, wrqu->length);
11074 if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) {
11075 DBG_871X(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
11080 if (addr > 0x3FFF) {
11081 DBG_871X(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
11086 if (DBG_MP_SDIO_INDIRECT_ACCESS)
11087 DBG_871X(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr);
11091 sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr));
11092 wrqu->length = strlen(extra);
11095 sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr));
11096 wrqu->length = strlen(extra);
11099 sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr));
11100 wrqu->length = strlen(extra);
11112 static int rtw_mp_sd_iwrite(struct net_device *dev
11113 , struct iw_request_info *info
11114 , struct iw_point *wrqu
11118 unsigned long addr, data;
11120 PADAPTER padapter = rtw_netdev_priv(dev);
11123 if (wrqu->length > 32) {
11124 DBG_871X(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
11129 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
11130 DBG_871X(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
11135 _rtw_memset(extra, 0, wrqu->length);
11137 if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) {
11138 DBG_871X(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
11143 if (addr > 0x3FFF) {
11144 DBG_871X(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
11149 if (DBG_MP_SDIO_INDIRECT_ACCESS)
11150 DBG_871X(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data);
11158 rtw_sd_iwrite8(padapter, addr, data);
11161 if (data > 0xFFFF) {
11165 rtw_sd_iwrite16(padapter, addr, data);
11168 rtw_sd_iwrite32(padapter, addr, data);
11179 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
11181 static int rtw_mp_set(struct net_device *dev,
11182 struct iw_request_info *info,
11183 union iwreq_data *wdata, char *extra)
11185 struct iw_point *wrqu = (struct iw_point *)wdata;
11186 u32 subcmd = wrqu->flags;
11187 PADAPTER padapter = rtw_netdev_priv(dev);
11189 if (padapter == NULL)
11194 if((padapter->bup == _FALSE ))
11196 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
11200 if (RTW_CANNOT_RUN(padapter)) {
11201 DBG_871X("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__);
11206 //_rtw_memset(extra, 0x00, IW_PRIV_SIZE_MASK);
11217 DBG_871X("set case mp_start \n");
11218 rtw_mp_start (dev,info,wrqu,extra);
11222 DBG_871X("set case mp_stop \n");
11223 rtw_mp_stop (dev,info,wrqu,extra);
11227 DBG_871X("set case mp_bandwidth \n");
11228 rtw_mp_bandwidth (dev,info,wrqu,extra);
11231 case MP_RESET_STATS:
11232 DBG_871X("set case MP_RESET_STATS \n");
11233 rtw_mp_reset_stats (dev,info,wrqu,extra);
11235 case MP_SetRFPathSwh:
11236 DBG_871X("set MP_SetRFPathSwitch \n");
11237 rtw_mp_SetRFPath (dev,info,wdata,extra);
11240 DBG_871X("set CTA_TEST\n");
11241 rtw_cta_test_start (dev, info, wdata, extra);
11243 case MP_DISABLE_BT_COEXIST:
11244 DBG_871X("set case MP_DISABLE_BT_COEXIST \n");
11245 rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
11247 #ifdef CONFIG_WOWLAN
11248 case MP_WOW_ENABLE:
11249 DBG_871X("set case MP_WOW_ENABLE: %s\n", extra);
11251 rtw_wowlan_ctrl(dev, info, wdata, extra);
11253 case MP_WOW_SET_PATTERN:
11254 DBG_871X("set case MP_WOW_SET_PATTERN: %s\n", extra);
11255 rtw_wowlan_set_pattern(dev, info, wdata, extra);
11258 #ifdef CONFIG_AP_WOWLAN
11259 case MP_AP_WOW_ENABLE:
11260 DBG_871X("set case MP_AP_WOW_ENABLE: %s\n", extra);
11261 rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
11271 static int rtw_mp_get(struct net_device *dev,
11272 struct iw_request_info *info,
11273 union iwreq_data *wdata, char *extra)
11275 struct iw_point *wrqu = (struct iw_point *)wdata;
11276 u32 subcmd = wrqu->flags;
11277 PADAPTER padapter = rtw_netdev_priv(dev);
11279 //DBG_871X("in mp_get extra= %s \n",extra);
11281 if (padapter == NULL)
11285 if((padapter->bup == _FALSE ))
11287 DBG_871X(" %s fail =>(padapter->bup == _FALSE )\n",__FUNCTION__);
11291 if (RTW_CANNOT_RUN(padapter)) {
11292 DBG_871X("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__);
11296 if (extra == NULL) {
11303 rtw_mp_write_reg(dev, info, wrqu, extra);
11307 rtw_mp_write_rf(dev, info, wrqu, extra);
11311 DBG_871X("mp_get MP_PHYPARA\n");
11312 rtw_mp_phypara(dev, info, wrqu, extra);
11316 DBG_871X("set case mp_channel\n");
11317 rtw_mp_channel(dev , info, wrqu, extra);
11321 DBG_871X("mp_get READ_REG\n");
11322 rtw_mp_read_reg(dev, info, wrqu, extra);
11325 DBG_871X("mp_get READ_RF\n");
11326 rtw_mp_read_rf(dev, info, wrqu, extra);
11330 DBG_871X("set case mp_rate\n");
11331 rtw_mp_rate(dev, info, wrqu, extra);
11335 DBG_871X("set case MP_TXPOWER\n");
11336 rtw_mp_txpower(dev, info, wrqu, extra);
11340 DBG_871X("set case MP_ANT_TX\n");
11341 rtw_mp_ant_tx(dev, info, wrqu, extra);
11345 DBG_871X("set case MP_ANT_RX\n");
11346 rtw_mp_ant_rx(dev, info, wrqu, extra);
11350 rtw_mp_trx_query(dev, info, wrqu, extra);
11354 DBG_871X("set case MP_CTX\n");
11355 rtw_mp_ctx(dev, info, wrqu, extra);
11359 DBG_871X("set case MP_ARX\n");
11360 rtw_mp_arx(dev, info, wrqu, extra);
11364 DBG_871X("efuse get EFUSE_GET\n");
11365 rtw_mp_efuse_get(dev, info, wdata, extra);
11369 DBG_871X("set case MP_DUMP\n");
11370 rtw_mp_dump(dev, info, wrqu, extra);
11373 DBG_871X("set case MP_PSD\n");
11374 rtw_mp_psd(dev, info, wrqu, extra);
11377 DBG_871X("set case MP_THER\n");
11378 rtw_mp_thermal(dev, info, wrqu, extra);
11381 DBG_871X("set MP_PwrCtlDM\n");
11382 rtw_mp_PwrCtlDM(dev, info, wrqu, extra);
11384 case MP_QueryDrvStats:
11385 DBG_871X("mp_get MP_QueryDrvStats\n");
11386 rtw_mp_QueryDrv(dev, info, wdata, extra);
11389 DBG_871X("set case MP_PWRTRK\n");
11390 rtw_mp_pwrtrk(dev, info, wrqu, extra);
11393 DBG_871X("set case efuse set\n");
11394 rtw_mp_efuse_set(dev, info, wdata, extra);
11396 case MP_GET_TXPOWER_INX:
11397 DBG_871X("mp_get MP_GET_TXPOWER_INX\n");
11398 rtw_mp_txpower_index(dev, info, wrqu, extra);
11401 DBG_871X("mp_get MP_GETVER\n");
11402 rtw_mp_getver(dev, info, wdata, extra);
11405 DBG_871X("mp_get MP_MON\n");
11406 rtw_mp_mon(dev, info, wdata, extra);
11409 DBG_871X("mp_get EFUSE_MASK\n");
11410 rtw_efuse_mask_file(dev, info, wdata, extra);
11413 DBG_871X("mp_get EFUSE_FILE\n");
11414 rtw_efuse_file_map(dev, info, wdata, extra);
11417 DBG_871X("mp_get MP_TX\n");
11418 rtw_mp_tx(dev, info, wdata, extra);
11421 DBG_871X("mp_get MP_RX\n");
11422 rtw_mp_rx(dev, info, wdata, extra);
11424 case MP_HW_TX_MODE:
11425 DBG_871X("mp_get MP_HW_TX_MODE\n");
11426 rtw_mp_hwtx(dev, info, wdata, extra);
11428 #if defined(CONFIG_RTL8723B)
11430 DBG_871X("set MP_SetBT\n");
11431 rtw_mp_SetBT(dev, info, wdata, extra);
11434 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
11436 rtw_mp_sd_iread(dev, info, wrqu, extra);
11439 rtw_mp_sd_iwrite(dev, info, wrqu, extra);
11444 rtw_msleep_os(10); //delay 5ms for sending pkt before exit adb shell operation
11448 #endif /*#if defined(CONFIG_MP_INCLUDED)*/
11450 static int rtw_wx_tdls_wfd_enable(struct net_device *dev,
11451 struct iw_request_info *info,
11452 union iwreq_data *wrqu, char *extra)
11459 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11461 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11463 if ( extra[ 0 ] == '0' )
11464 rtw_tdls_wfd_enable(padapter, 0);
11466 rtw_tdls_wfd_enable(padapter, 1);
11468 #endif /* CONFIG_WFD */
11469 #endif /* CONFIG_TDLS */
11474 static int rtw_tdls_weaksec(struct net_device *dev,
11475 struct iw_request_info *info,
11476 union iwreq_data *wrqu, char *extra)
11483 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11485 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11487 if ( extra[ 0 ] == '0' )
11488 padapter->wdinfo.wfd_tdls_weaksec = 0;
11490 padapter->wdinfo.wfd_tdls_weaksec = 1;
11492 #endif /* CONFIG_TDLS */
11498 static int rtw_tdls_enable(struct net_device *dev,
11499 struct iw_request_info *info,
11500 union iwreq_data *wrqu, char *extra)
11506 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11507 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11509 _list *plist, *phead;
11511 struct sta_info *psta = NULL;
11512 struct sta_priv *pstapriv = &padapter->stapriv;
11513 u8 tdls_sta[NUM_STA][ETH_ALEN];
11514 u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
11515 struct tdls_txmgmt txmgmt;
11517 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11519 _rtw_memset(tdls_sta, 0x00, sizeof(tdls_sta));
11520 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
11522 if (extra[ 0 ] == '0') {
11523 ptdlsinfo->tdls_enable = 0;
11525 if(pstapriv->asoc_sta_count==1)
11528 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
11529 for (index=0; index< NUM_STA; index++) {
11530 phead = &(pstapriv->sta_hash[index]);
11531 plist = get_next(phead);
11533 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
11534 psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list);
11536 plist = get_next(plist);
11538 if (psta->tdls_sta_state != TDLS_STATE_NONE) {
11539 _rtw_memcpy(tdls_sta[index], psta->hwaddr, ETH_ALEN);
11543 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
11545 for (index=0; index< NUM_STA; index++) {
11546 if (!_rtw_memcmp(tdls_sta[index], empty_hwaddr, ETH_ALEN)) {
11547 DBG_871X("issue tear down to "MAC_FMT"\n", MAC_ARG(tdls_sta[index]));
11548 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
11549 _rtw_memcpy(txmgmt.peer, tdls_sta[index], ETH_ALEN);
11550 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
11553 rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR);
11554 rtw_reset_tdls_info(padapter);
11555 } else if (extra[0] == '1') {
11556 ptdlsinfo->tdls_enable = 1;
11558 #endif /* CONFIG_TDLS */
11563 static int rtw_tdls_setup(struct net_device *dev,
11564 struct iw_request_info *info,
11565 union iwreq_data *wrqu, char *extra)
11570 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11571 struct tdls_txmgmt txmgmt;
11573 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
11574 #endif /* CONFIG_WFD */
11576 DBG_871X("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1);
11578 if (wrqu->data.length - 1 != 17) {
11579 DBG_871X("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length -1));
11583 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
11584 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
11585 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
11589 if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
11590 /* Weak Security situation with AP. */
11591 if (0 == pwdinfo->wfd_tdls_weaksec) {
11592 /* Can't send the tdls setup request out!! */
11593 DBG_871X("[%s] Current link is not AES, "
11594 "SKIP sending the tdls setup request!!\n", __FUNCTION__);
11596 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
11599 #endif /* CONFIG_WFD */
11601 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
11603 #endif /* CONFIG_TDLS */
11608 static int rtw_tdls_teardown(struct net_device *dev,
11609 struct iw_request_info *info,
11610 union iwreq_data *wrqu, char *extra)
11617 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11618 struct sta_info *ptdls_sta = NULL;
11619 struct tdls_txmgmt txmgmt;
11621 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11623 if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) {
11624 DBG_871X("[%s] length:%d != 17 or 19\n",
11625 __FUNCTION__, (wrqu->data.length -1));
11629 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
11630 for (i=0, j=0; i < ETH_ALEN; i++, j+=3)
11631 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
11633 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
11635 if (ptdls_sta != NULL) {
11636 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
11637 if (wrqu->data.length - 1 == 19)
11638 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
11640 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
11642 DBG_871X( "TDLS peer not found\n");
11644 #endif /* CONFIG_TDLS */
11649 static int rtw_tdls_discovery(struct net_device *dev,
11650 struct iw_request_info *info,
11651 union iwreq_data *wrqu, char *extra)
11657 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11658 struct tdls_txmgmt txmgmt;
11661 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11663 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
11664 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
11665 txmgmt.peer[i]=key_2char2num(*(extra+j), *(extra+j+1));
11668 issue_tdls_dis_req(padapter, &txmgmt);
11670 #endif /* CONFIG_TDLS */
11675 static int rtw_tdls_ch_switch(struct net_device *dev,
11676 struct iw_request_info *info,
11677 union iwreq_data *wrqu, char *extra)
11682 #ifdef CONFIG_TDLS_CH_SW
11683 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11684 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
11686 struct sta_info *ptdls_sta = NULL;
11689 DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11691 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE)
11693 DBG_871X("TDLS channel switch is not allowed\n");
11697 for( i=0, j=0 ; i < ETH_ALEN; i++, j+=3 ){
11698 pchsw_info->addr[i] = key_2char2num(*(extra+j), *(extra+j+1));
11701 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr);
11702 if( ptdls_sta == NULL )
11705 pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE;
11707 if (ptdls_sta != NULL) {
11708 if (pchsw_info->off_ch_num == 0)
11709 pchsw_info->off_ch_num = 11;
11711 DBG_871X( "TDLS peer not found\n");
11714 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
11716 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
11717 if (take_care_iqk == _TRUE) {
11721 bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
11722 central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
11723 if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) >= 0)
11724 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
11726 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_PREPARE);
11728 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
11730 //issue_tdls_ch_switch_req(padapter, ptdls_sta);
11731 /* DBG_871X("issue tdls ch switch req\n"); */
11733 #endif /* CONFIG_TDLS_CH_SW */
11734 #endif /* CONFIG_TDLS */
11739 static int rtw_tdls_ch_switch_off(struct net_device *dev,
11740 struct iw_request_info *info,
11741 union iwreq_data *wrqu, char *extra)
11746 #ifdef CONFIG_TDLS_CH_SW
11748 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11749 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
11750 u8 i, j, mac_addr[ETH_ALEN];
11751 struct sta_info *ptdls_sta = NULL;
11752 struct tdls_txmgmt txmgmt;
11754 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
11756 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11758 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE)
11760 DBG_871X("TDLS channel switch is not allowed\n");
11764 if (wrqu->data.length >= 17) {
11765 for (i=0, j=0 ; i < ETH_ALEN; i++, j+=3)
11766 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
11767 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11770 if (ptdls_sta == NULL)
11773 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
11775 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
11776 TDLS_CH_SWITCH_ON_STATE |
11777 TDLS_PEER_AT_OFF_STATE);
11778 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
11780 ptdls_sta->ch_switch_time = 0;
11781 ptdls_sta->ch_switch_timeout = 0;
11782 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
11783 _cancel_timer_ex(&ptdls_sta->delay_timer);
11784 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
11785 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
11787 rtw_pm_set_lps(padapter, PS_MODE_MAX);
11788 #endif /* CONFIG_TDLS_CH_SW */
11789 #endif /* CONFIG_TDLS */
11794 static int rtw_tdls_dump_ch(struct net_device *dev,
11795 struct iw_request_info *info,
11796 union iwreq_data *wrqu, char *extra)
11801 #ifdef CONFIG_TDLS_CH_SW
11802 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11803 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11805 DBG_8192C("[%s] dump_stack:%s\n", __FUNCTION__, extra);
11807 extra[ wrqu->data.length ] = 0x00;
11808 ptdlsinfo->chsw_info.dump_stack = rtw_atoi( extra );
11813 #endif /* CONFIG_TDLS */
11818 static int rtw_tdls_off_ch_num(struct net_device *dev,
11819 struct iw_request_info *info,
11820 union iwreq_data *wrqu, char *extra)
11825 #ifdef CONFIG_TDLS_CH_SW
11826 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11827 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11829 DBG_8192C("[%s] off_ch_num:%s\n", __FUNCTION__, extra);
11831 extra[ wrqu->data.length ] = 0x00;
11832 ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra);
11837 #endif /* CONFIG_TDLS */
11842 static int rtw_tdls_ch_offset(struct net_device *dev,
11843 struct iw_request_info *info,
11844 union iwreq_data *wrqu, char *extra)
11849 #ifdef CONFIG_TDLS_CH_SW
11850 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11851 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11853 DBG_8192C("[%s] ch_offset:%s\n", __FUNCTION__, extra);
11855 extra[ wrqu->data.length ] = 0x00;
11856 switch (rtw_atoi(extra)) {
11858 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11862 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11866 ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11873 #endif /* CONFIG_TDLS */
11878 static int rtw_tdls_pson(struct net_device *dev,
11879 struct iw_request_info *info,
11880 union iwreq_data *wrqu, char *extra)
11886 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11887 u8 i, j, mac_addr[ETH_ALEN];
11888 struct sta_info *ptdls_sta = NULL;
11890 DBG_871X( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11892 for (i=0, j=0; i < ETH_ALEN; i++, j+=3)
11893 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
11895 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11897 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 1, 3, 500);
11899 #endif /* CONFIG_TDLS */
11904 static int rtw_tdls_psoff(struct net_device *dev,
11905 struct iw_request_info *info,
11906 union iwreq_data *wrqu, char *extra)
11912 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11913 u8 i, j, mac_addr[ETH_ALEN];
11914 struct sta_info *ptdls_sta = NULL;
11916 DBG_8192C( "[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length -1 );
11918 for (i=0, j=0; i < ETH_ALEN; i++, j+=3)
11919 mac_addr[i]=key_2char2num(*(extra+j), *(extra+j+1));
11921 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
11924 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 3, 500);
11926 #endif /* CONFIG_TDLS */
11931 static int rtw_tdls_setip(struct net_device *dev,
11932 struct iw_request_info *info,
11933 union iwreq_data *wrqu, char *extra)
11940 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11941 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11942 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11943 u8 i=0, j=0, k=0, tag=0;
11945 DBG_871X("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
11948 for (j=0; j < 4; j++) {
11949 if (*( extra + j + tag ) == '.' || *( extra + j + tag ) == '\0') {
11951 pwfd_info->ip_address[i]=convert_ip_addr( '0', '0', *(extra+(j-1)+tag));
11953 pwfd_info->ip_address[i]=convert_ip_addr( '0', *(extra+(j-2)+tag), *(extra+(j-1)+tag));
11955 pwfd_info->ip_address[i]=convert_ip_addr( *(extra+(j-3)+tag), *(extra+(j-2)+tag), *(extra+(j-1)+tag));
11964 DBG_871X( "[%s] Set IP = %u.%u.%u.%u \n", __FUNCTION__,
11965 ptdlsinfo->wfd_info->ip_address[0],
11966 ptdlsinfo->wfd_info->ip_address[1],
11967 ptdlsinfo->wfd_info->ip_address[2],
11968 ptdlsinfo->wfd_info->ip_address[3]);
11970 #endif /* CONFIG_WFD */
11971 #endif /* CONFIG_TDLS */
11976 static int rtw_tdls_getip(struct net_device *dev,
11977 struct iw_request_info *info,
11978 union iwreq_data *wrqu, char *extra)
11985 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11986 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11987 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
11989 DBG_871X( "[%s]\n", __FUNCTION__);
11991 sprintf( extra, "\n\n%u.%u.%u.%u\n",
11992 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11993 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11995 DBG_871X( "[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
11996 pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
11997 pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
11999 wrqu->data.length = strlen( extra );
12001 #endif /* CONFIG_WFD */
12002 #endif /* CONFIG_TDLS */
12007 static int rtw_tdls_getport(struct net_device *dev,
12008 struct iw_request_info *info,
12009 union iwreq_data *wrqu, char *extra)
12017 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12018 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12019 struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
12021 DBG_871X( "[%s]\n", __FUNCTION__);
12023 sprintf( extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport );
12024 DBG_871X( "[%s] remote port = %d\n",
12025 __FUNCTION__, pwfd_info->peer_rtsp_ctrlport );
12027 wrqu->data.length = strlen( extra );
12029 #endif /* CONFIG_WFD */
12030 #endif /* CONFIG_TDLS */
12036 /* WFDTDLS, for sigma test */
12037 static int rtw_tdls_dis_result(struct net_device *dev,
12038 struct iw_request_info *info,
12039 union iwreq_data *wrqu, char *extra)
12047 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12048 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12050 DBG_871X( "[%s]\n", __FUNCTION__);
12052 if (ptdlsinfo->dev_discovered == _TRUE) {
12053 sprintf( extra, "\n\nDis=1\n" );
12054 ptdlsinfo->dev_discovered = _FALSE;
12057 wrqu->data.length = strlen( extra );
12059 #endif /* CONFIG_WFD */
12060 #endif /* CONFIG_TDLS */
12066 /* WFDTDLS, for sigma test */
12067 static int rtw_wfd_tdls_status(struct net_device *dev,
12068 struct iw_request_info *info,
12069 union iwreq_data *wrqu, char *extra)
12076 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12077 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12079 DBG_871X("[%s]\n", __FUNCTION__);
12081 sprintf( extra, "\nlink_established:%d \n"
12083 "sta_maximum:%d \n"
12084 "cur_channel:%d \n"
12086 #ifdef CONFIG_TDLS_CH_SW
12087 "ch_sw_state:%08x\n"
12092 "delay_swtich_back:%d"
12095 ptdlsinfo->link_established, ptdlsinfo->sta_cnt,
12096 ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel,
12097 ptdlsinfo->tdls_enable
12098 #ifdef CONFIG_TDLS_CH_SW
12100 ptdlsinfo->chsw_info.ch_sw_state,
12101 ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on),
12102 ptdlsinfo->chsw_info.off_ch_num,
12103 ptdlsinfo->chsw_info.cur_time,
12104 ptdlsinfo->chsw_info.ch_offset,
12105 ptdlsinfo->chsw_info.delay_switch_back
12109 wrqu->data.length = strlen( extra );
12111 #endif /* CONFIG_TDLS */
12117 static int rtw_tdls_getsta(struct net_device *dev,
12118 struct iw_request_info *info,
12119 union iwreq_data *wrqu, char *extra)
12125 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12126 u8 addr[ETH_ALEN] = {0};
12128 struct sta_info *ptdls_sta = NULL;
12130 DBG_871X("[%s] %s %d\n", __FUNCTION__,
12131 (char *)wrqu->data.pointer, wrqu->data.length -1);
12133 if(copy_from_user(charmac, wrqu->data.pointer+9, 17)){
12138 DBG_871X("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
12139 for (i=0, j=0 ; i < ETH_ALEN; i++, j+=3)
12140 addr[i]=key_2char2num(*(charmac+j), *(charmac+j+1));
12142 DBG_871X("[%s] %d, charmac:%s, addr:"MAC_FMT"\n",
12143 __FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
12144 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);
12146 sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state);
12147 DBG_871X("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
12149 sprintf(extra, "\n\nNot found this sta\n");
12150 DBG_871X("\n\nNot found this sta\n");
12152 wrqu->data.length = strlen( extra );
12154 #endif /* CONFIG_TDLS */
12160 static int rtw_tdls_get_best_ch(struct net_device *dev,
12161 struct iw_request_info *info,
12162 union iwreq_data *wrqu, char *extra)
12164 #ifdef CONFIG_FIND_BEST_CHANNEL
12165 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12166 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12167 u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
12169 for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
12170 if (pmlmeext->channel_set[i].ChannelNum == 1)
12172 if (pmlmeext->channel_set[i].ChannelNum == 36)
12176 for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
12178 if (pmlmeext->channel_set[i].ChannelNum == 6 || pmlmeext->channel_set[i].ChannelNum == 11) {
12179 if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) {
12181 best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
12186 if (pmlmeext->channel_set[i].ChannelNum >= 36
12187 && pmlmeext->channel_set[i].ChannelNum < 140) {
12188 /* Find primary channel */
12189 if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0)
12190 && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
12192 best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
12196 if (pmlmeext->channel_set[i].ChannelNum >= 149
12197 && pmlmeext->channel_set[i].ChannelNum < 165) {
12198 /* Find primary channel */
12199 if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0)
12200 && (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
12202 best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
12206 DBG_871X("The rx cnt of channel %3d = %d\n",
12207 pmlmeext->channel_set[i].ChannelNum,
12208 pmlmeext->channel_set[i].rx_count);
12212 sprintf( extra, "\nbest_channel_24G = %d\n", best_channel_24G );
12213 DBG_871X("best_channel_24G = %d\n", best_channel_24G);
12215 if (index_5G != 0) {
12216 sprintf(extra, "best_channel_5G = %d\n", best_channel_5G);
12217 DBG_871X("best_channel_5G = %d\n", best_channel_5G);
12220 wrqu->data.length = strlen( extra );
12228 static int rtw_tdls(struct net_device *dev,
12229 struct iw_request_info *info,
12230 union iwreq_data *wrqu, char *extra)
12236 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12238 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, extra );
12240 if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
12241 DBG_871X("Discard tdls oper since hal doesn't support tdls\n");
12245 if (padapter->tdlsinfo.tdls_enable == 0) {
12246 DBG_871X("tdls haven't enabled\n");
12250 /* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */
12252 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
12253 if (_rtw_memcmp(extra, "wfdenable=", 10)) {
12254 wrqu->data.length -= 10;
12255 rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]);
12260 if (_rtw_memcmp(extra, "weaksec=", 8)) {
12261 wrqu->data.length -=8;
12262 rtw_tdls_weaksec( dev, info, wrqu, &extra[8] );
12264 } else if (_rtw_memcmp( extra, "tdlsenable=", 11)) {
12265 wrqu->data.length -=11;
12266 rtw_tdls_enable( dev, info, wrqu, &extra[11] );
12270 if (_rtw_memcmp(extra, "setup=", 6)) {
12271 wrqu->data.length -=6;
12272 rtw_tdls_setup( dev, info, wrqu, &extra[6] );
12273 } else if (_rtw_memcmp(extra, "tear=", 5)) {
12274 wrqu->data.length -= 5;
12275 rtw_tdls_teardown( dev, info, wrqu, &extra[5] );
12276 } else if (_rtw_memcmp(extra, "dis=", 4)) {
12277 wrqu->data.length -= 4;
12278 rtw_tdls_discovery( dev, info, wrqu, &extra[4] );
12279 } else if (_rtw_memcmp(extra, "swoff=", 6)) {
12280 wrqu->data.length -= 6;
12281 rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]);
12282 } else if (_rtw_memcmp(extra, "sw=", 3)) {
12283 wrqu->data.length -= 3;
12284 rtw_tdls_ch_switch( dev, info, wrqu, &extra[3] );
12285 } else if (_rtw_memcmp(extra, "dumpstack=", 10)) {
12286 wrqu->data.length -= 10;
12287 rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]);
12288 } else if (_rtw_memcmp(extra, "offchnum=", 9)) {
12289 wrqu->data.length -= 9;
12290 rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]);
12291 } else if (_rtw_memcmp(extra, "choffset=", 9)) {
12292 wrqu->data.length -= 9;
12293 rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]);
12294 } else if (_rtw_memcmp(extra, "pson=", 5)) {
12295 wrqu->data.length -= 5;
12296 rtw_tdls_pson( dev, info, wrqu, &extra[5] );
12297 } else if (_rtw_memcmp(extra, "psoff=", 6)) {
12298 wrqu->data.length -= 6;
12299 rtw_tdls_psoff( dev, info, wrqu, &extra[6] );
12303 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
12304 if (_rtw_memcmp(extra, "setip=", 6)) {
12305 wrqu->data.length -= 6;
12306 rtw_tdls_setip(dev, info, wrqu, &extra[6]);
12307 } else if (_rtw_memcmp(extra, "tprobe=", 6)) {
12308 issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
12311 #endif /* CONFIG_WFD */
12313 #endif /* CONFIG_TDLS */
12319 static int rtw_tdls_get(struct net_device *dev,
12320 struct iw_request_info *info,
12321 union iwreq_data *wrqu, char *extra)
12327 DBG_871X( "[%s] extra = %s\n", __FUNCTION__, (char*) wrqu->data.pointer );
12329 if ( _rtw_memcmp( wrqu->data.pointer, "ip", 2 ) )
12330 rtw_tdls_getip( dev, info, wrqu, extra );
12331 else if (_rtw_memcmp(wrqu->data.pointer, "port", 4))
12332 rtw_tdls_getport( dev, info, wrqu, extra );
12333 /* WFDTDLS, for sigma test */
12334 else if ( _rtw_memcmp(wrqu->data.pointer, "dis", 3))
12335 rtw_tdls_dis_result( dev, info, wrqu, extra );
12336 else if ( _rtw_memcmp(wrqu->data.pointer, "status", 6))
12337 rtw_wfd_tdls_status( dev, info, wrqu, extra );
12338 else if ( _rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9))
12339 rtw_tdls_getsta( dev, info, wrqu, extra );
12340 else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7))
12341 rtw_tdls_get_best_ch(dev, info, wrqu, extra);
12342 #endif /* CONFIG_TDLS */
12351 #ifdef CONFIG_INTEL_WIDI
12352 static int rtw_widi_set(struct net_device *dev,
12353 struct iw_request_info *info,
12354 union iwreq_data *wrqu, char *extra)
12357 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12359 process_intel_widi_cmd(padapter, extra);
12364 static int rtw_widi_set_probe_request(struct net_device *dev,
12365 struct iw_request_info *info,
12366 union iwreq_data *wrqu, char *extra)
12370 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12372 pbuf = rtw_malloc(sizeof(l2_msg_t));
12375 if ( copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length) )
12377 //_rtw_memcpy(pbuf, wrqu->data.pointer, wrqu->data.length);
12379 if( wrqu->data.flags == 0 )
12380 intel_widi_wk_cmd(padapter, INTEL_WIDI_ISSUE_PROB_WK, pbuf, sizeof(l2_msg_t));
12381 else if( wrqu->data.flags == 1 )
12382 rtw_set_wfd_rds_sink_info( padapter, (l2_msg_t *)pbuf );
12386 #endif // CONFIG_INTEL_WIDI
12388 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
12390 #if defined(CONFIG_RTL8188E)
12391 #include <rtl8188e_hal.h>
12392 extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
12393 #define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum
12394 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
12395 extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
12396 #define fill_default_txdesc rtl8188es_fill_default_txdesc
12397 #endif // CONFIG_SDIO_HCI
12398 #endif // CONFIG_RTL8188E
12399 #if defined(CONFIG_RTL8723B)
12400 extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
12401 #define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum
12402 extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
12403 #define fill_default_txdesc rtl8723b_fill_default_txdesc
12404 #endif // CONFIG_RTL8723B
12406 #if defined(CONFIG_RTL8703B)
12407 /* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
12408 #define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum
12409 /* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
12410 #define fill_default_txdesc rtl8703b_fill_default_txdesc
12411 #endif /* CONFIG_RTL8703B */
12413 #if defined(CONFIG_RTL8192E)
12414 extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
12415 #define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum
12416 #ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
12417 extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
12418 #define fill_default_txdesc rtl8192es_fill_default_txdesc
12419 #endif // CONFIG_SDIO_HCI
12420 #endif //CONFIG_RTL8192E
12422 static s32 initLoopback(PADAPTER padapter)
12424 PLOOPBACKDATA ploopback;
12427 if (padapter->ploopback == NULL) {
12428 ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
12429 if (ploopback == NULL) return -ENOMEM;
12431 _rtw_init_sema(&ploopback->sema, 0);
12432 ploopback->bstop = _TRUE;
12433 ploopback->cnt = 0;
12434 ploopback->size = 300;
12435 _rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
12437 padapter->ploopback = ploopback;
12443 static void freeLoopback(PADAPTER padapter)
12445 PLOOPBACKDATA ploopback;
12448 ploopback = padapter->ploopback;
12450 rtw_mfree((u8*)ploopback, sizeof(LOOPBACKDATA));
12451 padapter->ploopback = NULL;
12455 static s32 initpseudoadhoc(PADAPTER padapter)
12457 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
12460 networkType = Ndis802_11IBSS;
12461 err = rtw_set_802_11_infrastructure_mode(padapter, networkType);
12462 if (err == _FALSE) return _FAIL;
12464 err = rtw_setopmode_cmd(padapter, networkType,_TRUE);
12465 if (err == _FAIL) return _FAIL;
12470 static s32 createpseudoadhoc(PADAPTER padapter)
12472 NDIS_802_11_AUTHENTICATION_MODE authmode;
12473 struct mlme_priv *pmlmepriv;
12474 NDIS_802_11_SSID *passoc_ssid;
12475 WLAN_BSSID_EX *pdev_network;
12477 u8 ssid[] = "pseduo_ad-hoc";
12482 pmlmepriv = &padapter->mlmepriv;
12484 authmode = Ndis802_11AuthModeOpen;
12485 err = rtw_set_802_11_authentication_mode(padapter, authmode);
12486 if (err == _FALSE) return _FAIL;
12488 passoc_ssid = &pmlmepriv->assoc_ssid;
12489 _rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
12490 passoc_ssid->SsidLength = sizeof(ssid) - 1;
12491 _rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
12493 pdev_network = &padapter->registrypriv.dev_network;
12494 pibss = padapter->registrypriv.dev_network.MacAddress;
12495 _rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
12497 rtw_update_registrypriv_dev_network(padapter);
12498 rtw_generate_random_ibss(pibss);
12500 _enter_critical_bh(&pmlmepriv->lock, &irqL);
12501 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
12502 _exit_critical_bh(&pmlmepriv->lock, &irqL);
12505 err = rtw_create_ibss_cmd(padapter, 0);
12506 if (err == _FAIL) return _FAIL;
12509 struct wlan_network *pcur_network;
12510 struct sta_info *psta;
12512 //3 create a new psta
12513 pcur_network = &pmlmepriv->cur_network;
12515 //clear psta in the cur_network, if any
12516 psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
12517 if (psta) rtw_free_stainfo(padapter, psta);
12519 psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
12520 if (psta == NULL) return _FAIL;
12522 //3 join psudo AdHoc
12523 pcur_network->join_res = 1;
12524 pcur_network->aid = psta->aid = 1;
12525 _rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
12527 // set msr to WIFI_FW_ADHOC_STATE
12529 Set_NETYPE0_MSR(padapter, WIFI_FW_ADHOC_STATE);
12534 val8 = rtw_read8(padapter, MSR);
12535 val8 &= 0xFC; // clear NETYPE0
12536 val8 |= WIFI_FW_ADHOC_STATE & 0x3;
12537 rtw_write8(padapter, MSR, val8);
12546 static struct xmit_frame* createloopbackpkt(PADAPTER padapter, u32 size)
12548 struct xmit_priv *pxmitpriv;
12549 struct xmit_frame *pframe;
12550 struct xmit_buf *pxmitbuf;
12551 struct pkt_attrib *pattrib;
12552 struct tx_desc *desc;
12553 u8 *pkt_start, *pkt_end, *ptr;
12554 struct rtw_ieee80211_hdr *hdr;
12559 if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ) return NULL;
12561 pxmitpriv = &padapter->xmitpriv;
12564 //2 1. allocate xmit frame
12565 pframe = rtw_alloc_xmitframe(pxmitpriv);
12566 if (pframe == NULL) return NULL;
12567 pframe->padapter = padapter;
12569 //2 2. allocate xmit buffer
12570 _enter_critical_bh(&pxmitpriv->lock, &irqL);
12571 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
12572 _exit_critical_bh(&pxmitpriv->lock, &irqL);
12573 if (pxmitbuf == NULL) {
12574 rtw_free_xmitframe(pxmitpriv, pframe);
12578 pframe->pxmitbuf = pxmitbuf;
12579 pframe->buf_addr = pxmitbuf->pbuf;
12580 pxmitbuf->priv_data = pframe;
12582 //2 3. update_attrib()
12583 pattrib = &pframe->attrib;
12585 // init xmitframe attribute
12586 _rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
12588 pattrib->ether_type = 0x8723;
12589 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
12590 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
12591 _rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
12592 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
12594 // pattrib->dhcp_pkt = 0;
12595 // pattrib->pktlen = 0;
12596 pattrib->ack_policy = 0;
12597 // pattrib->pkt_hdrlen = ETH_HLEN;
12598 pattrib->hdrlen = WLAN_HDR_A3_LEN;
12599 pattrib->subtype = WIFI_DATA;
12600 pattrib->priority = 0;
12601 pattrib->qsel = pattrib->priority;
12602 // do_queue_select(padapter, pattrib);
12603 pattrib->nr_frags = 1;
12604 pattrib->encrypt = 0;
12605 pattrib->bswenc = _FALSE;
12606 pattrib->qos_en = _FALSE;
12608 bmcast = IS_MCAST(pattrib->ra);
12610 pattrib->mac_id = 1;
12611 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
12613 pattrib->mac_id = 0;
12614 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
12617 pattrib->pktlen = size;
12618 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
12620 //2 4. fill TX descriptor
12621 desc = (struct tx_desc*)pframe->buf_addr;
12622 _rtw_memset(desc, 0, TXDESC_SIZE);
12624 fill_default_txdesc(pframe, (u8*)desc);
12626 // Hw set sequence number
12627 ((PTXDESC)desc)->hwseq_en = 0; // HWSEQ_EN, 0:disable, 1:enable
12628 // ((PTXDESC)desc)->hwseq_sel = 0; // HWSEQ_SEL
12630 ((PTXDESC)desc)->disdatafb = 1;
12632 // convert to little endian
12633 desc->txdw0 = cpu_to_le32(desc->txdw0);
12634 desc->txdw1 = cpu_to_le32(desc->txdw1);
12635 desc->txdw2 = cpu_to_le32(desc->txdw2);
12636 desc->txdw3 = cpu_to_le32(desc->txdw3);
12637 desc->txdw4 = cpu_to_le32(desc->txdw4);
12638 desc->txdw5 = cpu_to_le32(desc->txdw5);
12639 desc->txdw6 = cpu_to_le32(desc->txdw6);
12640 desc->txdw7 = cpu_to_le32(desc->txdw7);
12641 #ifdef CONFIG_PCI_HCI
12642 desc->txdw8 = cpu_to_le32(desc->txdw8);
12643 desc->txdw9 = cpu_to_le32(desc->txdw9);
12644 desc->txdw10 = cpu_to_le32(desc->txdw10);
12645 desc->txdw11 = cpu_to_le32(desc->txdw11);
12646 desc->txdw12 = cpu_to_le32(desc->txdw12);
12647 desc->txdw13 = cpu_to_le32(desc->txdw13);
12648 desc->txdw14 = cpu_to_le32(desc->txdw14);
12649 desc->txdw15 = cpu_to_le32(desc->txdw15);
12652 cal_txdesc_chksum(desc);
12655 pkt_start = pframe->buf_addr + TXDESC_SIZE;
12656 pkt_end = pkt_start + pattrib->last_txcmdsz;
12658 //3 5.1. make wlan header, make_wlanhdr()
12659 hdr = (struct rtw_ieee80211_hdr *)pkt_start;
12660 SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
12661 _rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); // DA
12662 _rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); // SA
12663 _rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); // RA, BSSID
12665 //3 5.2. make payload
12666 ptr = pkt_start + pattrib->hdrlen;
12667 get_random_bytes(ptr, pkt_end - ptr);
12669 pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
12670 pxmitbuf->ptail += pxmitbuf->len;
12675 static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
12677 struct xmit_priv *pxmitpriv;
12678 struct xmit_buf *pxmitbuf;
12681 pxmitpriv = &padapter->xmitpriv;
12682 pxmitbuf = pframe->pxmitbuf;
12684 rtw_free_xmitframe(pxmitpriv, pframe);
12685 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
12688 static void printdata(u8 *pbuf, u32 len)
12693 for (i = 0; (i+4) <= len; i+=4) {
12694 printk("%08X", *(u32*)(pbuf + i));
12695 if ((i+4) & 0x1F) printk(" ");
12701 #ifdef CONFIG_BIG_ENDIAN
12702 for (; i < len, i++)
12703 printk("%02X", pbuf+i);
12704 #else // CONFIG_LITTLE_ENDIAN
12707 _rtw_memcpy(&val, pbuf + i, len - i);
12708 printk("%8X", val);
12714 _rtw_memcpy(&val, pbuf+i, n);
12715 sprintf(str, "%08X", val);
12717 printk("%8s", str+n);
12719 #endif // CONFIG_LITTLE_ENDIAN
12724 static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
12726 PHAL_DATA_TYPE phal;
12727 struct recv_stat *prxstat;
12728 struct recv_stat report;
12729 PRXREPORT prxreport;
12735 prxstat = (struct recv_stat*)rxbuf;
12736 report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
12737 report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
12738 report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
12739 report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
12740 report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
12741 report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
12743 prxreport = (PRXREPORT)&report;
12744 drvinfosize = prxreport->drvinfosize << 3;
12745 rxpktsize = prxreport->pktlen;
12747 phal = GET_HAL_DATA(padapter);
12748 if (phal->ReceiveConfig & RCR_APPFCS) fcssize = IEEE80211_FCS_LEN;
12751 if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
12752 DBG_8192C("%s: ERROR! size not match tx/rx=%d/%d !\n",
12753 __func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
12756 ret = _rtw_memcmp(txbuf + TXDESC_SIZE,\
12757 rxbuf + RXDESC_SIZE + drvinfosize,\
12758 txsz - TXDESC_SIZE);
12759 if (ret == _FALSE) {
12760 DBG_8192C("%s: ERROR! pkt content mismatch!\n", __func__);
12766 DBG_8192C("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
12767 __func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
12768 DBG_8192C("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
12769 printdata(txbuf, TXDESC_SIZE);
12770 DBG_8192C("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
12771 printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
12773 DBG_8192C("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
12774 __func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
12775 if (rxpktsize != 0)
12777 DBG_8192C("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
12778 printdata(rxbuf, RXDESC_SIZE);
12779 DBG_8192C("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
12780 printdata(rxbuf + RXDESC_SIZE, drvinfosize);
12781 DBG_8192C("%s: RX content size=%d\n", __func__, rxpktsize);
12782 printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
12784 DBG_8192C("%s: RX data size=%d\n", __func__, rxsz);
12785 printdata(rxbuf, rxsz);
12792 thread_return lbk_thread(thread_context context)
12796 PLOOPBACKDATA ploopback;
12797 struct xmit_frame *pxmitframe;
12798 u32 cnt, ok, fail, headerlen;
12803 padapter = (PADAPTER)context;
12804 ploopback = padapter->ploopback;
12805 if (ploopback == NULL) return -1;
12810 daemonize("%s", "RTW_LBK_THREAD");
12811 allow_signal(SIGTERM);
12814 if (ploopback->size == 0) {
12815 get_random_bytes(&pktsize, 4);
12816 pktsize = (pktsize % 1535) + 1; // 1~1535
12818 pktsize = ploopback->size;
12820 pxmitframe = createloopbackpkt(padapter, pktsize);
12821 if (pxmitframe == NULL) {
12822 sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
12826 ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
12827 _rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
12828 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
12830 DBG_8192C("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
12831 pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
12832 rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
12835 _rtw_down_sema(&ploopback->sema);
12837 err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
12843 ploopback->txsize = 0;
12844 _rtw_memset(ploopback->txbuf, 0, 0x8000);
12845 ploopback->rxsize = 0;
12846 _rtw_memset(ploopback->rxbuf, 0, 0x8000);
12848 freeloopbackpkt(padapter, pxmitframe);
12851 if (signal_pending(current)) {
12852 flush_signals(current);
12855 if ((ploopback->bstop == _TRUE) ||
12856 ((ploopback->cnt != 0) && (ploopback->cnt == cnt)))
12858 u32 ok_rate, fail_rate, all;
12860 ok_rate = (ok*100)/all;
12861 fail_rate = (fail*100)/all;
12862 sprintf(ploopback->msg,\
12863 "loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)",\
12864 ok_rate, ok, all, fail_rate, fail, all);
12869 ploopback->bstop = _TRUE;
12874 static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8* pmsg)
12876 PLOOPBACKDATA ploopback;
12881 ploopback = padapter->ploopback;
12885 if (ploopback->bstop == _FALSE) {
12886 ploopback->bstop = _TRUE;
12887 _rtw_up_sema(&ploopback->sema);
12891 len = strlen(ploopback->msg);
12895 _rtw_memcpy(pmsg, ploopback->msg, len+1);
12896 freeLoopback(padapter);
12901 // disable dynamic algorithm
12902 rtw_phydm_ability_backup(padapter);
12903 rtw_phydm_func_disable_all(padapter);
12905 // create pseudo ad-hoc connection
12906 err = initpseudoadhoc(padapter);
12907 if (err == _FAIL) {
12908 sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
12912 err = createpseudoadhoc(padapter);
12913 if (err == _FAIL) {
12914 sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
12918 err = initLoopback(padapter);
12920 sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
12924 ploopback = padapter->ploopback;
12926 ploopback->bstop = _FALSE;
12927 ploopback->cnt = cnt;
12928 ploopback->size = size;
12929 ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
12930 if (IS_ERR(padapter->lbkthread))
12932 freeLoopback(padapter);
12933 sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
12937 sprintf(pmsg, "loopback start! cnt=%d", cnt);
12939 #endif // CONFIG_MAC_LOOPBACK_DRIVER
12941 static int rtw_test(
12942 struct net_device *dev,
12943 struct iw_request_info *info,
12944 union iwreq_data *wrqu, char *extra)
12950 PADAPTER padapter = rtw_netdev_priv(dev);
12953 DBG_871X("+%s\n", __func__);
12954 len = wrqu->data.length;
12956 pbuf = (u8*)rtw_zmalloc(len);
12957 if (pbuf == NULL) {
12958 DBG_871X("%s: no memory!\n", __func__);
12962 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
12963 rtw_mfree(pbuf, len);
12964 DBG_871X("%s: copy from user fail!\n", __func__);
12967 DBG_871X("%s: string=\"%s\"\n", __func__, pbuf);
12969 ptmp = (char*)pbuf;
12970 pch = strsep(&ptmp, delim);
12971 if ((pch == NULL) || (strlen(pch) == 0)) {
12972 rtw_mfree(pbuf, len);
12973 DBG_871X("%s: parameter error(level 1)!\n", __func__);
12977 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
12978 if (strcmp(pch, "loopback") == 0)
12983 pch = strsep(&ptmp, delim);
12984 if ((pch == NULL) || (strlen(pch) == 0)) {
12985 rtw_mfree(pbuf, len);
12986 DBG_871X("%s: parameter error(level 2)!\n", __func__);
12990 sscanf(pch, "%d", &cnt);
12991 DBG_871X("%s: loopback cnt=%d\n", __func__, cnt);
12993 pch = strsep(&ptmp, delim);
12994 if ((pch == NULL) || (strlen(pch) == 0)) {
12995 rtw_mfree(pbuf, len);
12996 DBG_871X("%s: parameter error(level 2)!\n", __func__);
13000 sscanf(pch, "%d", &size);
13001 DBG_871X("%s: loopback size=%d\n", __func__, size);
13003 loopbackTest(padapter, cnt, size, extra);
13004 wrqu->data.length = strlen(extra) + 1;
13011 #ifdef CONFIG_BT_COEXIST
13012 if (strcmp(pch, "bton") == 0) {
13013 rtw_btcoex_SetManualControl(padapter, _FALSE);
13015 } else if (strcmp(pch, "btoff") == 0) {
13016 rtw_btcoex_SetManualControl(padapter, _TRUE);
13021 if (strcmp(pch, "h2c") == 0) {
13030 pch = strsep(&ptmp, delim);
13031 if ((pch == NULL) || (strlen(pch) == 0))
13034 sscanf(pch, "%x", &tmp);
13035 param[count++] = (u8)tmp;
13036 } while (count < 8);
13039 rtw_mfree(pbuf, len);
13040 DBG_871X("%s: parameter error(level 2)!\n", __func__);
13044 ret = rtw_hal_fill_h2c_cmd(padapter, param[0], count-1, ¶m[1]);
13046 pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
13047 for (i=1; i<count; i++) {
13048 pos += sprintf(extra+pos, "%02x,", param[i]);
13052 pos += sprintf(extra+pos, " %s", ret==_FAIL?"FAIL":"OK");
13054 wrqu->data.length = strlen(extra) + 1;
13060 rtw_mfree(pbuf, len);
13064 static iw_handler rtw_handlers[] =
13066 NULL, /* SIOCSIWCOMMIT */
13067 rtw_wx_get_name, /* SIOCGIWNAME */
13068 dummy, /* SIOCSIWNWID */
13069 dummy, /* SIOCGIWNWID */
13070 rtw_wx_set_freq, /* SIOCSIWFREQ */
13071 rtw_wx_get_freq, /* SIOCGIWFREQ */
13072 rtw_wx_set_mode, /* SIOCSIWMODE */
13073 rtw_wx_get_mode, /* SIOCGIWMODE */
13074 dummy, /* SIOCSIWSENS */
13075 rtw_wx_get_sens, /* SIOCGIWSENS */
13076 NULL, /* SIOCSIWRANGE */
13077 rtw_wx_get_range, /* SIOCGIWRANGE */
13078 rtw_wx_set_priv, /* SIOCSIWPRIV */
13079 NULL, /* SIOCGIWPRIV */
13080 NULL, /* SIOCSIWSTATS */
13081 NULL, /* SIOCGIWSTATS */
13082 dummy, /* SIOCSIWSPY */
13083 dummy, /* SIOCGIWSPY */
13084 NULL, /* SIOCGIWTHRSPY */
13085 NULL, /* SIOCWIWTHRSPY */
13086 rtw_wx_set_wap, /* SIOCSIWAP */
13087 rtw_wx_get_wap, /* SIOCGIWAP */
13088 rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */
13089 dummy, /* SIOCGIWAPLIST -- depricated */
13090 rtw_wx_set_scan, /* SIOCSIWSCAN */
13091 rtw_wx_get_scan, /* SIOCGIWSCAN */
13092 rtw_wx_set_essid, /* SIOCSIWESSID */
13093 rtw_wx_get_essid, /* SIOCGIWESSID */
13094 dummy, /* SIOCSIWNICKN */
13095 rtw_wx_get_nick, /* SIOCGIWNICKN */
13096 NULL, /* -- hole -- */
13097 NULL, /* -- hole -- */
13098 rtw_wx_set_rate, /* SIOCSIWRATE */
13099 rtw_wx_get_rate, /* SIOCGIWRATE */
13100 rtw_wx_set_rts, /* SIOCSIWRTS */
13101 rtw_wx_get_rts, /* SIOCGIWRTS */
13102 rtw_wx_set_frag, /* SIOCSIWFRAG */
13103 rtw_wx_get_frag, /* SIOCGIWFRAG */
13104 dummy, /* SIOCSIWTXPOW */
13105 dummy, /* SIOCGIWTXPOW */
13106 dummy, /* SIOCSIWRETRY */
13107 rtw_wx_get_retry, /* SIOCGIWRETRY */
13108 rtw_wx_set_enc, /* SIOCSIWENCODE */
13109 rtw_wx_get_enc, /* SIOCGIWENCODE */
13110 dummy, /* SIOCSIWPOWER */
13111 rtw_wx_get_power, /* SIOCGIWPOWER */
13112 NULL, /*---hole---*/
13113 NULL, /*---hole---*/
13114 rtw_wx_set_gen_ie, /* SIOCSIWGENIE */
13115 NULL, /* SIOCGWGENIE */
13116 rtw_wx_set_auth, /* SIOCSIWAUTH */
13117 NULL, /* SIOCGIWAUTH */
13118 rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
13119 NULL, /* SIOCGIWENCODEEXT */
13120 rtw_wx_set_pmkid, /* SIOCSIWPMKSA */
13121 NULL, /*---hole---*/
13125 static const struct iw_priv_args rtw_private_args[] = {
13127 SIOCIWFIRSTPRIV + 0x0,
13128 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
13131 SIOCIWFIRSTPRIV + 0x1,
13132 IW_PRIV_TYPE_CHAR | 0x7FF,
13133 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
13136 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
13139 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
13142 SIOCIWFIRSTPRIV + 0x4,
13143 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
13146 SIOCIWFIRSTPRIV + 0x5,
13147 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
13150 SIOCIWFIRSTPRIV + 0x6,
13151 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
13153 //for PLATFORM_MT53XX
13155 SIOCIWFIRSTPRIV + 0x7,
13156 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
13159 SIOCIWFIRSTPRIV + 0x8,
13160 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
13163 SIOCIWFIRSTPRIV + 0x9,
13164 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
13167 //for RTK_DMP_PLATFORM
13169 SIOCIWFIRSTPRIV + 0xA,
13170 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
13174 SIOCIWFIRSTPRIV + 0xB,
13175 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
13178 SIOCIWFIRSTPRIV + 0xC,
13179 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
13182 SIOCIWFIRSTPRIV + 0xD,
13183 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
13187 SIOCIWFIRSTPRIV + 0xE,0,0, "wowlan_ctrl"
13191 SIOCIWFIRSTPRIV + 0x10,
13192 IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
13195 SIOCIWFIRSTPRIV + 0x11,
13196 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
13199 SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
13202 SIOCIWFIRSTPRIV + 0x13,
13203 IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
13206 SIOCIWFIRSTPRIV + 0x14,
13207 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
13210 SIOCIWFIRSTPRIV + 0x15,
13211 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
13214 SIOCIWFIRSTPRIV + 0x16,
13215 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
13218 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
13219 #ifdef CONFIG_MP_INCLUDED
13220 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
13221 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
13223 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
13224 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
13227 SIOCIWFIRSTPRIV + 0x1D,
13228 IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
13231 #ifdef CONFIG_INTEL_WIDI
13233 SIOCIWFIRSTPRIV + 0x1E,
13234 IW_PRIV_TYPE_CHAR | 1024, 0, "widi_set"
13237 SIOCIWFIRSTPRIV + 0x1F,
13238 IW_PRIV_TYPE_CHAR | 128, 0, "widi_prob_req"
13240 #endif // CONFIG_INTEL_WIDI
13242 #ifdef CONFIG_MP_INCLUDED
13243 { SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, //set
13244 { SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},//get
13245 /* --- sub-ioctls definitions --- */
13246 { MP_START , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start" }, //set
13247 { MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },//get
13248 { MP_STOP , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop" }, //set
13249 { MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },//get
13250 { MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, //set
13251 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },//get
13252 { MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
13253 { MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"}, //get
13254 { READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
13255 { MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
13256 { READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
13257 { MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
13258 { MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
13259 { MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
13260 { MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
13261 { MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
13262 { WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
13263 { WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
13264 { MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
13265 { MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
13266 { MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
13267 { EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
13268 { EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
13269 { MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
13270 { MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
13271 { MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"}, // mp_ioctl
13272 { MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath" },
13273 { MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
13274 { MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
13275 { MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },
13276 { MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },
13277 { EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },
13278 { EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },
13279 { MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },
13280 { MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },
13281 { MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },
13282 #if defined(CONFIG_RTL8723B)
13283 { MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
13284 { MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
13286 { CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
13288 #ifdef CONFIG_WOWLAN
13289 { MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
13290 { MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },
13292 #ifdef CONFIG_AP_WOWLAN
13293 { MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, //set
13295 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
13296 { MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },
13297 { MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },
13301 static iw_handler rtw_private_handler[] =
13303 rtw_wx_write32, //0x00
13304 rtw_wx_read32, //0x01
13305 rtw_drvext_hdl, //0x02
13306 rtw_mp_ioctl_hdl, //0x03
13308 // for MM DTV platform
13309 rtw_get_ap_info, //0x04
13311 rtw_set_pid, //0x05
13312 rtw_wps_start, //0x06
13314 // for PLATFORM_MT53XX
13315 rtw_wx_get_sensitivity, //0x07
13316 rtw_wx_set_mtk_wps_probe_ie, //0x08
13317 rtw_wx_set_mtk_wps_ie, //0x09
13319 // for RTK_DMP_PLATFORM
13320 // Set Channel depend on the country code
13321 rtw_wx_set_channel_plan, //0x0A
13323 rtw_dbg_port, //0x0B
13324 rtw_wx_write_rf, //0x0C
13325 rtw_wx_read_rf, //0x0D
13326 #ifdef CONFIG_MP_INCLUDED
13330 rtw_wx_priv_null, //0x0E
13331 rtw_wx_priv_null, //0x0F
13333 rtw_p2p_set, //0x10
13334 rtw_p2p_get, //0x11
13336 rtw_p2p_get2, //0x13
13339 rtw_tdls_get, //0x15
13342 rtw_wx_priv_null, //0x17
13343 rtw_rereg_nd_name, //0x18
13344 rtw_wx_priv_null, //0x19
13345 #ifdef CONFIG_MP_INCLUDED
13346 rtw_wx_priv_null, //0x1A
13347 rtw_wx_priv_null, //0x1B
13349 rtw_mp_efuse_set, //0x1A
13350 rtw_mp_efuse_get, //0x1B
13352 NULL, // 0x1C is reserved for hostapd
13354 #ifdef CONFIG_INTEL_WIDI
13355 rtw_widi_set, //0x1E
13356 rtw_widi_set_probe_request, //0x1F
13357 #endif // CONFIG_INTEL_WIDI
13361 #if WIRELESS_EXT >= 17
13362 static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
13364 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
13365 struct iw_statistics *piwstats=&padapter->iwstats;
13370 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE)
13372 piwstats->qual.qual = 0;
13373 piwstats->qual.level = 0;
13374 piwstats->qual.noise = 0;
13375 //DBG_871X("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
13378 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
13379 tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
13381 #ifdef CONFIG_SIGNAL_SCALE_MAPPING
13382 tmp_level = padapter->recvpriv.signal_strength;
13385 /* Do signal scale mapping when using percentage as the unit of signal strength, since the scale mapping is skipped in odm */
13387 HAL_DATA_TYPE *pHal = GET_HAL_DATA(padapter);
13389 tmp_level = (u8)odm_SignalScaleMapping(&pHal->odmpriv, padapter->recvpriv.signal_strength);
13394 tmp_qual = padapter->recvpriv.signal_qual;
13395 rtw_get_noise(padapter);
13396 tmp_noise = padapter->recvpriv.noise;
13397 //DBG_871X("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi);
13399 piwstats->qual.level = tmp_level;
13400 piwstats->qual.qual = tmp_qual;
13401 piwstats->qual.noise = tmp_noise;
13403 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
13404 piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;//|IW_QUAL_DBM;
13406 #ifdef RTK_DMP_PLATFORM
13407 //IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm.
13408 //remove this flag for show percentage 0~100
13409 piwstats->qual.updated = 0x07;
13411 piwstats->qual.updated = 0x0f;
13415 #ifdef CONFIG_SIGNAL_DISPLAY_DBM
13416 piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
13419 return &padapter->iwstats;
13423 #ifdef CONFIG_WIRELESS_EXT
13424 struct iw_handler_def rtw_handlers_def =
13426 .standard = rtw_handlers,
13427 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
13428 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) || defined(CONFIG_WEXT_PRIV)
13429 .private = rtw_private_handler,
13430 .private_args = (struct iw_priv_args *)rtw_private_args,
13431 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
13432 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
13434 #if WIRELESS_EXT >= 17
13435 .get_wireless_stats = rtw_get_wireless_stats,
13440 // copy from net/wireless/wext.c start
13441 /* ---------------------------------------------------------------- */
13443 * Calculate size of private arguments
13445 static const char iw_priv_type_size[] = {
13446 0, /* IW_PRIV_TYPE_NONE */
13447 1, /* IW_PRIV_TYPE_BYTE */
13448 1, /* IW_PRIV_TYPE_CHAR */
13449 0, /* Not defined */
13450 sizeof(__u32), /* IW_PRIV_TYPE_INT */
13451 sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
13452 sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
13453 0, /* Not defined */
13456 static int get_priv_size(__u16 args)
13458 int num = args & IW_PRIV_SIZE_MASK;
13459 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
13461 return num * iw_priv_type_size[type];
13463 // copy from net/wireless/wext.c end
13466 static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
13471 const char delim[] = " ";
13473 u32 output_len = 0;
13476 u32 buffer_len = 0;
13478 u8 cmdname[17] = {0}; // IFNAMSIZ+1
13482 u32 extra_size = 0;
13485 const iw_handler *priv; /* Private ioctl */
13486 const struct iw_priv_args *priv_args; /* Private ioctl description */
13487 u32 num_priv; /* Number of ioctl */
13488 u32 num_priv_args; /* Number of descriptions */
13489 iw_handler handler;
13491 int subcmd = 0; /* sub-ioctl index */
13492 int offset = 0; /* Space for sub-ioctl index */
13494 union iwreq_data wdata;
13496 _rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
13498 input_len = wdata.data.length;
13499 input = rtw_zmalloc(input_len);
13500 if (NULL == input || input_len == 0)
13502 if (copy_from_user(input, wdata.data.pointer, input_len)) {
13506 input[input_len - 1] = '\0';
13515 sscanf(ptr, "%16s", cmdname);
13516 cmdlen = strlen(cmdname);
13517 DBG_871X("%s: cmd=%s\n", __func__, cmdname);
13519 // skip command string
13521 cmdlen += 1; // skip one space
13524 DBG_871X("%s: parameters=%s\n", __func__, ptr);
13526 priv = rtw_private_handler;
13527 priv_args = rtw_private_args;
13528 num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
13529 num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
13531 if (num_priv_args == 0) {
13536 /* Search the correct ioctl */
13538 while((++k < num_priv_args) && strcmp(priv_args[k].name, cmdname));
13540 /* If not found... */
13541 if (k == num_priv_args) {
13546 /* Watch out for sub-ioctls ! */
13547 if (priv_args[k].cmd < SIOCDEVPRIVATE)
13551 /* Find the matching *real* ioctl */
13552 while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
13553 (priv_args[j].set_args != priv_args[k].set_args) ||
13554 (priv_args[j].get_args != priv_args[k].get_args)));
13556 /* If not found... */
13557 if (j == num_priv_args) {
13562 /* Save sub-ioctl number */
13563 subcmd = priv_args[k].cmd;
13564 /* Reserve one int (simplify alignment issues) */
13565 offset = sizeof(__u32);
13566 /* Use real ioctl definition from now on */
13570 buffer = rtw_zmalloc(4096);
13571 if (NULL == buffer) {
13576 /* If we have to set some data */
13577 if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
13578 (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
13582 switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK)
13584 case IW_PRIV_TYPE_BYTE:
13588 str = strsep(&ptr, delim);
13589 if (NULL == str) break;
13590 sscanf(str, "%i", &temp);
13591 buffer[count++] = (u8)temp;
13593 buffer_len = count;
13595 /* Number of args to fetch */
13596 wdata.data.length = count;
13597 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
13598 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
13602 case IW_PRIV_TYPE_INT:
13606 str = strsep(&ptr, delim);
13607 if (NULL == str) break;
13608 sscanf(str, "%i", &temp);
13609 ((s32*)buffer)[count++] = (s32)temp;
13611 buffer_len = count * sizeof(s32);
13613 /* Number of args to fetch */
13614 wdata.data.length = count;
13615 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
13616 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
13620 case IW_PRIV_TYPE_CHAR:
13623 /* Size of the string to fetch */
13624 wdata.data.length = len;
13625 if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
13626 wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
13629 _rtw_memcpy(buffer, ptr, wdata.data.length);
13633 wdata.data.length = 1;
13636 buffer_len = wdata.data.length;
13640 DBG_8192C("%s: Not yet implemented...\n", __func__);
13645 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
13646 (wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK)))
13648 DBG_8192C("%s: The command %s needs exactly %d argument(s)...\n",
13649 __func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
13653 } /* if args to set */
13656 wdata.data.length = 0L;
13659 /* Those two tests are important. They define how the driver
13660 * will have to handle the data */
13661 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
13662 ((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ))
13664 /* First case : all SET args fit within wrq */
13666 wdata.mode = subcmd;
13667 _rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
13671 if ((priv_args[k].set_args == 0) &&
13672 (priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
13673 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
13675 /* Second case : no SET args, GET args fit within wrq */
13677 wdata.mode = subcmd;
13681 /* Third case : args won't fit in wrq, or variable number of args */
13682 if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
13686 wdata.data.flags = subcmd;
13690 rtw_mfree(input, input_len);
13694 if (IW_IS_SET(priv_args[k].cmd))
13696 /* Size of set arguments */
13697 extra_size = get_priv_size(priv_args[k].set_args);
13699 /* Does it fits in iwr ? */
13700 if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
13701 ((extra_size + offset) <= IFNAMSIZ))
13704 /* Size of get arguments */
13705 extra_size = get_priv_size(priv_args[k].get_args);
13707 /* Does it fits in iwr ? */
13708 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
13709 (extra_size <= IFNAMSIZ))
13713 if (extra_size == 0) {
13714 extra = (u8*)&wdata;
13715 rtw_mfree(buffer, 4096);
13720 handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
13721 err = handler(dev, NULL, &wdata, extra);
13723 /* If we have to get some data */
13724 if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
13725 (priv_args[k].get_args & IW_PRIV_SIZE_MASK))
13728 int n = 0; /* number of args */
13731 /* Check where is the returned data */
13732 if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
13733 (get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
13734 n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
13736 n = wdata.data.length;
13738 output = rtw_zmalloc(4096);
13739 if (NULL == output) {
13744 switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK)
13746 case IW_PRIV_TYPE_BYTE:
13748 for (j = 0; j < n; j++)
13750 sprintf(str, "%d ", extra[j]);
13752 output_len = strlen(output);
13753 if ((output_len + len + 1) > 4096) {
13757 _rtw_memcpy(output+output_len, str, len);
13761 case IW_PRIV_TYPE_INT:
13763 for (j = 0; j < n; j++)
13765 sprintf(str, "%d ", ((__s32*)extra)[j]);
13767 output_len = strlen(output);
13768 if ((output_len + len + 1) > 4096) {
13772 _rtw_memcpy(output+output_len, str, len);
13776 case IW_PRIV_TYPE_CHAR:
13778 _rtw_memcpy(output, extra, n);
13782 DBG_8192C("%s: Not yet implemented...\n", __func__);
13787 output_len = strlen(output) + 1;
13788 wrq_data->data.length = output_len;
13789 if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
13793 } /* if args to set */
13796 wrq_data->data.length = 0;
13801 rtw_mfree(input, input_len);
13803 rtw_mfree(buffer, 4096);
13805 rtw_mfree(output, 4096);
13810 #ifdef CONFIG_COMPAT
13811 static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)
13813 struct compat_iw_point iwp_compat;
13814 union iwreq_data wrq_data;
13816 DBG_871X("%s:...\n", __func__);
13817 if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))
13820 wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);
13821 wrq_data.data.length = iwp_compat.length;
13822 wrq_data.data.flags = iwp_compat.flags;
13824 err = _rtw_ioctl_wext_private(dev, &wrq_data);
13826 iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);
13827 iwp_compat.length = wrq_data.data.length;
13828 iwp_compat.flags = wrq_data.data.flags;
13829 if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))
13834 #endif // CONFIG_COMPAT
13836 static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)
13838 struct iw_point *iwp;
13840 union iwreq_data wrq_data;
13842 iwp = &wrq_data.data;
13843 DBG_871X("%s:...\n", __func__);
13844 if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))
13847 err = _rtw_ioctl_wext_private(dev, &wrq_data);
13849 if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))
13855 static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq)
13857 #ifdef CONFIG_COMPAT
13858 if(is_compat_task())
13859 return rtw_ioctl_compat_wext_private( dev, rq );
13861 #endif // CONFIG_COMPAT
13862 return rtw_ioctl_standard_wext_private( dev, rq );
13865 int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
13867 struct iwreq *wrq = (struct iwreq *)rq;
13872 case RTL_IOCTL_WPA_SUPPLICANT:
13873 ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
13875 #ifdef CONFIG_AP_MODE
13876 case RTL_IOCTL_HOSTAPD:
13877 ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
13879 #ifdef CONFIG_WIRELESS_EXT
13881 ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
13884 #endif // CONFIG_AP_MODE
13885 case SIOCDEVPRIVATE:
13886 ret = rtw_ioctl_wext_private(dev, rq);
13888 case (SIOCDEVPRIVATE+1):
13889 ret = rtw_android_priv_cmd(dev, rq, cmd);