Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/ioctl_linux.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#define _IOCTL_LINUX_C_1516#include <drv_types.h>17#include <rtw_mp.h>18#include "../../hal/phydm/phydm_precomp.h"19#ifdef RTW_HALMAC20#include "../../hal/hal_halmac.h"21#endif2223#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))24#define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e)25#define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e)26#endif2728#ifdef CONFIG_80211N_HT29extern int rtw_ht_enable;30#endif313233#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)3435#define SCAN_ITEM_SIZE 76836#define MAX_CUSTOM_LEN 6437#define RATE_COUNT 438#define MAX_SCAN_BUFFER_LEN 655353940#ifdef CONFIG_GLOBAL_UI_PID41extern int ui_pid[3];42#endif4344/* combo scan */45#define WEXT_CSCAN_AMOUNT 946#define WEXT_CSCAN_BUF_LEN 36047#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"48#define WEXT_CSCAN_HEADER_SIZE 1249#define WEXT_CSCAN_SSID_SECTION 'S'50#define WEXT_CSCAN_CHANNEL_SECTION 'C'51#define WEXT_CSCAN_NPROBE_SECTION 'N'52#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'53#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'54#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'55#define WEXT_CSCAN_TYPE_SECTION 'T'565758extern u8 key_2char2num(u8 hch, u8 lch);59extern u8 str_2char2num(u8 hch, u8 lch);60extern void macstr2num(u8 *dst, u8 *src);61extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);6263u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,646000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};6566/**67* hwaddr_aton - Convert ASCII string to MAC address68* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")69* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)70* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)71*/72static int hwaddr_aton_i(const char *txt, u8 *addr)73{74int i;7576for (i = 0; i < 6; i++) {77int a, b;7879a = hex2num_i(*txt++);80if (a < 0)81return -1;82b = hex2num_i(*txt++);83if (b < 0)84return -1;85*addr++ = (a << 4) | b;86if (i < 5 && *txt++ != ':')87return -1;88}8990return 0;91}92#ifdef CONFIG_ANDROID93static void indicate_wx_custom_event(_adapter *padapter, char *msg)94{95u8 *buff;96union iwreq_data wrqu;9798if (strlen(msg) > IW_CUSTOM_MAX) {99RTW_INFO("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);100return;101}102103buff = rtw_zmalloc(IW_CUSTOM_MAX + 1);104if (!buff)105return;106107_rtw_memcpy(buff, msg, strlen(msg));108109_rtw_memset(&wrqu, 0, sizeof(wrqu));110wrqu.data.length = strlen(msg);111112RTW_INFO("%s %s\n", __FUNCTION__, buff);113#ifndef CONFIG_IOCTL_CFG80211114wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);115#endif116117rtw_mfree(buff, IW_CUSTOM_MAX + 1);118119}120#endif121122#if 0123static void request_wps_pbc_event(_adapter *padapter)124{125u8 *buff, *p;126union iwreq_data wrqu;127128129buff = rtw_malloc(IW_CUSTOM_MAX);130if (!buff)131return;132133_rtw_memset(buff, 0, IW_CUSTOM_MAX);134135p = buff;136137p += sprintf(p, "WPS_PBC_START.request=TRUE");138139_rtw_memset(&wrqu, 0, sizeof(wrqu));140141wrqu.data.length = p - buff;142143wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX;144145RTW_INFO("%s\n", __FUNCTION__);146147#ifndef CONFIG_IOCTL_CFG80211148wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);149#endif150151if (buff)152rtw_mfree(buff, IW_CUSTOM_MAX);153154}155#endif156157#ifdef CONFIG_SUPPORT_HW_WPS_PBC158void rtw_request_wps_pbc_event(_adapter *padapter)159{160#ifdef RTK_DMP_PLATFORM161#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))162kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);163#else164kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);165#endif166#else167168if (padapter->pid[0] == 0) {169/* 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. */170return;171}172173rtw_signal_process(padapter->pid[0], SIGUSR1);174175#endif176177rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);178}179#endif/* #ifdef CONFIG_SUPPORT_HW_WPS_PBC */180181void indicate_wx_scan_complete_event(_adapter *padapter)182{183union iwreq_data wrqu;184185_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));186187/* RTW_INFO("+rtw_indicate_wx_scan_complete_event\n"); */188#ifndef CONFIG_IOCTL_CFG80211189wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);190#endif191}192193194void rtw_indicate_wx_assoc_event(_adapter *padapter)195{196union iwreq_data wrqu;197struct mlme_priv *pmlmepriv = &padapter->mlmepriv;198struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;199struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);200WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));201202_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));203204wrqu.ap_addr.sa_family = ARPHRD_ETHER;205206if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)207_rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);208else209_rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);210211RTW_PRINT("assoc success\n");212#ifndef CONFIG_IOCTL_CFG80211213wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);214#endif215}216217void rtw_indicate_wx_disassoc_event(_adapter *padapter)218{219union iwreq_data wrqu;220221_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));222223wrqu.ap_addr.sa_family = ARPHRD_ETHER;224_rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);225226#ifndef CONFIG_IOCTL_CFG80211227RTW_PRINT("indicate disassoc\n");228wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);229#endif230}231232/*233uint rtw_is_cckrates_included(u8 *rate)234{235u32 i = 0;236237while(rate[i]!=0)238{239if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||240(((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )241return _TRUE;242i++;243}244245return _FALSE;246}247248uint rtw_is_cckratesonly_included(u8 *rate)249{250u32 i = 0;251252while(rate[i]!=0)253{254if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&255(((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )256return _FALSE;257i++;258}259260return _TRUE;261}262*/263264static int search_p2p_wfd_ie(_adapter *padapter,265struct iw_request_info *info, struct wlan_network *pnetwork,266char *start, char *stop)267{268#ifdef CONFIG_P2P269struct wifidirect_info *pwdinfo = &padapter->wdinfo;270#ifdef CONFIG_WFD271if (SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type) {272273} else if ((SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type) ||274(SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type))275#endif /* CONFIG_WFD */276{277if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {278u32 blnGotP2PIE = _FALSE;279280/* User is doing the P2P device discovery */281/* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */282/* If not, the driver should ignore this AP and go to the next AP. */283284/* Verifying the SSID */285if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {286u32 p2pielen = 0;287288/* Verifying the P2P IE */289if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen))290blnGotP2PIE = _TRUE;291}292293if (blnGotP2PIE == _FALSE)294return _FALSE;295296}297}298299#ifdef CONFIG_WFD300if (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type) {301u32 blnGotWFD = _FALSE;302u8 *wfd_ie;303uint wfd_ielen = 0;304305wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);306if (wfd_ie) {307u8 *wfd_devinfo;308uint wfd_devlen;309310wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);311if (wfd_devinfo) {312if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK) {313/* the first two bits will indicate the WFD device type */314if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_SOURCE) {315/* If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. */316blnGotWFD = _TRUE;317}318} else if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE) {319/* the first two bits will indicate the WFD device type */320if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_PSINK) {321/* If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. */322/* Todo: How about the SSink?! */323blnGotWFD = _TRUE;324}325}326}327}328329if (blnGotWFD == _FALSE)330return _FALSE;331}332#endif /* CONFIG_WFD */333334#endif /* CONFIG_P2P */335return _TRUE;336}337static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,338struct iw_request_info *info, struct wlan_network *pnetwork,339char *start, char *stop, struct iw_event *iwe)340{341/* AP MAC address */342iwe->cmd = SIOCGIWAP;343iwe->u.ap_addr.sa_family = ARPHRD_ETHER;344345_rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);346start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);347return start;348}349static inline char *iwe_stream_essid_proess(_adapter *padapter,350struct iw_request_info *info, struct wlan_network *pnetwork,351char *start, char *stop, struct iw_event *iwe)352{353354/* Add the ESSID */355iwe->cmd = SIOCGIWESSID;356iwe->u.data.flags = 1;357iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);358start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);359return start;360}361362static inline char *iwe_stream_chan_process(_adapter *padapter,363struct iw_request_info *info, struct wlan_network *pnetwork,364char *start, char *stop, struct iw_event *iwe)365{366if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig>14*/)367pnetwork->network.Configuration.DSConfig = 1;368369/* Add frequency/channel */370iwe->cmd = SIOCGIWFREQ;371iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;372iwe->u.freq.e = 1;373iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;374start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);375return start;376}377static inline char *iwe_stream_mode_process(_adapter *padapter,378struct iw_request_info *info, struct wlan_network *pnetwork,379char *start, char *stop, struct iw_event *iwe, u16 cap)380{381/* Add mode */382if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {383iwe->cmd = SIOCGIWMODE;384if (cap & WLAN_CAPABILITY_BSS)385iwe->u.mode = IW_MODE_MASTER;386else387iwe->u.mode = IW_MODE_ADHOC;388389start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);390}391return start;392}393static inline char *iwe_stream_encryption_process(_adapter *padapter,394struct iw_request_info *info, struct wlan_network *pnetwork,395char *start, char *stop, struct iw_event *iwe, u16 cap)396{397398/* Add encryption capability */399iwe->cmd = SIOCGIWENCODE;400if (cap & WLAN_CAPABILITY_PRIVACY)401iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;402else403iwe->u.data.flags = IW_ENCODE_DISABLED;404iwe->u.data.length = 0;405start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);406return start;407408}409410static inline char *iwe_stream_protocol_process(_adapter *padapter,411struct iw_request_info *info, struct wlan_network *pnetwork,412char *start, char *stop, struct iw_event *iwe)413{414u16 ht_cap = _FALSE, vht_cap = _FALSE;415u32 ht_ielen = 0, vht_ielen = 0;416char *p;417u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request */418419#ifdef CONFIG_80211N_HT420/* parsing HT_CAP_IE */421if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {422p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);423if (p && ht_ielen > 0)424ht_cap = _TRUE;425}426#endif427428#ifdef CONFIG_80211AC_VHT429/* parsing VHT_CAP_IE */430if(padapter->registrypriv.wireless_mode & WIRELESS_11AC) {431p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);432if (p && vht_ielen > 0)433vht_cap = _TRUE;434}435#endif436/* Add the protocol name */437iwe->cmd = SIOCGIWNAME;438if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {439if (ht_cap == _TRUE)440snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");441else442snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");443} else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {444if (ht_cap == _TRUE)445snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");446else447snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");448} else {449if (pnetwork->network.Configuration.DSConfig > 14) {450#ifdef CONFIG_80211AC_VHT451if (vht_cap == _TRUE)452snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");453else454#endif455{456if (ht_cap == _TRUE)457snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");458else459snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");460}461} else {462if (ht_cap == _TRUE)463snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");464else465snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");466}467}468start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);469return start;470}471472static inline char *iwe_stream_rate_process(_adapter *padapter,473struct iw_request_info *info, struct wlan_network *pnetwork,474char *start, char *stop, struct iw_event *iwe)475{476u32 ht_ielen = 0, vht_ielen = 0;477char *p;478u16 max_rate = 0, rate, ht_cap = _FALSE, vht_cap = _FALSE;479u32 i = 0;480u8 bw_40MHz = 0, short_GI = 0, bw_160MHz = 0, vht_highest_rate = 0;481u16 mcs_rate = 0, vht_data_rate = 0;482char custom[MAX_CUSTOM_LEN] = {0};483u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request */484485/* parsing HT_CAP_IE */486if(is_supported_ht(padapter->registrypriv.wireless_mode)) {487p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);488if (p && ht_ielen > 0) {489struct rtw_ieee80211_ht_cap *pht_capie;490ht_cap = _TRUE;491pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);492_rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);493bw_40MHz = (pht_capie->cap_info & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;494short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;495}496}497#ifdef CONFIG_80211AC_VHT498/* parsing VHT_CAP_IE */499if(padapter->registrypriv.wireless_mode & WIRELESS_11AC){500p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);501if (p && vht_ielen > 0) {502u8 mcs_map[2];503504vht_cap = _TRUE;505bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p + 2);506if (bw_160MHz)507short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p + 2);508else509short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p + 2);510511_rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p + 2), 2);512513vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);514vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);515}516}517#endif518519/*Add basic and extended rates */520p = custom;521p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");522while (pnetwork->network.SupportedRates[i] != 0) {523rate = pnetwork->network.SupportedRates[i] & 0x7F;524if (rate > max_rate)525max_rate = rate;526p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),527"%d%s ", rate >> 1, (rate & 1) ? ".5" : "");528i++;529}530#ifdef CONFIG_80211AC_VHT531if (vht_cap == _TRUE)532max_rate = vht_data_rate;533else534#endif535if (ht_cap == _TRUE) {536if (mcs_rate & 0x8000) /* MCS15 */537max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);538539else if (mcs_rate & 0x0080) /* MCS7 */540max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);541else { /* default MCS7 */542/* RTW_INFO("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); */543max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);544}545546max_rate = max_rate * 2; /* Mbps/2; */547}548549iwe->cmd = SIOCGIWRATE;550iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;551iwe->u.bitrate.value = max_rate * 500000;552start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);553return start ;554}555556static inline char *iwe_stream_wpa_wpa2_process(_adapter *padapter,557struct iw_request_info *info, struct wlan_network *pnetwork,558char *start, char *stop, struct iw_event *iwe)559{560int buf_size = MAX_WPA_IE_LEN * 2;561/* u8 pbuf[buf_size]={0}; */562u8 *pbuf = rtw_zmalloc(buf_size);563564u8 wpa_ie[255] = {0}, rsn_ie[255] = {0};565u16 i, wpa_len = 0, rsn_len = 0;566u8 *p;567sint out_len = 0;568569570if (pbuf) {571p = pbuf;572573/* parsing WPA/WPA2 IE */574if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */575out_len = rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);576577if (wpa_len > 0) {578579_rtw_memset(pbuf, 0, buf_size);580p += sprintf(p, "wpa_ie=");581for (i = 0; i < wpa_len; i++)582p += sprintf(p, "%02x", wpa_ie[i]);583584if (wpa_len > 100) {585printk("-----------------Len %d----------------\n", wpa_len);586for (i = 0; i < wpa_len; i++)587printk("%02x ", wpa_ie[i]);588printk("\n");589printk("-----------------Len %d----------------\n", wpa_len);590}591592_rtw_memset(iwe, 0, sizeof(*iwe));593iwe->cmd = IWEVCUSTOM;594iwe->u.data.length = strlen(pbuf);595start = iwe_stream_add_point(info, start, stop, iwe, pbuf);596597_rtw_memset(iwe, 0, sizeof(*iwe));598iwe->cmd = IWEVGENIE;599iwe->u.data.length = wpa_len;600start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);601}602if (rsn_len > 0) {603604_rtw_memset(pbuf, 0, buf_size);605p += sprintf(p, "rsn_ie=");606for (i = 0; i < rsn_len; i++)607p += sprintf(p, "%02x", rsn_ie[i]);608_rtw_memset(iwe, 0, sizeof(*iwe));609iwe->cmd = IWEVCUSTOM;610iwe->u.data.length = strlen(pbuf);611start = iwe_stream_add_point(info, start, stop, iwe, pbuf);612613_rtw_memset(iwe, 0, sizeof(*iwe));614iwe->cmd = IWEVGENIE;615iwe->u.data.length = rsn_len;616start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);617}618}619620rtw_mfree(pbuf, buf_size);621}622return start;623}624625static inline char *iwe_stream_wps_process(_adapter *padapter,626struct iw_request_info *info, struct wlan_network *pnetwork,627char *start, char *stop, struct iw_event *iwe)628{629/* parsing WPS IE */630uint cnt = 0, total_ielen;631u8 *wpsie_ptr = NULL;632uint wps_ielen = 0;633u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);634635u8 *ie_ptr = pnetwork->network.IEs + ie_offset;636total_ielen = pnetwork->network.IELength - ie_offset;637638if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) { /* Probe Request */639ie_ptr = pnetwork->network.IEs;640total_ielen = pnetwork->network.IELength;641} else { /* Beacon or Probe Respones */642ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;643total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;644}645while (cnt < total_ielen) {646if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {647wpsie_ptr = &ie_ptr[cnt];648iwe->cmd = IWEVGENIE;649iwe->u.data.length = (u16)wps_ielen;650start = iwe_stream_add_point(info, start, stop, iwe, wpsie_ptr);651}652cnt += ie_ptr[cnt + 1] + 2; /* goto next */653}654return start;655}656657static inline char *iwe_stream_wapi_process(_adapter *padapter,658struct iw_request_info *info, struct wlan_network *pnetwork,659char *start, char *stop, struct iw_event *iwe)660{661#ifdef CONFIG_WAPI_SUPPORT662char *p;663664if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */665sint out_len_wapi = 0;666/* here use static for stack size */667static u8 buf_wapi[MAX_WAPI_IE_LEN * 2] = {0};668static u8 wapi_ie[MAX_WAPI_IE_LEN] = {0};669u16 wapi_len = 0;670u16 i;671672out_len_wapi = rtw_get_wapi_ie(pnetwork->network.IEs , pnetwork->network.IELength, wapi_ie, &wapi_len);673674RTW_INFO("rtw_wx_get_scan: %s ", pnetwork->network.Ssid.Ssid);675RTW_INFO("rtw_wx_get_scan: ssid = %d ", wapi_len);676677678if (wapi_len > 0) {679p = buf_wapi;680/* _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2); */681p += sprintf(p, "wapi_ie=");682for (i = 0; i < wapi_len; i++)683p += sprintf(p, "%02x", wapi_ie[i]);684685_rtw_memset(iwe, 0, sizeof(*iwe));686iwe->cmd = IWEVCUSTOM;687iwe->u.data.length = strlen(buf_wapi);688start = iwe_stream_add_point(info, start, stop, iwe, buf_wapi);689690_rtw_memset(iwe, 0, sizeof(*iwe));691iwe->cmd = IWEVGENIE;692iwe->u.data.length = wapi_len;693start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);694}695}696#endif/* #ifdef CONFIG_WAPI_SUPPORT */697return start;698}699700static inline char *iwe_stream_rssi_process(_adapter *padapter,701struct iw_request_info *info, struct wlan_network *pnetwork,702char *start, char *stop, struct iw_event *iwe)703{704u8 ss, sq;705struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);706#ifdef CONFIG_BACKGROUND_NOISE_MONITOR707s16 noise = 0;708#endif709710/* Add quality statistics */711iwe->cmd = IWEVQUAL;712iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED713#ifdef CONFIG_BACKGROUND_NOISE_MONITOR714| IW_QUAL_NOISE_UPDATED715#else716| IW_QUAL_NOISE_INVALID717#endif718#ifdef CONFIG_SIGNAL_DISPLAY_DBM719| IW_QUAL_DBM720#endif721;722723if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&724is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {725ss = padapter->recvpriv.signal_strength;726sq = padapter->recvpriv.signal_qual;727} else {728ss = pnetwork->network.PhyInfo.SignalStrength;729sq = pnetwork->network.PhyInfo.SignalQuality;730}731732733#ifdef CONFIG_SIGNAL_DISPLAY_DBM734iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */735#else736iwe->u.qual.level = (u8)ss; /* % */737#endif738739iwe->u.qual.qual = (u8)sq; /* signal quality */740741#ifdef CONFIG_PLATFORM_ROCKCHIPS742iwe->u.qual.noise = -100; /* noise level suggest by zhf@rockchips */743#else744#ifdef CONFIG_BACKGROUND_NOISE_MONITOR745if (IS_NM_ENABLE(padapter)) {746noise = rtw_noise_query_by_chan_num(padapter, pnetwork->network.Configuration.DSConfig);747#ifndef CONFIG_SIGNAL_DISPLAY_DBM748noise = translate_dbm_to_percentage(noise);/*percentage*/749#endif750iwe->u.qual.noise = noise;751}752#else753iwe->u.qual.noise = 0; /* noise level */754#endif755#endif /* CONFIG_PLATFORM_ROCKCHIPS */756757/* RTW_INFO("iqual=%d, ilevel=%d, inoise=%d, iupdated=%d\n", iwe.u.qual.qual, iwe.u.qual.level , iwe.u.qual.noise, iwe.u.qual.updated); */758759start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);760return start;761}762763static inline char *iwe_stream_net_rsv_process(_adapter *padapter,764struct iw_request_info *info, struct wlan_network *pnetwork,765char *start, char *stop, struct iw_event *iwe)766{767u8 buf[32] = {0};768u8 *p, *pos;769p = buf;770pos = pnetwork->network.Reserved;771772p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);773_rtw_memset(iwe, 0, sizeof(*iwe));774iwe->cmd = IWEVCUSTOM;775iwe->u.data.length = strlen(buf);776start = iwe_stream_add_point(info, start, stop, iwe, buf);777return start;778}779780static char *translate_scan(_adapter *padapter,781struct iw_request_info *info, struct wlan_network *pnetwork,782char *start, char *stop)783{784struct iw_event iwe;785u16 cap = 0;786_rtw_memset(&iwe, 0, sizeof(iwe));787788if (_FALSE == search_p2p_wfd_ie(padapter, info, pnetwork, start, stop))789return start;790791start = iwe_stream_mac_addr_proess(padapter, info, pnetwork, start, stop, &iwe);792start = iwe_stream_essid_proess(padapter, info, pnetwork, start, stop, &iwe);793start = iwe_stream_protocol_process(padapter, info, pnetwork, start, stop, &iwe);794if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) /* Probe Request */795cap = 0;796else {797_rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);798cap = le16_to_cpu(cap);799}800801start = iwe_stream_mode_process(padapter, info, pnetwork, start, stop, &iwe, cap);802start = iwe_stream_chan_process(padapter, info, pnetwork, start, stop, &iwe);803start = iwe_stream_encryption_process(padapter, info, pnetwork, start, stop, &iwe, cap);804start = iwe_stream_rate_process(padapter, info, pnetwork, start, stop, &iwe);805start = iwe_stream_wpa_wpa2_process(padapter, info, pnetwork, start, stop, &iwe);806start = iwe_stream_wps_process(padapter, info, pnetwork, start, stop, &iwe);807start = iwe_stream_wapi_process(padapter, info, pnetwork, start, stop, &iwe);808start = iwe_stream_rssi_process(padapter, info, pnetwork, start, stop, &iwe);809start = iwe_stream_net_rsv_process(padapter, info, pnetwork, start, stop, &iwe);810811return start;812}813814static int wpa_set_auth_algs(struct net_device *dev, u32 value)815{816_adapter *padapter = (_adapter *) rtw_netdev_priv(dev);817int ret = 0;818819if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {820RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);821padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;822padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;823padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;824} else if (value & AUTH_ALG_SHARED_KEY) {825RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);826padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;827828#ifdef CONFIG_PLATFORM_MT53XX829padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;830padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;831#else832padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;833padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;834#endif835} else if (value & AUTH_ALG_OPEN_SYSTEM) {836RTW_INFO("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");837/* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */838if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {839#ifdef CONFIG_PLATFORM_MT53XX840padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;841padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;842#else843padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;844padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;845#endif846}847848} else if (value & AUTH_ALG_LEAP)849RTW_INFO("wpa_set_auth_algs, AUTH_ALG_LEAP\n");850else {851RTW_INFO("wpa_set_auth_algs, error!\n");852ret = -EINVAL;853}854855return ret;856857}858859static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)860{861int ret = 0;862u32 wep_key_idx, wep_key_len;863_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);864struct mlme_priv *pmlmepriv = &padapter->mlmepriv;865struct security_priv *psecuritypriv = &padapter->securitypriv;866#ifdef CONFIG_P2P867struct wifidirect_info *pwdinfo = &padapter->wdinfo;868#endif /* CONFIG_P2P */869870871param->u.crypt.err = 0;872param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';873874if (param_len < (u32)((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {875ret = -EINVAL;876goto exit;877}878879if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&880param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&881param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {882883if (param->u.crypt.idx >= WEP_KEYS884#ifdef CONFIG_IEEE80211W885&& param->u.crypt.idx > BIP_MAX_KEYID886#endif /* CONFIG_IEEE80211W */887) {888ret = -EINVAL;889goto exit;890}891} else {892#ifdef CONFIG_WAPI_SUPPORT893if (strcmp(param->u.crypt.alg, "SMS4"))894#endif895{896ret = -EINVAL;897goto exit;898}899}900901if (strcmp(param->u.crypt.alg, "WEP") == 0) {902RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");903904wep_key_idx = param->u.crypt.idx;905wep_key_len = param->u.crypt.key_len;906907if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {908ret = -EINVAL;909goto exit;910}911912if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {913/* wep default key has not been set, so use this key index as default key.*/914915wep_key_len = wep_key_len <= 5 ? 5 : 13;916917psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;918psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;919psecuritypriv->dot118021XGrpPrivacy = _WEP40_;920921if (wep_key_len == 13) {922psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;923psecuritypriv->dot118021XGrpPrivacy = _WEP104_;924}925926psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;927}928929_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);930931psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;932933psecuritypriv->key_mask |= BIT(wep_key_idx);934935padapter->mlmeextpriv.mlmext_info.key_index = wep_key_idx;936goto exit;937}938939if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */940struct sta_info *psta, *pbcmc_sta;941struct sta_priv *pstapriv = &padapter->stapriv;942943if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */944psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));945if (psta == NULL) {946/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */947} else {948/* Jeff: don't disable ieee8021x_blocked while clearing key */949if (strcmp(param->u.crypt.alg, "none") != 0)950psta->ieee8021x_blocked = _FALSE;951952if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||953(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))954psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;955956if (param->u.crypt.set_tx == 1) { /* pairwise key */957RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n"958, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);959_rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));960if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */961_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);962_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);963padapter->securitypriv.busetkipkey = _FALSE;964}965psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);966psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);967psta->bpairwise_key_installed = _TRUE;968rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);969970} else { /* group key */971if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {972RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"973, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);974_rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,975(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));976/* only TKIP group key need to install this */977if (param->u.crypt.key_len > 16) {978_rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);979_rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);980}981padapter->securitypriv.binstallGrpkey = _TRUE;982if (param->u.crypt.idx < 4)983_rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8);984padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;985rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);986987#ifdef CONFIG_IEEE80211W988} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {989RTW_INFO(FUNC_ADPT_FMT" set IGTK idx:%u, len:%u\n"990, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);991_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,992(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));993psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;994psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);995psecuritypriv->binstallBIPkey = _TRUE;996#endif /* CONFIG_IEEE80211W */997998}9991000#ifdef CONFIG_P2P1001if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))1002rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);1003#endif /* CONFIG_P2P */10041005/* WPA/WPA2 key-handshake has completed */1006clr_fwstate(pmlmepriv, WIFI_UNDER_KEY_HANDSHAKE);1007}1008}10091010pbcmc_sta = rtw_get_bcmc_stainfo(padapter);1011if (pbcmc_sta == NULL) {1012/* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */1013} else {1014/* Jeff: don't disable ieee8021x_blocked while clearing key */1015if (strcmp(param->u.crypt.alg, "none") != 0)1016pbcmc_sta->ieee8021x_blocked = _FALSE;10171018if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||1019(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))1020pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;1021}1022} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */1023}1024}10251026#ifdef CONFIG_WAPI_SUPPORT1027if (strcmp(param->u.crypt.alg, "SMS4") == 0)1028rtw_wapi_set_set_encryption(padapter, param);1029#endif10301031exit:103210331034return ret;1035}10361037static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)1038{1039u8 *buf = NULL, *pos = NULL;1040int group_cipher = 0, pairwise_cipher = 0;1041u8 mfp_opt = MFP_NO;1042int ret = 0;1043u8 null_addr[] = {0, 0, 0, 0, 0, 0};1044#ifdef CONFIG_P2P1045struct wifidirect_info *pwdinfo = &padapter->wdinfo;1046#endif /* CONFIG_P2P */10471048if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {1049_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);1050if (pie == NULL)1051return ret;1052else1053return -EINVAL;1054}10551056if (ielen) {1057buf = rtw_zmalloc(ielen);1058if (buf == NULL) {1059ret = -ENOMEM;1060goto exit;1061}10621063_rtw_memcpy(buf, pie , ielen);10641065/* dump */1066{1067int i;1068RTW_INFO("\n wpa_ie(length:%d):\n", ielen);1069for (i = 0; i < ielen; i = i + 8)1070RTW_INFO("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);1071}10721073pos = buf;1074if (ielen < RSN_HEADER_LEN) {1075ret = -1;1076goto exit;1077}10781079if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {1080padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;1081padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;1082_rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);1083}10841085if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) {1086padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;1087padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;1088_rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);1089}10901091if (group_cipher == 0)1092group_cipher = WPA_CIPHER_NONE;1093if (pairwise_cipher == 0)1094pairwise_cipher = WPA_CIPHER_NONE;10951096switch (group_cipher) {1097case WPA_CIPHER_NONE:1098padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;1099padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;1100break;1101case WPA_CIPHER_WEP40:1102padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;1103padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;1104break;1105case WPA_CIPHER_TKIP:1106padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;1107padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;1108break;1109case WPA_CIPHER_CCMP:1110padapter->securitypriv.dot118021XGrpPrivacy = _AES_;1111padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;1112break;1113case WPA_CIPHER_WEP104:1114padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;1115padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;1116break;1117}11181119switch (pairwise_cipher) {1120case WPA_CIPHER_NONE:1121padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;1122padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;1123break;1124case WPA_CIPHER_WEP40:1125padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;1126padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;1127break;1128case WPA_CIPHER_TKIP:1129padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;1130padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;1131break;1132case WPA_CIPHER_CCMP:1133padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;1134padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;1135break;1136case WPA_CIPHER_WEP104:1137padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;1138padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;1139break;1140}11411142if (mfp_opt == MFP_INVALID) {1143RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));1144ret = -EINVAL;1145goto exit;1146}1147padapter->securitypriv.mfp_opt = mfp_opt;11481149_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);1150{/* set wps_ie */1151u16 cnt = 0;1152u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};11531154while (cnt < ielen) {1155eid = buf[cnt];11561157if ((eid == _VENDOR_SPECIFIC_IE_) && (_rtw_memcmp(&buf[cnt + 2], wps_oui, 4) == _TRUE)) {1158RTW_INFO("SET WPS_IE\n");11591160padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < MAX_WPS_IE_LEN) ? (buf[cnt + 1] + 2) : MAX_WPS_IE_LEN;11611162_rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);11631164set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);11651166#ifdef CONFIG_P2P1167if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))1168rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);1169#endif /* CONFIG_P2P */1170cnt += buf[cnt + 1] + 2;11711172break;1173} else {1174cnt += buf[cnt + 1] + 2; /* goto next */1175}1176}1177}1178}11791180/* TKIP and AES disallow multicast packets until installing group key */1181if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_1182|| padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_1183|| padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)1184/* WPS open need to enable multicast1185* || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */1186rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);118711881189exit:11901191if (buf)1192rtw_mfree(buf, ielen);11931194return ret;1195}11961197static int rtw_wx_get_name(struct net_device *dev,1198struct iw_request_info *info,1199union iwreq_data *wrqu, char *extra)1200{1201_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1202u32 ht_ielen = 0;1203char *p;1204u8 ht_cap = _FALSE, vht_cap = _FALSE;1205struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);1206WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;1207NDIS_802_11_RATES_EX *prates = NULL;1208120912101211if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {1212/* parsing HT_CAP_IE */1213if( is_supported_ht(padapter->registrypriv.wireless_mode)&&(padapter->registrypriv.ht_enable)) {1214p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);1215if (p && ht_ielen > 0 )1216ht_cap = _TRUE;1217}1218#ifdef CONFIG_80211AC_VHT1219if ((padapter->registrypriv.wireless_mode & WIRELESS_11AC) &&1220(pmlmepriv->vhtpriv.vht_option == _TRUE))1221vht_cap = _TRUE;1222#endif12231224prates = &pcur_bss->SupportedRates;1225if (rtw_is_cckratesonly_included((u8 *)prates) == _TRUE) {1226if (ht_cap == _TRUE)1227snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");1228else1229snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");1230} else if ((rtw_is_cckrates_included((u8 *)prates)) == _TRUE) {1231if (ht_cap == _TRUE)1232snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");1233else {1234if(padapter->registrypriv.wireless_mode & WIRELESS_11G)1235snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");1236else1237snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");1238}1239} else {1240if (pcur_bss->Configuration.DSConfig > 14) {1241#ifdef CONFIG_80211AC_VHT1242if (vht_cap == _TRUE)1243snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");1244else1245#endif1246{1247if (ht_cap == _TRUE)1248snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");1249else1250snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");1251}1252} else {1253if (ht_cap == _TRUE)1254snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");1255else1256snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");1257}1258}1259} else {1260/* prates = &padapter->registrypriv.dev_network.SupportedRates; */1261/* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */1262snprintf(wrqu->name, IFNAMSIZ, "unassociated");1263}126412651266return 0;1267}12681269static int rtw_wx_set_freq(struct net_device *dev,1270struct iw_request_info *info,1271union iwreq_data *wrqu, char *extra)1272{12731274_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1275int exp = 1, freq = 0, div = 0;12761277rtw_ps_deny(padapter, PS_DENY_IOCTL);1278if (rtw_pwr_wakeup(padapter) == _FALSE)1279goto exit;1280if (wrqu->freq.m <= 1000) {1281if (wrqu->freq.flags == IW_FREQ_AUTO) {1282if (rtw_chset_search_ch(adapter_to_chset(padapter), wrqu->freq.m) > 0) {1283padapter->mlmeextpriv.cur_channel = wrqu->freq.m;1284RTW_INFO("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m);1285} else {1286padapter->mlmeextpriv.cur_channel = 1;1287RTW_INFO("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__);1288}1289} else {1290padapter->mlmeextpriv.cur_channel = wrqu->freq.m;1291RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);1292}1293} else {1294while (wrqu->freq.e) {1295exp *= 10;1296wrqu->freq.e--;1297}12981299freq = wrqu->freq.m;13001301while (!(freq % 10)) {1302freq /= 10;1303exp *= 10;1304}13051306/* freq unit is MHz here */1307div = 1000000 / exp;13081309if (div)1310freq /= div;1311else {1312div = exp / 1000000;1313freq *= div;1314}13151316/* If freq is invalid, rtw_freq2ch() will return channel 1 */1317padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);1318RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);1319}1320set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);1321exit:1322rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);13231324return 0;1325}13261327static int rtw_wx_get_freq(struct net_device *dev,1328struct iw_request_info *info,1329union iwreq_data *wrqu, char *extra)1330{1331_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1332struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);1333WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;13341335if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {13361337wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;1338wrqu->freq.e = 1;1339wrqu->freq.i = pcur_bss->Configuration.DSConfig;13401341} else {1342wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;1343wrqu->freq.e = 1;1344wrqu->freq.i = padapter->mlmeextpriv.cur_channel;1345}13461347return 0;1348}13491350static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,1351union iwreq_data *wrqu, char *b)1352{1353_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1354struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);1355NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;1356int ret = 0;135713581359if (_FAIL == rtw_pwr_wakeup(padapter)) {1360ret = -EPERM;1361goto exit;1362}13631364if (!rtw_is_hw_init_completed(padapter)) {1365ret = -EPERM;1366goto exit;1367}13681369/* initial default type */1370dev->type = ARPHRD_ETHER;13711372if (wrqu->mode == IW_MODE_MONITOR) {1373rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE);1374LeaveAllPowerSaveMode(padapter);1375} else {1376rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE);1377}13781379switch (wrqu->mode) {1380case IW_MODE_MONITOR:1381networkType = Ndis802_11Monitor;1382#if 01383dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */1384#endif13851386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))1387dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */1388RTW_INFO("set_mode = IW_MODE_MONITOR\n");1389#else1390RTW_INFO("kernel version < 2.6.24 not support IW_MODE_MONITOR\n");1391#endif1392break;13931394case IW_MODE_AUTO:1395networkType = Ndis802_11AutoUnknown;1396RTW_INFO("set_mode = IW_MODE_AUTO\n");1397break;1398case IW_MODE_ADHOC:1399networkType = Ndis802_11IBSS;1400RTW_INFO("set_mode = IW_MODE_ADHOC\n");1401break;1402case IW_MODE_MASTER:1403networkType = Ndis802_11APMode;1404RTW_INFO("set_mode = IW_MODE_MASTER\n");1405break;1406case IW_MODE_INFRA:1407networkType = Ndis802_11Infrastructure;1408RTW_INFO("set_mode = IW_MODE_INFRA\n");1409break;14101411default:1412ret = -EINVAL;;1413goto exit;1414}14151416if (rtw_set_802_11_infrastructure_mode(padapter, networkType, 0) == _FALSE) {14171418ret = -EPERM;1419goto exit;14201421}14221423rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);14241425if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)1426rtw_indicate_connect(padapter);14271428exit:142914301431return ret;14321433}14341435static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,1436union iwreq_data *wrqu, char *b)1437{1438_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1439struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);1440144114421443if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)1444wrqu->mode = IW_MODE_INFRA;1445else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||1446(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))14471448wrqu->mode = IW_MODE_ADHOC;1449else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)1450wrqu->mode = IW_MODE_MASTER;1451else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)1452wrqu->mode = IW_MODE_MONITOR;1453else1454wrqu->mode = IW_MODE_AUTO;145514561457return 0;14581459}146014611462static int rtw_wx_set_pmkid(struct net_device *dev,1463struct iw_request_info *a,1464union iwreq_data *wrqu, char *extra)1465{1466_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1467u8 j, blInserted = _FALSE;1468int intReturn = _FALSE;1469struct security_priv *psecuritypriv = &padapter->securitypriv;1470struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;1471u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };1472u8 strIssueBssid[ETH_ALEN] = { 0x00 };14731474#if 01475struct iw_pmksa {1476__u32 cmd;1477struct sockaddr bssid;1478__u8 pmkid[IW_PMKID_LEN]; /* IW_PMKID_LEN=16 */1479}1480There are the BSSID information in the bssid.sa_data array.1481If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.1482If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID / BSSID to driver.1483If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID / BSSID from driver.1484#endif14851486_rtw_memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);1487if (pPMK->cmd == IW_PMKSA_ADD) {1488RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");1489if (_rtw_memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == _TRUE)1490return intReturn ;1491else1492intReturn = _TRUE;1493blInserted = _FALSE;14941495/* overwrite PMKID */1496for (j = 0 ; j < NUM_PMKID_CACHE; j++) {1497if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {1498/* BSSID is matched, the same AP => rewrite with new PMKID. */14991500RTW_INFO("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");15011502_rtw_memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);1503psecuritypriv->PMKIDList[j].bUsed = _TRUE;1504psecuritypriv->PMKIDIndex = j + 1;1505blInserted = _TRUE;1506break;1507}1508}15091510if (!blInserted) {1511/* Find a new entry */1512RTW_INFO("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",1513psecuritypriv->PMKIDIndex);15141515_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);1516_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);15171518psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;1519psecuritypriv->PMKIDIndex++ ;1520if (psecuritypriv->PMKIDIndex == 16)1521psecuritypriv->PMKIDIndex = 0;1522}1523} else if (pPMK->cmd == IW_PMKSA_REMOVE) {1524RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");1525intReturn = _TRUE;1526for (j = 0 ; j < NUM_PMKID_CACHE; j++) {1527if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {1528/* BSSID is matched, the same AP => Remove this PMKID information and reset it. */1529_rtw_memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);1530psecuritypriv->PMKIDList[j].bUsed = _FALSE;1531break;1532}1533}1534} else if (pPMK->cmd == IW_PMKSA_FLUSH) {1535RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");1536_rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);1537psecuritypriv->PMKIDIndex = 0;1538intReturn = _TRUE;1539}1540return intReturn ;1541}15421543static int rtw_wx_get_sens(struct net_device *dev,1544struct iw_request_info *info,1545union iwreq_data *wrqu, char *extra)1546{1547#ifdef CONFIG_PLATFORM_ROCKCHIPS1548_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1549struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);15501551/*1552* 20110311 Commented by Jeff1553* For rockchip platform's wpa_driver_wext_get_rssi1554*/1555if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {1556/* wrqu->sens.value=-padapter->recvpriv.signal_strength; */1557wrqu->sens.value = -padapter->recvpriv.rssi;1558/* RTW_INFO("%s: %d\n", __FUNCTION__, wrqu->sens.value); */1559wrqu->sens.fixed = 0; /* no auto select */1560} else1561#endif1562{1563wrqu->sens.value = 0;1564wrqu->sens.fixed = 0; /* no auto select */1565wrqu->sens.disabled = 1;1566}1567return 0;1568}15691570static int rtw_wx_get_range(struct net_device *dev,1571struct iw_request_info *info,1572union iwreq_data *wrqu, char *extra)1573{1574struct iw_range *range = (struct iw_range *)extra;1575_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1576struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);1577u16 val;1578int i;1579158015811582wrqu->data.length = sizeof(*range);1583_rtw_memset(range, 0, sizeof(*range));15841585/* Let's try to keep this struct in the same order as in1586* linux/include/wireless.h1587*/15881589/* TODO: See what values we can set, and remove the ones we can't1590* set, or fill them with some default data.1591*/15921593/* ~5 Mb/s real (802.11b) */1594range->throughput = 5 * 1000 * 1000;15951596/* TODO: Not used in 802.11b?1597* range->min_nwid; Minimal NWID we are able to set */1598/* TODO: Not used in 802.11b?1599* range->max_nwid; Maximal NWID we are able to set */16001601/* Old Frequency (backward compat - moved lower ) */1602/* range->old_num_channels;1603* range->old_num_frequency;1604* range->old_freq[6]; Filler to keep "version" at the same offset */16051606/* signal level threshold range */16071608/* Quality of link & SNR stuff */1609/* Quality range (link, level, noise)1610* If the quality is absolute, it will be in the range [0 ; max_qual],1611* if the quality is dBm, it will be in the range [max_qual ; 0].1612* Don't forget that we use 8 bit arithmetics...1613*1614* If percentage range is 0~1001615* Signal strength dbm range logical is -100 ~ 01616* but usually value is -90 ~ -201617*/1618range->max_qual.qual = 100;1619#ifdef CONFIG_SIGNAL_DISPLAY_DBM1620range->max_qual.level = (u8)-100;1621range->max_qual.noise = (u8)-100;1622range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */1623range->max_qual.updated |= IW_QUAL_DBM;1624#else /* !CONFIG_SIGNAL_DISPLAY_DBM */1625/* percent values between 0 and 100. */1626range->max_qual.level = 100;1627range->max_qual.noise = 100;1628range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */1629#endif /* !CONFIG_SIGNAL_DISPLAY_DBM */16301631/* This should contain the average/typical values of the quality1632* indicator. This should be the threshold between a "good" and1633* a "bad" link (example : monitor going from green to orange).1634* Currently, user space apps like quality monitors don't have any1635* way to calibrate the measurement. With this, they can split1636* the range between 0 and max_qual in different quality level1637* (using a geometric subdivision centered on the average).1638* I expect that people doing the user space apps will feedback1639* us on which value we need to put in each driver... */1640range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */1641#ifdef CONFIG_SIGNAL_DISPLAY_DBM1642/* TODO: Find real 'good' to 'bad' threshold value for RSSI */1643range->avg_qual.level = (u8)-70;1644range->avg_qual.noise = 0;1645range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */1646range->avg_qual.updated |= IW_QUAL_DBM;1647#else /* !CONFIG_SIGNAL_DISPLAY_DBM */1648/* TODO: Find real 'good' to 'bad' threshol value for RSSI */1649range->avg_qual.level = 30;1650range->avg_qual.noise = 100;1651range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */1652#endif /* !CONFIG_SIGNAL_DISPLAY_DBM */16531654range->num_bitrates = RATE_COUNT;16551656for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)1657range->bitrate[i] = rtw_rates[i];16581659range->min_frag = MIN_FRAG_THRESHOLD;1660range->max_frag = MAX_FRAG_THRESHOLD;16611662range->pm_capa = 0;16631664range->we_version_compiled = WIRELESS_EXT;1665range->we_version_source = 16;16661667/* range->retry_capa; What retry options are supported1668* range->retry_flags; How to decode max/min retry limit1669* range->r_time_flags; How to decode max/min retry life1670* range->min_retry; Minimal number of retries1671* range->max_retry; Maximal number of retries1672* range->min_r_time; Minimal retry lifetime1673* range->max_r_time; Maximal retry lifetime */16741675for (i = 0, val = 0; i < rfctl->max_chan_nums; i++) {16761677/* Include only legal frequencies for some countries */1678if (rfctl->channel_set[i].ChannelNum != 0) {1679range->freq[val].i = rfctl->channel_set[i].ChannelNum;1680range->freq[val].m = rtw_ch2freq(rfctl->channel_set[i].ChannelNum) * 100000;1681range->freq[val].e = 1;1682val++;1683}16841685if (val == IW_MAX_FREQUENCIES)1686break;1687}16881689range->num_channels = val;1690range->num_frequency = val;16911692/* Commented by Albert 2009/10/131693* The following code will proivde the security capability to network manager.1694* If the driver doesn't provide this capability to network manager,1695* the WPA/WPA2 routers can't be choosen in the network manager. */16961697/*1698#define IW_SCAN_CAPA_NONE 0x001699#define IW_SCAN_CAPA_ESSID 0x011700#define IW_SCAN_CAPA_BSSID 0x021701#define IW_SCAN_CAPA_CHANNEL 0x041702#define IW_SCAN_CAPA_MODE 0x081703#define IW_SCAN_CAPA_RATE 0x101704#define IW_SCAN_CAPA_TYPE 0x201705#define IW_SCAN_CAPA_TIME 0x401706*/17071708#if WIRELESS_EXT > 171709range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |1710IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;1711#endif17121713#ifdef IW_SCAN_CAPA_ESSID /* WIRELESS_EXT > 21 */1714range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID |1715IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;1716#endif1717171817191720return 0;17211722}17231724/* set bssid flow1725* s1. rtw_set_802_11_infrastructure_mode()1726* s2. rtw_set_802_11_authentication_mode()1727* s3. set_802_11_encryption_mode()1728* s4. rtw_set_802_11_bssid() */1729static int rtw_wx_set_wap(struct net_device *dev,1730struct iw_request_info *info,1731union iwreq_data *awrq,1732char *extra)1733{1734_irqL irqL;1735uint ret = 0;1736_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1737struct sockaddr *temp = (struct sockaddr *)awrq;1738struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);1739_list *phead;1740u8 *dst_bssid, *src_bssid;1741_queue *queue = &(pmlmepriv->scanned_queue);1742struct wlan_network *pnetwork = NULL;1743NDIS_802_11_AUTHENTICATION_MODE authmode;17441745/*1746#ifdef CONFIG_CONCURRENT_MODE1747if(padapter->adapter_type > PRIMARY_IFACE)1748{1749ret = -EINVAL;1750goto exit;1751}1752#endif1753*/17541755#ifdef CONFIG_CONCURRENT_MODE1756if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {1757RTW_INFO("set bssid, but buddy_intf is under scanning or linking\n");17581759ret = -EINVAL;17601761goto exit;1762}1763#endif17641765rtw_ps_deny(padapter, PS_DENY_JOIN);1766if (_FAIL == rtw_pwr_wakeup(padapter)) {1767ret = -1;1768goto cancel_ps_deny;1769}17701771if (!padapter->bup) {1772ret = -1;1773goto cancel_ps_deny;1774}177517761777if (temp->sa_family != ARPHRD_ETHER) {1778ret = -EINVAL;1779goto cancel_ps_deny;1780}17811782authmode = padapter->securitypriv.ndisauthtype;1783_enter_critical_bh(&queue->lock, &irqL);1784phead = get_list_head(queue);1785pmlmepriv->pscanned = get_next(phead);17861787while (1) {17881789if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) {1790#if 01791ret = -EINVAL;1792goto cancel_ps_deny;17931794if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {1795rtw_set_802_11_bssid(padapter, temp->sa_data);1796goto cancel_ps_deny;1797} else {1798ret = -EINVAL;1799goto cancel_ps_deny;1800}1801#endif18021803break;1804}18051806pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);18071808pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);18091810dst_bssid = pnetwork->network.MacAddress;18111812src_bssid = temp->sa_data;18131814if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) {1815if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0)) {1816ret = -1;1817_exit_critical_bh(&queue->lock, &irqL);1818goto cancel_ps_deny;1819}18201821break;1822}18231824}1825_exit_critical_bh(&queue->lock, &irqL);18261827rtw_set_802_11_authentication_mode(padapter, authmode);1828/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */1829if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {1830ret = -1;1831goto cancel_ps_deny;1832}18331834cancel_ps_deny:1835rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);18361837#ifdef CONFIG_CONCURRENT_MODE1838exit:1839#endif1840return ret;1841}18421843static int rtw_wx_get_wap(struct net_device *dev,1844struct iw_request_info *info,1845union iwreq_data *wrqu, char *extra)1846{18471848_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1849struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);1850WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;18511852wrqu->ap_addr.sa_family = ARPHRD_ETHER;18531854_rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);1855185618571858if (((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) ||1859((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||1860((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE))18611862_rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);1863else1864_rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);186518661867return 0;18681869}18701871static int rtw_wx_set_mlme(struct net_device *dev,1872struct iw_request_info *info,1873union iwreq_data *wrqu, char *extra)1874{1875#if 01876/* SIOCSIWMLME data */1877struct iw_mlme {1878__u16 cmd; /* IW_MLME_* */1879__u16 reason_code;1880struct sockaddr addr;1881};1882#endif18831884int ret = 0;1885u16 reason;1886_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1887struct iw_mlme *mlme = (struct iw_mlme *) extra;188818891890if (mlme == NULL)1891return -1;18921893RTW_INFO("%s\n", __FUNCTION__);18941895reason = cpu_to_le16(mlme->reason_code);189618971898RTW_INFO("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);189919001901switch (mlme->cmd) {1902case IW_MLME_DEAUTH:1903if (!rtw_set_802_11_disassociate(padapter))1904ret = -1;1905break;19061907case IW_MLME_DISASSOC:1908if (!rtw_set_802_11_disassociate(padapter))1909ret = -1;19101911break;19121913default:1914return -EOPNOTSUPP;1915}1916#ifdef CONFIG_RTW_REPEATER_SON1917rtw_rson_do_disconnect(padapter);1918#endif1919return ret;1920}19211922static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,1923union iwreq_data *wrqu, char *extra)1924{1925u8 _status = _FALSE;1926int ret = 0;1927_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1928/*struct mlme_priv *pmlmepriv = &padapter->mlmepriv;*/1929struct sitesurvey_parm parm;1930u8 ssc_chk;1931#ifdef CONFIG_P2P1932struct wifidirect_info *pwdinfo = &(padapter->wdinfo);1933#endif /* CONFIG_P2P */19341935#ifdef DBG_IOCTL1936RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);1937#endif19381939#if 11940ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);19411942#ifdef CONFIG_DOSCAN_IN_BUSYTRAFFIC1943if ((ssc_chk != SS_ALLOW) && (ssc_chk != SS_DENY_BUSY_TRAFFIC))1944#else1945/* When Busy Traffic, driver do not site survey. So driver return success. */1946/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */1947/* modify by thomas 2011-02-22. */1948if (ssc_chk != SS_ALLOW)1949#endif1950{1951if (ssc_chk == SS_DENY_MP_MODE)1952ret = -EPERM;1953#ifdef DBG_LA_MODE1954else if (ssc_chk == SS_DENY_LA_MODE)1955ret = -EPERM;1956#endif1957else1958indicate_wx_scan_complete_event(padapter);19591960goto exit;1961} else1962RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));19631964rtw_ps_deny(padapter, PS_DENY_SCAN);1965if (_FAIL == rtw_pwr_wakeup(padapter)) {1966ret = -1;1967goto cancel_ps_deny;1968}1969if (!rtw_is_adapter_up(padapter)) {1970ret = -1;1971goto cancel_ps_deny;1972}1973#else19741975#ifdef CONFIG_MP_INCLUDED1976if (rtw_mp_mode_check(padapter)) {1977RTW_INFO("MP mode block Scan request\n");1978ret = -EPERM;1979goto exit;1980}1981#endif1982if (rtw_is_scan_deny(padapter)) {1983indicate_wx_scan_complete_event(padapter);1984goto exit;1985}19861987rtw_ps_deny(padapter, PS_DENY_SCAN);1988if (_FAIL == rtw_pwr_wakeup(padapter)) {1989ret = -1;1990goto cancel_ps_deny;1991}19921993if (!rtw_is_adapter_up(padapter)) {1994ret = -1;1995goto cancel_ps_deny;1996}19971998#ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC1999/* When Busy Traffic, driver do not site survey. So driver return success. */2000/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */2001/* modify by thomas 2011-02-22. */2002if (rtw_mi_busy_traffic_check(padapter, _FALSE)) {2003indicate_wx_scan_complete_event(padapter);2004goto cancel_ps_deny;2005}2006#endif2007#ifdef CONFIG_RTW_REPEATER_SON2008if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {2009RTW_INFO(FUNC_ADPT_FMT" blocking scan for under rson scanning process\n", FUNC_ADPT_ARG(padapter));2010indicate_wx_scan_complete_event(padapter);2011goto cancel_ps_deny;2012}2013#endif2014if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {2015RTW_INFO("AP mode process WPS\n");2016indicate_wx_scan_complete_event(padapter);2017goto cancel_ps_deny;2018}20192020if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {2021indicate_wx_scan_complete_event(padapter);2022goto cancel_ps_deny;2023}20242025#ifdef CONFIG_CONCURRENT_MODE2026if (rtw_mi_buddy_check_fwstate(padapter,2027_FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS)) {20282029indicate_wx_scan_complete_event(padapter);2030goto cancel_ps_deny;2031}2032#endif2033#endif20342035#ifdef CONFIG_P2P2036if (pwdinfo->p2p_state != P2P_STATE_NONE) {2037rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));2038rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);2039rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);2040rtw_free_network_queue(padapter, _TRUE);2041}2042#endif /* CONFIG_P2P */20432044#if WIRELESS_EXT >= 172045if (wrqu->data.length == sizeof(struct iw_scan_req)) {2046struct iw_scan_req *req = (struct iw_scan_req *)extra;20472048if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {2049int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);20502051rtw_init_sitesurvey_parm(padapter, &parm);2052_rtw_memcpy(&parm.ssid[0].Ssid, &req->essid, len);2053parm.ssid[0].SsidLength = len;2054parm.ssid_num = 1;20552056RTW_INFO("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);20572058_status = rtw_set_802_11_bssid_list_scan(padapter, &parm);20592060} else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)2061RTW_INFO("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");20622063} else2064#endif20652066if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE2067&& _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE2068) {2069int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;2070char *pos = extra + WEXT_CSCAN_HEADER_SIZE;2071char section;2072char sec_len;2073int ssid_index = 0;20742075/* RTW_INFO("%s COMBO_SCAN header is recognized\n", __FUNCTION__); */2076rtw_init_sitesurvey_parm(padapter, &parm);20772078while (len >= 1) {2079section = *(pos++);2080len -= 1;20812082switch (section) {2083case WEXT_CSCAN_SSID_SECTION:2084/* RTW_INFO("WEXT_CSCAN_SSID_SECTION\n"); */2085if (len < 1) {2086len = 0;2087break;2088}20892090sec_len = *(pos++);2091len -= 1;20922093if (sec_len > 0 && sec_len <= len) {20942095parm.ssid[ssid_index].SsidLength = sec_len;2096_rtw_memcpy(&parm.ssid[ssid_index].Ssid, pos, sec_len);20972098/* RTW_INFO("%s COMBO_SCAN with specific parm.ssid:%s, %d\n", __FUNCTION__ */2099/* , parm.ssid[ssid_index].Ssid, parm.ssid[ssid_index].SsidLength); */2100ssid_index++;2101}21022103pos += sec_len;2104len -= sec_len;2105break;210621072108case WEXT_CSCAN_CHANNEL_SECTION:2109/* RTW_INFO("WEXT_CSCAN_CHANNEL_SECTION\n"); */2110pos += 1;2111len -= 1;2112break;2113case WEXT_CSCAN_ACTV_DWELL_SECTION:2114/* RTW_INFO("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); */2115pos += 2;2116len -= 2;2117break;2118case WEXT_CSCAN_PASV_DWELL_SECTION:2119/* RTW_INFO("WEXT_CSCAN_PASV_DWELL_SECTION\n"); */2120pos += 2;2121len -= 2;2122break;2123case WEXT_CSCAN_HOME_DWELL_SECTION:2124/* RTW_INFO("WEXT_CSCAN_HOME_DWELL_SECTION\n"); */2125pos += 2;2126len -= 2;2127break;2128case WEXT_CSCAN_TYPE_SECTION:2129/* RTW_INFO("WEXT_CSCAN_TYPE_SECTION\n"); */2130pos += 1;2131len -= 1;2132break;2133#if 02134case WEXT_CSCAN_NPROBE_SECTION:2135RTW_INFO("WEXT_CSCAN_NPROBE_SECTION\n");2136break;2137#endif21382139default:2140/* RTW_INFO("Unknown CSCAN section %c\n", section); */2141len = 0; /* stop parsing */2142}2143/* RTW_INFO("len:%d\n", len); */21442145}2146parm.ssid_num = ssid_index;21472148/* jeff: it has still some scan paramater to parse, we only do this now... */2149_status = rtw_set_802_11_bssid_list_scan(padapter, &parm);21502151} else21522153_status = rtw_set_802_11_bssid_list_scan(padapter, NULL);21542155if (_status == _FALSE)2156ret = -1;21572158cancel_ps_deny:2159rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);21602161exit:2162#ifdef DBG_IOCTL2163RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);2164#endif21652166return ret;2167}21682169static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,2170union iwreq_data *wrqu, char *extra)2171{2172_irqL irqL;2173_list *plist, *phead;2174_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2175struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);2176RT_CHANNEL_INFO *chset = rfctl->channel_set;2177struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);2178_queue *queue = &(pmlmepriv->scanned_queue);2179struct wlan_network *pnetwork = NULL;2180char *ev = extra;2181char *stop = ev + wrqu->data.length;2182u32 ret = 0;2183u32 wait_for_surveydone;2184sint wait_status;2185u8 ch;21862187#ifdef CONFIG_P2P2188struct wifidirect_info *pwdinfo = &padapter->wdinfo;2189#endif /* CONFIG_P2P */219021912192#ifdef DBG_IOCTL2193RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);2194#endif21952196if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) {2197ret = -EINVAL;2198goto exit;2199}22002201#ifdef CONFIG_P2P2202if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))2203wait_for_surveydone = 200;2204else {2205/* P2P is disabled */2206wait_for_surveydone = 100;2207}2208#else2209{2210wait_for_surveydone = 100;2211}2212#endif /* CONFIG_P2P */22132214#if 1 /* Wireless Extension use EAGAIN to try */2215wait_status = _FW_UNDER_SURVEY2216#ifndef CONFIG_ANDROID2217| _FW_UNDER_LINKING2218#endif2219;22202221while (check_fwstate(pmlmepriv, wait_status) == _TRUE)2222return -EAGAIN;2223#else2224wait_status = _FW_UNDER_SURVEY2225#ifndef CONFIG_ANDROID2226| _FW_UNDER_LINKING2227#endif2228;22292230while (check_fwstate(pmlmepriv, wait_status) == _TRUE) {2231rtw_msleep_os(30);2232cnt++;2233if (cnt > wait_for_surveydone)2234break;2235}2236#endif2237_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);22382239phead = get_list_head(queue);2240plist = get_next(phead);22412242while (1) {2243if (rtw_end_of_queue_search(phead, plist) == _TRUE)2244break;22452246if ((stop - ev) < SCAN_ITEM_SIZE) {2247if(wrqu->data.length == MAX_SCAN_BUFFER_LEN){ /*max buffer len defined by iwlist*/2248ret = 0;2249RTW_INFO("%s: Scan results incomplete\n", __FUNCTION__);2250break;2251}2252ret = -E2BIG;2253break;2254}22552256pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);2257ch = pnetwork->network.Configuration.DSConfig;22582259/* report network only if the current channel set contains the channel to which this network belongs */2260if (rtw_chset_search_ch(chset, ch) >= 02261&& rtw_mlme_band_check(padapter, ch) == _TRUE2262&& _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))2263&& (!IS_DFS_SLAVE_WITH_RD(rfctl)2264|| rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl))2265|| !rtw_chset_is_ch_non_ocp(chset, ch))2266)2267ev = translate_scan(padapter, a, pnetwork, ev, stop);22682269plist = get_next(plist);22702271}22722273_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);22742275wrqu->data.length = ev - extra;2276wrqu->data.flags = 0;22772278exit:227922802281#ifdef DBG_IOCTL2282RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);2283#endif22842285return ret ;22862287}22882289/* set ssid flow2290* s1. rtw_set_802_11_infrastructure_mode()2291* s2. set_802_11_authenticaion_mode()2292* s3. set_802_11_encryption_mode()2293* s4. rtw_set_802_11_ssid() */2294static int rtw_wx_set_essid(struct net_device *dev,2295struct iw_request_info *a,2296union iwreq_data *wrqu, char *extra)2297{2298_irqL irqL;2299_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2300struct mlme_priv *pmlmepriv = &padapter->mlmepriv;2301_queue *queue = &pmlmepriv->scanned_queue;2302_list *phead;2303struct wlan_network *pnetwork = NULL;2304NDIS_802_11_AUTHENTICATION_MODE authmode;2305NDIS_802_11_SSID ndis_ssid;2306u8 *dst_ssid, *src_ssid;23072308uint ret = 0, len;230923102311#ifdef DBG_IOCTL2312RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);2313#endif2314#ifdef CONFIG_WEXT_DONT_JOIN_BYSSID2315RTW_INFO("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);2316return -EPERM;2317#endif23182319#if WIRELESS_EXT <= 202320if ((wrqu->essid.length - 1) > IW_ESSID_MAX_SIZE) {2321#else2322if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {2323#endif2324ret = -E2BIG;2325goto exit;2326}2327232823292330rtw_ps_deny(padapter, PS_DENY_JOIN);2331if (_FAIL == rtw_pwr_wakeup(padapter)) {2332ret = -1;2333goto cancel_ps_deny;2334}23352336if (!padapter->bup) {2337ret = -1;2338goto cancel_ps_deny;2339}23402341if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {2342ret = -1;2343goto cancel_ps_deny;2344}23452346#ifdef CONFIG_CONCURRENT_MODE2347if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {2348RTW_INFO("set ssid, but buddy_intf is under scanning or linking\n");2349ret = -EINVAL;2350goto cancel_ps_deny;2351}2352#endif2353authmode = padapter->securitypriv.ndisauthtype;2354RTW_INFO("=>%s\n", __FUNCTION__);2355if (wrqu->essid.flags && wrqu->essid.length) {2356/* Commented by Albert 20100519 */2357/* We got the codes in "set_info" function of iwconfig source code. */2358/* ========================================= */2359/* wrq.u.essid.length = strlen(essid) + 1; */2360/* if(we_kernel_version > 20) */2361/* wrq.u.essid.length--; */2362/* ========================================= */2363/* That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. */2364#if WIRELESS_EXT <= 202365len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE;2366#else2367len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;2368#endif23692370if (wrqu->essid.length != 33)2371RTW_INFO("ssid=%s, len=%d\n", extra, wrqu->essid.length);23722373_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));2374ndis_ssid.SsidLength = len;2375_rtw_memcpy(ndis_ssid.Ssid, extra, len);2376src_ssid = ndis_ssid.Ssid;23772378_enter_critical_bh(&queue->lock, &irqL);2379phead = get_list_head(queue);2380pmlmepriv->pscanned = get_next(phead);23812382while (1) {2383if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) {2384#if 02385if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {2386rtw_set_802_11_ssid(padapter, &ndis_ssid);23872388goto cancel_ps_deny;2389} else {2390ret = -EINVAL;2391goto cancel_ps_deny;2392}2393#endif23942395break;2396}23972398pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);23992400pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);24012402dst_ssid = pnetwork->network.Ssid.Ssid;240324042405if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&2406(pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {24072408if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {2409if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)2410continue;2411}24122413if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0) == _FALSE) {2414ret = -1;2415_exit_critical_bh(&queue->lock, &irqL);2416goto cancel_ps_deny;2417}24182419break;2420}2421}2422_exit_critical_bh(&queue->lock, &irqL);2423rtw_set_802_11_authentication_mode(padapter, authmode);2424/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */2425if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {2426ret = -1;2427goto cancel_ps_deny;2428}2429}24302431cancel_ps_deny:2432rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);24332434exit:2435RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);24362437#ifdef DBG_IOCTL2438RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);2439#endif244024412442return ret;2443}24442445static int rtw_wx_get_essid(struct net_device *dev,2446struct iw_request_info *a,2447union iwreq_data *wrqu, char *extra)2448{2449u32 len, ret = 0;2450_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2451struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);2452WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;2453245424552456if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||2457(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {2458len = pcur_bss->Ssid.SsidLength;24592460wrqu->essid.length = len;24612462_rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);24632464wrqu->essid.flags = 1;2465} else {2466ret = -1;2467goto exit;2468}24692470exit:247124722473return ret;24742475}24762477static int rtw_wx_set_rate(struct net_device *dev,2478struct iw_request_info *a,2479union iwreq_data *wrqu, char *extra)2480{2481int i, ret = 0;2482_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2483u8 datarates[NumRates];2484u32 target_rate = wrqu->bitrate.value;2485u32 fixed = wrqu->bitrate.fixed;2486u32 ratevalue = 0;2487u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};2488248924902491if (target_rate == -1) {2492ratevalue = 11;2493goto set_rate;2494}2495target_rate = target_rate / 100000;24962497switch (target_rate) {2498case 10:2499ratevalue = 0;2500break;2501case 20:2502ratevalue = 1;2503break;2504case 55:2505ratevalue = 2;2506break;2507case 60:2508ratevalue = 3;2509break;2510case 90:2511ratevalue = 4;2512break;2513case 110:2514ratevalue = 5;2515break;2516case 120:2517ratevalue = 6;2518break;2519case 180:2520ratevalue = 7;2521break;2522case 240:2523ratevalue = 8;2524break;2525case 360:2526ratevalue = 9;2527break;2528case 480:2529ratevalue = 10;2530break;2531case 540:2532ratevalue = 11;2533break;2534default:2535ratevalue = 11;2536break;2537}25382539set_rate:25402541for (i = 0; i < NumRates; i++) {2542if (ratevalue == mpdatarate[i]) {2543datarates[i] = mpdatarate[i];2544if (fixed == 0)2545break;2546} else2547datarates[i] = 0xff;25482549}25502551if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {2552ret = -1;2553}255425552556return ret;2557}25582559static int rtw_wx_get_rate(struct net_device *dev,2560struct iw_request_info *info,2561union iwreq_data *wrqu, char *extra)2562{2563u16 max_rate = 0;25642565max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));25662567if (max_rate == 0)2568return -EPERM;25692570wrqu->bitrate.fixed = 0; /* no auto select */2571wrqu->bitrate.value = max_rate * 100000;25722573return 0;2574}25752576static int rtw_wx_set_rts(struct net_device *dev,2577struct iw_request_info *info,2578union iwreq_data *wrqu, char *extra)2579{2580_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);258125822583if (wrqu->rts.disabled)2584padapter->registrypriv.rts_thresh = 2347;2585else {2586if (wrqu->rts.value < 0 ||2587wrqu->rts.value > 2347)2588return -EINVAL;25892590padapter->registrypriv.rts_thresh = wrqu->rts.value;2591}25922593RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);259425952596return 0;25972598}25992600static int rtw_wx_get_rts(struct net_device *dev,2601struct iw_request_info *info,2602union iwreq_data *wrqu, char *extra)2603{2604_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);260526062607RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);26082609wrqu->rts.value = padapter->registrypriv.rts_thresh;2610wrqu->rts.fixed = 0; /* no auto select */2611/* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */261226132614return 0;2615}26162617static int rtw_wx_set_frag(struct net_device *dev,2618struct iw_request_info *info,2619union iwreq_data *wrqu, char *extra)2620{2621_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);262226232624if (wrqu->frag.disabled)2625padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;2626else {2627if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||2628wrqu->frag.value > MAX_FRAG_THRESHOLD)2629return -EINVAL;26302631padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;2632}26332634RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);263526362637return 0;26382639}26402641static int rtw_wx_get_frag(struct net_device *dev,2642struct iw_request_info *info,2643union iwreq_data *wrqu, char *extra)2644{2645_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);264626472648RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);26492650wrqu->frag.value = padapter->xmitpriv.frag_len;2651wrqu->frag.fixed = 0; /* no auto select */2652/* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */265326542655return 0;2656}26572658static int rtw_wx_get_retry(struct net_device *dev,2659struct iw_request_info *info,2660union iwreq_data *wrqu, char *extra)2661{2662/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */266326642665wrqu->retry.value = 7;2666wrqu->retry.fixed = 0; /* no auto select */2667wrqu->retry.disabled = 1;26682669return 0;26702671}26722673#if 02674#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */2675#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */2676#define IW_ENCODE_MODE 0xF000 /* Modes defined below */2677#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */2678#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */2679#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */2680#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */2681#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */2682#define IW_ENCODE_TEMP 0x0400 /* Temporary key */2683/*2684iwconfig wlan0 key on->flags = 0x6001->maybe it means auto2685iwconfig wlan0 key off->flags = 0x88002686iwconfig wlan0 key open->flags = 0x28002687iwconfig wlan0 key open 1234567890->flags = 0x20002688iwconfig wlan0 key restricted->flags = 0x48002689iwconfig wlan0 key open [3] 1234567890->flags = 0x20032690iwconfig wlan0 key restricted [2] 1234567890->flags = 0x40022691iwconfig wlan0 key open [3] -> flags = 0x28032692iwconfig wlan0 key restricted [2] -> flags = 0x48022693*/2694#endif26952696static int rtw_wx_set_enc(struct net_device *dev,2697struct iw_request_info *info,2698union iwreq_data *wrqu, char *keybuf)2699{2700u32 key, ret = 0;2701u32 keyindex_provided;2702NDIS_802_11_WEP wep;2703NDIS_802_11_AUTHENTICATION_MODE authmode;27042705struct iw_point *erq = &(wrqu->encoding);2706_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2707struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);2708RTW_INFO("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);27092710_rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));27112712key = erq->flags & IW_ENCODE_INDEX;271327142715if (erq->flags & IW_ENCODE_DISABLED) {2716RTW_INFO("EncryptionDisabled\n");2717padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;2718padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;2719padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;2720padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */2721authmode = Ndis802_11AuthModeOpen;2722padapter->securitypriv.ndisauthtype = authmode;27232724goto exit;2725}27262727if (key) {2728if (key > WEP_KEYS)2729return -EINVAL;2730key--;2731keyindex_provided = 1;2732} else {2733keyindex_provided = 0;2734key = padapter->securitypriv.dot11PrivacyKeyIndex;2735RTW_INFO("rtw_wx_set_enc, key=%d\n", key);2736}27372738/* set authentication mode */2739if (erq->flags & IW_ENCODE_OPEN) {2740RTW_INFO("rtw_wx_set_enc():IW_ENCODE_OPEN\n");2741padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */27422743#ifdef CONFIG_PLATFORM_MT53XX2744padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;2745#else2746padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;2747#endif27482749padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;2750padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;2751authmode = Ndis802_11AuthModeOpen;2752padapter->securitypriv.ndisauthtype = authmode;2753} else if (erq->flags & IW_ENCODE_RESTRICTED) {2754RTW_INFO("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");2755padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;27562757#ifdef CONFIG_PLATFORM_MT53XX2758padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;2759#else2760padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;2761#endif27622763padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;2764padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;2765authmode = Ndis802_11AuthModeShared;2766padapter->securitypriv.ndisauthtype = authmode;2767} else {2768RTW_INFO("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);27692770padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */2771padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */2772padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;2773padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;2774authmode = Ndis802_11AuthModeOpen;2775padapter->securitypriv.ndisauthtype = authmode;2776}27772778wep.KeyIndex = key;2779if (erq->length > 0) {2780wep.KeyLength = erq->length <= 5 ? 5 : 13;27812782wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);2783} else {2784wep.KeyLength = 0 ;27852786if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length==0). */2787padapter->securitypriv.dot11PrivacyKeyIndex = key;27882789RTW_INFO("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);27902791switch (padapter->securitypriv.dot11DefKeylen[key]) {2792case 5:2793padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;2794break;2795case 13:2796padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;2797break;2798default:2799padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;2800break;2801}28022803goto exit;28042805}28062807}28082809wep.KeyIndex |= 0x80000000;28102811_rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);28122813if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {2814if (rf_on == pwrpriv->rf_pwrstate)2815ret = -EOPNOTSUPP;2816goto exit;2817}28182819exit:282028212822return ret;28232824}28252826static int rtw_wx_get_enc(struct net_device *dev,2827struct iw_request_info *info,2828union iwreq_data *wrqu, char *keybuf)2829{2830uint key, ret = 0;2831_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2832struct iw_point *erq = &(wrqu->encoding);2833struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);283428352836if (check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) {2837if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) {2838erq->length = 0;2839erq->flags |= IW_ENCODE_DISABLED;2840return 0;2841}2842}284328442845key = erq->flags & IW_ENCODE_INDEX;28462847if (key) {2848if (key > WEP_KEYS)2849return -EINVAL;2850key--;2851} else2852key = padapter->securitypriv.dot11PrivacyKeyIndex;28532854erq->flags = key + 1;28552856/* if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */2857/* { */2858/* erq->flags |= IW_ENCODE_OPEN; */2859/* } */28602861switch (padapter->securitypriv.ndisencryptstatus) {2862case Ndis802_11EncryptionNotSupported:2863case Ndis802_11EncryptionDisabled:28642865erq->length = 0;2866erq->flags |= IW_ENCODE_DISABLED;28672868break;28692870case Ndis802_11Encryption1Enabled:28712872erq->length = padapter->securitypriv.dot11DefKeylen[key];28732874if (erq->length) {2875_rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);28762877erq->flags |= IW_ENCODE_ENABLED;28782879if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)2880erq->flags |= IW_ENCODE_OPEN;2881else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)2882erq->flags |= IW_ENCODE_RESTRICTED;2883} else {2884erq->length = 0;2885erq->flags |= IW_ENCODE_DISABLED;2886}28872888break;28892890case Ndis802_11Encryption2Enabled:2891case Ndis802_11Encryption3Enabled:28922893erq->length = 16;2894erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);28952896break;28972898default:2899erq->length = 0;2900erq->flags |= IW_ENCODE_DISABLED;29012902break;29032904}290529062907return ret;29082909}29102911static int rtw_wx_get_power(struct net_device *dev,2912struct iw_request_info *info,2913union iwreq_data *wrqu, char *extra)2914{2915/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */29162917wrqu->power.value = 0;2918wrqu->power.fixed = 0; /* no auto select */2919wrqu->power.disabled = 1;29202921return 0;29222923}29242925static int rtw_wx_set_gen_ie(struct net_device *dev,2926struct iw_request_info *info,2927union iwreq_data *wrqu, char *extra)2928{2929int ret;2930_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);29312932ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);29332934return ret;2935}29362937static int rtw_wx_set_auth(struct net_device *dev,2938struct iw_request_info *info,2939union iwreq_data *wrqu, char *extra)2940{2941_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);2942struct iw_param *param = (struct iw_param *)&(wrqu->param);2943#ifdef CONFIG_WAPI_SUPPORT2944#ifndef CONFIG_IOCTL_CFG802112945struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;2946struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);2947struct security_priv *psecuritypriv = &padapter->securitypriv;2948u32 value = param->value;2949#endif2950#endif2951int ret = 0;29522953switch (param->flags & IW_AUTH_INDEX) {29542955case IW_AUTH_WPA_VERSION:2956#ifdef CONFIG_WAPI_SUPPORT2957#ifndef CONFIG_IOCTL_CFG802112958padapter->wapiInfo.bWapiEnable = false;2959if (value == IW_AUTH_WAPI_VERSION_1) {2960padapter->wapiInfo.bWapiEnable = true;2961psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;2962psecuritypriv->dot118021XGrpPrivacy = _SMS4_;2963psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;2964pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;2965padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;2966padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;2967}2968#endif2969#endif2970break;2971case IW_AUTH_CIPHER_PAIRWISE:29722973break;2974case IW_AUTH_CIPHER_GROUP:29752976break;2977case IW_AUTH_KEY_MGMT:2978#ifdef CONFIG_WAPI_SUPPORT2979#ifndef CONFIG_IOCTL_CFG802112980RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case\n");2981if (value == IW_AUTH_KEY_MGMT_WAPI_PSK)2982padapter->wapiInfo.bWapiPSK = true;2983else2984padapter->wapiInfo.bWapiPSK = false;2985RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d\n", padapter->wapiInfo.bWapiPSK);2986#endif2987#endif2988/*2989* ??? does not use these parameters2990*/2991break;29922993case IW_AUTH_TKIP_COUNTERMEASURES: {2994if (param->value) {2995/* wpa_supplicant is enabling the tkip countermeasure. */2996padapter->securitypriv.btkip_countermeasure = _TRUE;2997} else {2998/* wpa_supplicant is disabling the tkip countermeasure. */2999padapter->securitypriv.btkip_countermeasure = _FALSE;3000}3001break;3002}3003case IW_AUTH_DROP_UNENCRYPTED: {3004/* HACK:3005*3006* wpa_supplicant calls set_wpa_enabled when the driver3007* is loaded and unloaded, regardless of if WPA is being3008* used. No other calls are made which can be used to3009* determine if encryption will be used or not prior to3010* association being expected. If encryption is not being3011* used, drop_unencrypted is set to false, else true -- we3012* can use this to determine if the CAP_PRIVACY_ON bit should3013* be set.3014*/30153016if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) {3017break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */3018/* then it needn't reset it; */3019}30203021if (param->value) {3022padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;3023padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;3024padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;3025padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */3026padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;3027}30283029break;3030}30313032case IW_AUTH_80211_AUTH_ALG:30333034#if defined(CONFIG_ANDROID) || 13035/*3036* It's the starting point of a link layer connection using wpa_supplicant3037*/3038if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {3039LeaveAllPowerSaveMode(padapter);3040rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK);3041RTW_INFO("%s...call rtw_indicate_disconnect\n ", __FUNCTION__);3042rtw_indicate_disconnect(padapter, 0, _FALSE);3043rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK);3044}3045#endif304630473048ret = wpa_set_auth_algs(dev, (u32)param->value);30493050break;30513052case IW_AUTH_WPA_ENABLED:30533054/* if(param->value) */3055/* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; */ /* 802.1x */3056/* else */3057/* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; */ /* open system */30583059/* _disassociate(priv); */30603061break;30623063case IW_AUTH_RX_UNENCRYPTED_EAPOL:3064/* ieee->ieee802_1x = param->value; */3065break;30663067case IW_AUTH_PRIVACY_INVOKED:3068/* ieee->privacy_invoked = param->value; */3069break;30703071#ifdef CONFIG_WAPI_SUPPORT3072#ifndef CONFIG_IOCTL_CFG802113073case IW_AUTH_WAPI_ENABLED:3074break;3075#endif3076#endif30773078default:3079return -EOPNOTSUPP;30803081}30823083return ret;30843085}30863087static int rtw_wx_set_enc_ext(struct net_device *dev,3088struct iw_request_info *info,3089union iwreq_data *wrqu, char *extra)3090{3091char *alg_name;3092u32 param_len;3093struct ieee_param *param = NULL;3094struct iw_point *pencoding = &wrqu->encoding;3095struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;3096int ret = 0;30973098param_len = sizeof(struct ieee_param) + pext->key_len;3099param = (struct ieee_param *)rtw_malloc(param_len);3100if (param == NULL)3101return -1;31023103_rtw_memset(param, 0, param_len);31043105param->cmd = IEEE_CMD_SET_ENCRYPTION;3106_rtw_memset(param->sta_addr, 0xff, ETH_ALEN);310731083109switch (pext->alg) {3110case IW_ENCODE_ALG_NONE:3111/* todo: remove key */3112/* remove = 1; */3113alg_name = "none";3114break;3115case IW_ENCODE_ALG_WEP:3116alg_name = "WEP";3117break;3118case IW_ENCODE_ALG_TKIP:3119alg_name = "TKIP";3120break;3121case IW_ENCODE_ALG_CCMP:3122alg_name = "CCMP";3123break;3124#ifdef CONFIG_IEEE80211W3125case IW_ENCODE_ALG_AES_CMAC:3126alg_name = "BIP";3127break;3128#endif /* CONFIG_IEEE80211W */3129#ifdef CONFIG_WAPI_SUPPORT3130#ifndef CONFIG_IOCTL_CFG802113131case IW_ENCODE_ALG_SM4:3132alg_name = "SMS4";3133_rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);3134RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");3135break;3136#endif3137#endif3138default:3139ret = -1;3140goto exit;3141}31423143strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);31443145if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)3146param->u.crypt.set_tx = 1;31473148/* cliW: WEP does not have group key3149* just not checking GROUP key setting3150*/3151if ((pext->alg != IW_ENCODE_ALG_WEP) &&3152((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)3153#ifdef CONFIG_IEEE80211W3154|| (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)3155#endif /* CONFIG_IEEE80211W */3156))3157param->u.crypt.set_tx = 0;31583159param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1 ;31603161if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {3162#ifdef CONFIG_WAPI_SUPPORT3163#ifndef CONFIG_IOCTL_CFG802113164if (pext->alg == IW_ENCODE_ALG_SM4)3165_rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);3166else3167#endif /* CONFIG_IOCTL_CFG80211 */3168#endif /* CONFIG_WAPI_SUPPORT */3169_rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);3170}31713172if (pext->key_len) {3173param->u.crypt.key_len = pext->key_len;3174/* _rtw_memcpy(param + 1, pext + 1, pext->key_len); */3175_rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);3176}31773178if (pencoding->flags & IW_ENCODE_DISABLED) {3179/* todo: remove key */3180/* remove = 1; */3181}31823183ret = wpa_set_encryption(dev, param, param_len);31843185exit:3186if (param)3187rtw_mfree((u8 *)param, param_len);31883189return ret;3190}319131923193static int rtw_wx_get_nick(struct net_device *dev,3194struct iw_request_info *info,3195union iwreq_data *wrqu, char *extra)3196{3197/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */3198/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */3199/* struct security_priv *psecuritypriv = &padapter->securitypriv; */32003201if (extra) {3202wrqu->data.length = 14;3203wrqu->data.flags = 1;3204_rtw_memcpy(extra, "WIFI@RTL8814AU", 14);3205}32063207/* rtw_signal_process(pid, SIGUSR1); */ /* for test */32083209/* dump debug info here */3210#if 03211u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, shared, and 8021x */3212u32 dot11PrivacyAlgrthm; /* This specify the privacy for shared auth. algorithm. */3213u32 dot118021XGrpPrivacy; /* This specify the privacy algthm. used for Grp key */3214u32 ndisauthtype;3215u32 ndisencryptstatus;3216#endif32173218/* RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", */3219/* psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, */3220/* psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); */32213222/* RTW_INFO("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); */3223/* RTW_INFO("auth_type=0x%x\n", psecuritypriv->ndisauthtype); */3224/* RTW_INFO("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); */32253226#if 03227RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));3228RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));3229RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));3230RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));3231RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));32323233RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));323432353236RTW_INFO("\n");32373238RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));3239RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));32403241RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));32423243RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));32443245RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));3246RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));32473248RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));3249RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));3250RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));3251RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));3252#endif32533254return 0;32553256}32573258static int rtw_wx_read32(struct net_device *dev,3259struct iw_request_info *info,3260union iwreq_data *wrqu, char *extra)3261{3262PADAPTER padapter;3263struct iw_point *p;3264u16 len;3265u32 addr;3266u32 data32;3267u32 bytes;3268u8 *ptmp;3269int ret;327032713272ret = 0;3273padapter = (PADAPTER)rtw_netdev_priv(dev);3274p = &wrqu->data;3275len = p->length;3276if (0 == len)3277return -EINVAL;32783279ptmp = (u8 *)rtw_malloc(len);3280if (NULL == ptmp)3281return -ENOMEM;32823283if (copy_from_user(ptmp, p->pointer, len)) {3284ret = -EFAULT;3285goto exit;3286}32873288bytes = 0;3289addr = 0;3290sscanf(ptmp, "%d,%x", &bytes, &addr);32913292switch (bytes) {3293case 1:3294data32 = rtw_read8(padapter, addr);3295sprintf(extra, "0x%02X", data32);3296break;3297case 2:3298data32 = rtw_read16(padapter, addr);3299sprintf(extra, "0x%04X", data32);3300break;3301case 4:3302data32 = rtw_read32(padapter, addr);3303sprintf(extra, "0x%08X", data32);3304break;33053306#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)3307case 11:3308data32 = rtw_sd_iread8(padapter, addr);3309sprintf(extra, "0x%02X", data32);3310break;3311case 12:3312data32 = rtw_sd_iread16(padapter, addr);3313sprintf(extra, "0x%04X", data32);3314break;3315case 14:3316data32 = rtw_sd_iread32(padapter, addr);3317sprintf(extra, "0x%08X", data32);3318break;3319#endif3320default:3321RTW_INFO("%s: usage> read [bytes],[address(hex)]\n", __func__);3322ret = -EINVAL;3323goto exit;3324}3325RTW_INFO("%s: addr=0x%08X data=%s\n", __func__, addr, extra);33263327exit:3328rtw_mfree(ptmp, len);33293330return 0;3331}33323333static int rtw_wx_write32(struct net_device *dev,3334struct iw_request_info *info,3335union iwreq_data *wrqu, char *extra)3336{3337PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);33383339u32 addr;3340u32 data32;3341u32 bytes;334233433344bytes = 0;3345addr = 0;3346data32 = 0;3347sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);33483349switch (bytes) {3350case 1:3351rtw_write8(padapter, addr, (u8)data32);3352RTW_INFO("%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);3353break;3354case 2:3355rtw_write16(padapter, addr, (u16)data32);3356RTW_INFO("%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);3357break;3358case 4:3359rtw_write32(padapter, addr, data32);3360RTW_INFO("%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);3361break;3362default:3363RTW_INFO("%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);3364return -EINVAL;3365}33663367return 0;3368}33693370static int rtw_wx_read_rf(struct net_device *dev,3371struct iw_request_info *info,3372union iwreq_data *wrqu, char *extra)3373{3374_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3375u32 path, addr, data32;337633773378path = *(u32 *)extra;3379addr = *((u32 *)extra + 1);3380data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);3381/* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */3382/*3383* IMPORTANT!!3384* Only when wireless private ioctl is at odd order,3385* "extra" would be copied to user space.3386*/3387sprintf(extra, "0x%05x", data32);33883389return 0;3390}33913392static int rtw_wx_write_rf(struct net_device *dev,3393struct iw_request_info *info,3394union iwreq_data *wrqu, char *extra)3395{3396_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3397u32 path, addr, data32;339833993400path = *(u32 *)extra;3401addr = *((u32 *)extra + 1);3402data32 = *((u32 *)extra + 2);3403/* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */3404rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);34053406return 0;3407}34083409static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,3410union iwreq_data *wrqu, char *b)3411{3412return -1;3413}34143415#ifdef CONFIG_RTW_80211K3416extern void rm_dbg_cmd(_adapter *padapter, char *s);3417static int rtw_wx_priv_rrm(struct net_device *dev, struct iw_request_info *a,3418union iwreq_data *wrqu, char *b)3419{3420_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3421u32 path, addr, data32;342234233424rm_dbg_cmd(padapter, b);3425wrqu->data.length = strlen(b);34263427return 0;3428}3429#endif34303431static int dummy(struct net_device *dev, struct iw_request_info *a,3432union iwreq_data *wrqu, char *b)3433{3434/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */3435/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */34363437/* RTW_INFO("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); */34383439return -1;34403441}34423443static int rtw_wx_set_channel_plan(struct net_device *dev,3444struct iw_request_info *info,3445union iwreq_data *wrqu, char *extra)3446{3447_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3448u8 channel_plan_req = (u8)(*((int *)wrqu));34493450if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req))3451return -EPERM;34523453return 0;3454}34553456static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,3457struct iw_request_info *a,3458union iwreq_data *wrqu, char *b)3459{3460#ifdef CONFIG_PLATFORM_MT53XX3461_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3462struct mlme_priv *pmlmepriv = &padapter->mlmepriv;34633464#endif3465return 0;3466}34673468static int rtw_wx_get_sensitivity(struct net_device *dev,3469struct iw_request_info *info,3470union iwreq_data *wrqu, char *buf)3471{3472#ifdef CONFIG_PLATFORM_MT53XX3473_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);34743475/* Modified by Albert 20110914 */3476/* This is in dbm format for MTK platform. */3477wrqu->qual.level = padapter->recvpriv.rssi;3478RTW_INFO(" level = %u\n", wrqu->qual.level);3479#endif3480return 0;3481}34823483static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,3484struct iw_request_info *info,3485union iwreq_data *wrqu, char *extra)3486{3487#ifdef CONFIG_PLATFORM_MT53XX3488_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);34893490return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);3491#else3492return 0;3493#endif3494}34953496#ifdef MP_IOCTL_HDL3497static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)3498{3499pRW_Reg RegRWStruct;3500struct rf_reg_param *prfreg;3501u8 path;3502u8 offset;3503u32 value;35043505RTW_INFO("%s\n", __FUNCTION__);35063507switch (id) {3508case GEN_MP_IOCTL_SUBCODE(MP_START):3509RTW_INFO("871x_driver is only for normal mode, can't enter mp mode\n");3510break;3511case GEN_MP_IOCTL_SUBCODE(READ_REG):3512RegRWStruct = (pRW_Reg)pdata;3513switch (RegRWStruct->width) {3514case 1:3515RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);3516break;3517case 2:3518RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);3519break;3520case 4:3521RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);3522break;3523default:3524break;3525}35263527break;3528case GEN_MP_IOCTL_SUBCODE(WRITE_REG):3529RegRWStruct = (pRW_Reg)pdata;3530switch (RegRWStruct->width) {3531case 1:3532rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);3533break;3534case 2:3535rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);3536break;3537case 4:3538rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);3539break;3540default:3541break;3542}35433544break;3545case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):35463547prfreg = (struct rf_reg_param *)pdata;35483549path = (u8)prfreg->path;3550offset = (u8)prfreg->offset;35513552value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);35533554prfreg->value = value;35553556break;3557case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):35583559prfreg = (struct rf_reg_param *)pdata;35603561path = (u8)prfreg->path;3562offset = (u8)prfreg->offset;3563value = prfreg->value;35643565rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);35663567break;3568case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):3569RTW_INFO("==> trigger gpio 0\n");3570rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);3571break;3572#ifdef CONFIG_BT_COEXIST3573case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):3574RTW_INFO("==> set dm_bt_coexist:%x\n", *(u8 *)pdata);3575rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);3576break;3577case GEN_MP_IOCTL_SUBCODE(DEL_BA):3578RTW_INFO("==> delete ba:%x\n", *(u8 *)pdata);3579rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);3580break;3581#endif3582#ifdef DBG_CONFIG_ERROR_DETECT3583case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):3584*pdata = rtw_hal_sreset_get_wifi_status(padapter);3585break;3586#endif35873588default:3589break;3590}35913592}3593static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,3594union iwreq_data *wrqu, char *extra)3595{3596int ret = 0;3597u32 BytesRead, BytesWritten, BytesNeeded;3598struct oid_par_priv oid_par;3599struct mp_ioctl_handler *phandler;3600struct mp_ioctl_param *poidparam;3601uint status = 0;3602u16 len;3603u8 *pparmbuf = NULL, bset;3604PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);3605struct iw_point *p = &wrqu->data;36063607/* RTW_INFO("+rtw_mp_ioctl_hdl\n"); */36083609/* mutex_lock(&ioctl_mutex); */36103611if ((!p->length) || (!p->pointer)) {3612ret = -EINVAL;3613goto _rtw_mp_ioctl_hdl_exit;3614}36153616pparmbuf = NULL;3617bset = (u8)(p->flags & 0xFFFF);3618len = p->length;3619pparmbuf = (u8 *)rtw_malloc(len);3620if (pparmbuf == NULL) {3621ret = -ENOMEM;3622goto _rtw_mp_ioctl_hdl_exit;3623}36243625if (copy_from_user(pparmbuf, p->pointer, len)) {3626ret = -EFAULT;3627goto _rtw_mp_ioctl_hdl_exit;3628}36293630poidparam = (struct mp_ioctl_param *)pparmbuf;36313632if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {3633ret = -EINVAL;3634goto _rtw_mp_ioctl_hdl_exit;3635}36363637/* RTW_INFO("%s: %d\n", __func__, poidparam->subcode); */3638#ifdef CONFIG_MP_INCLUDED3639if (padapter->registrypriv.mp_mode == 1) {3640phandler = mp_ioctl_hdl + poidparam->subcode;36413642if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {3643ret = -EINVAL;3644goto _rtw_mp_ioctl_hdl_exit;3645}36463647if (phandler->handler) {3648oid_par.adapter_context = padapter;3649oid_par.oid = phandler->oid;3650oid_par.information_buf = poidparam->data;3651oid_par.information_buf_len = poidparam->len;3652oid_par.dbg = 0;36533654BytesWritten = 0;3655BytesNeeded = 0;36563657if (bset) {3658oid_par.bytes_rw = &BytesRead;3659oid_par.bytes_needed = &BytesNeeded;3660oid_par.type_of_oid = SET_OID;3661} else {3662oid_par.bytes_rw = &BytesWritten;3663oid_par.bytes_needed = &BytesNeeded;3664oid_par.type_of_oid = QUERY_OID;3665}36663667status = phandler->handler(&oid_par);36683669/* todo:check status, BytesNeeded, etc. */3670} else {3671RTW_INFO("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",3672poidparam->subcode, phandler->oid, phandler->handler);3673ret = -EFAULT;3674goto _rtw_mp_ioctl_hdl_exit;3675}3676} else3677#endif3678{3679rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);3680}36813682if (bset == 0x00) {/* query info */3683if (copy_to_user(p->pointer, pparmbuf, len))3684ret = -EFAULT;3685}36863687if (status) {3688ret = -EFAULT;3689goto _rtw_mp_ioctl_hdl_exit;3690}36913692_rtw_mp_ioctl_hdl_exit:36933694if (pparmbuf)3695rtw_mfree(pparmbuf, len);36963697/* mutex_unlock(&ioctl_mutex); */36983699return ret;3700}3701#endif /*MP_IOCTL_HDL*/3702static int rtw_get_ap_info(struct net_device *dev,3703struct iw_request_info *info,3704union iwreq_data *wrqu, char *extra)3705{3706int ret = 0;3707u32 cnt = 0, wpa_ielen;3708_irqL irqL;3709_list *plist, *phead;3710unsigned char *pbuf;3711u8 bssid[ETH_ALEN];3712char data[32];3713struct wlan_network *pnetwork = NULL;3714_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3715struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);3716_queue *queue = &(pmlmepriv->scanned_queue);3717struct iw_point *pdata = &wrqu->data;37183719RTW_INFO("+rtw_get_aplist_info\n");37203721if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {3722ret = -EINVAL;3723goto exit;3724}37253726while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING))) == _TRUE) {3727rtw_msleep_os(30);3728cnt++;3729if (cnt > 100)3730break;3731}373237333734/* pdata->length = 0; */ /* ? */3735pdata->flags = 0;3736if (pdata->length >= 32) {3737if (copy_from_user(data, pdata->pointer, 32)) {3738ret = -EINVAL;3739goto exit;3740}3741} else {3742ret = -EINVAL;3743goto exit;3744}37453746_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);37473748phead = get_list_head(queue);3749plist = get_next(phead);37503751while (1) {3752if (rtw_end_of_queue_search(phead, plist) == _TRUE)3753break;375437553756pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);37573758/* if(hwaddr_aton_i(pdata->pointer, bssid)) */3759if (hwaddr_aton_i(data, bssid)) {3760RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data);3761_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);3762return -EINVAL;3763}376437653766if (_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) { /* BSSID match, then check if supporting wpa/wpa2 */3767RTW_INFO("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));37683769pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);3770if (pbuf && (wpa_ielen > 0)) {3771pdata->flags = 1;3772break;3773}37743775pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);3776if (pbuf && (wpa_ielen > 0)) {3777pdata->flags = 2;3778break;3779}37803781}37823783plist = get_next(plist);37843785}37863787_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);37883789if (pdata->length >= 34) {3790if (copy_to_user((u8 *)pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {3791ret = -EINVAL;3792goto exit;3793}3794}37953796exit:37973798return ret;37993800}38013802static int rtw_set_pid(struct net_device *dev,3803struct iw_request_info *info,3804union iwreq_data *wrqu, char *extra)3805{38063807int ret = 0;3808_adapter *padapter = rtw_netdev_priv(dev);3809int *pdata = (int *)wrqu;3810int selector;38113812if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {3813ret = -EINVAL;3814goto exit;3815}38163817selector = *pdata;3818if (selector < 3 && selector >= 0) {3819padapter->pid[selector] = *(pdata + 1);3820#ifdef CONFIG_GLOBAL_UI_PID3821ui_pid[selector] = *(pdata + 1);3822#endif3823RTW_INFO("%s set pid[%d]=%d\n", __FUNCTION__, selector , padapter->pid[selector]);3824} else3825RTW_INFO("%s selector %d error\n", __FUNCTION__, selector);38263827exit:38283829return ret;38303831}38323833static int rtw_wps_start(struct net_device *dev,3834struct iw_request_info *info,3835union iwreq_data *wrqu, char *extra)3836{38373838int ret = 0;3839_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3840struct iw_point *pdata = &wrqu->data;3841u32 u32wps_start = 0;3842unsigned int uintRet = 0;38433844if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) {3845ret = -EINVAL;3846goto exit;3847}38483849uintRet = copy_from_user((void *) &u32wps_start, pdata->pointer, 4);3850if (u32wps_start == 0)3851u32wps_start = *extra;38523853RTW_INFO("[%s] wps_start = %d\n", __FUNCTION__, u32wps_start);38543855if (u32wps_start == 1) /* WPS Start */3856rtw_led_control(padapter, LED_CTL_START_WPS);3857else if (u32wps_start == 2) /* WPS Stop because of wps success */3858rtw_led_control(padapter, LED_CTL_STOP_WPS);3859else if (u32wps_start == 3) /* WPS Stop because of wps fail */3860rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);38613862exit:38633864return ret;38653866}38673868#ifdef CONFIG_P2P3869static int rtw_wext_p2p_enable(struct net_device *dev,3870struct iw_request_info *info,3871union iwreq_data *wrqu, char *extra)3872{38733874int ret = 0;3875_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3876struct wifidirect_info *pwdinfo = &(padapter->wdinfo);3877struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;3878enum P2P_ROLE init_role = P2P_ROLE_DISABLE;38793880if (*extra == '0')3881init_role = P2P_ROLE_DISABLE;3882else if (*extra == '1')3883init_role = P2P_ROLE_DEVICE;3884else if (*extra == '2')3885init_role = P2P_ROLE_CLIENT;3886else if (*extra == '3')3887init_role = P2P_ROLE_GO;38883889if (_FAIL == rtw_p2p_enable(padapter, init_role)) {3890ret = -EFAULT;3891goto exit;3892}38933894/* set channel/bandwidth */3895if (init_role != P2P_ROLE_DISABLE) {3896u8 channel, ch_offset;3897u16 bwmode;38983899if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {3900/* Stay at the listen state and wait for discovery. */3901channel = pwdinfo->listen_channel;3902pwdinfo->operating_channel = pwdinfo->listen_channel;3903ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;3904bwmode = CHANNEL_WIDTH_20;3905}3906#ifdef CONFIG_CONCURRENT_MODE3907else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {39083909_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval);39103911channel = rtw_mi_get_union_chan(padapter);3912ch_offset = rtw_mi_get_union_offset(padapter);3913bwmode = rtw_mi_get_union_bw(padapter);39143915pwdinfo->operating_channel = channel;3916}3917#endif3918else {3919pwdinfo->operating_channel = pmlmeext->cur_channel;39203921channel = pwdinfo->operating_channel;3922ch_offset = pmlmeext->cur_ch_offset;3923bwmode = pmlmeext->cur_bwmode;3924}39253926set_channel_bwmode(padapter, channel, ch_offset, bwmode);3927}39283929exit:3930return ret;39313932}39333934static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,3935struct iw_request_info *info,3936union iwreq_data *wrqu, char *extra)3937{39383939int ret = 0;3940_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3941struct wifidirect_info *pwdinfo = &(padapter->wdinfo);39423943RTW_INFO("[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen(extra));3944_rtw_memcpy(pwdinfo->nego_ssid, extra, strlen(extra));3945pwdinfo->nego_ssidlen = strlen(extra);39463947return ret;39483949}395039513952static int rtw_p2p_set_intent(struct net_device *dev,3953struct iw_request_info *info,3954union iwreq_data *wrqu, char *extra)3955{3956int ret = 0;3957_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3958struct wifidirect_info *pwdinfo = &(padapter->wdinfo);3959u8 intent = pwdinfo->intent;39603961extra[wrqu->data.length] = 0x00;39623963intent = rtw_atoi(extra);39643965if (intent <= 15)3966pwdinfo->intent = intent;3967else3968ret = -1;39693970RTW_INFO("[%s] intent = %d\n", __FUNCTION__, intent);39713972return ret;39733974}39753976static int rtw_p2p_set_listen_ch(struct net_device *dev,3977struct iw_request_info *info,3978union iwreq_data *wrqu, char *extra)3979{39803981int ret = 0;3982_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);3983struct wifidirect_info *pwdinfo = &(padapter->wdinfo);3984u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */39853986extra[wrqu->data.length] = 0x00;3987listen_ch = rtw_atoi(extra);39883989if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {3990pwdinfo->listen_channel = listen_ch;3991set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);3992} else3993ret = -1;39943995RTW_INFO("[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel);39963997return ret;39983999}40004001static int rtw_p2p_set_op_ch(struct net_device *dev,4002struct iw_request_info *info,4003union iwreq_data *wrqu, char *extra)4004{4005/* Commented by Albert 201105244006* This function is used to set the operating channel if the driver will become the group owner */40074008int ret = 0;4009_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4010struct wifidirect_info *pwdinfo = &(padapter->wdinfo);4011u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */40124013extra[wrqu->data.length] = 0x00;40144015op_ch = (u8) rtw_atoi(extra);4016if (op_ch > 0)4017pwdinfo->operating_channel = op_ch;4018else4019ret = -1;40204021RTW_INFO("[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel);40224023return ret;40244025}402640274028static int rtw_p2p_profilefound(struct net_device *dev,4029struct iw_request_info *info,4030union iwreq_data *wrqu, char *extra)4031{40324033int ret = 0;4034_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4035struct wifidirect_info *pwdinfo = &(padapter->wdinfo);40364037/* Comment by Albert 2010/10/13 */4038/* Input data format: */4039/* Ex: 0 */4040/* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */4041/* 0 => Reflush the profile record list. */4042/* 1 => Add the profile list */4043/* XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) */4044/* YY => SSID Length */4045/* SSID => SSID for persistence group */40464047RTW_INFO("[%s] In value = %s, len = %d\n", __FUNCTION__, extra, wrqu->data.length - 1);404840494050/* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */4051if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {4052if (extra[0] == '0') {4053/* Remove all the profile information of wifidirect_info structure. */4054_rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);4055pwdinfo->profileindex = 0;4056} else {4057if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM)4058ret = -1;4059else {4060int jj, kk;40614062/* Add this profile information into pwdinfo->profileinfo */4063/* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */4064for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)4065pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);40664067/* pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[19] - '0' ); */4068/* _rtw_memcpy( pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen ); */4069pwdinfo->profileindex++;4070}4071}4072}40734074return ret;40754076}40774078static int rtw_p2p_setDN(struct net_device *dev,4079struct iw_request_info *info,4080union iwreq_data *wrqu, char *extra)4081{40824083int ret = 0;4084_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4085struct wifidirect_info *pwdinfo = &(padapter->wdinfo);408640874088RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);4089_rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);4090_rtw_memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);4091pwdinfo->device_name_len = wrqu->data.length - 1;40924093return ret;40944095}409640974098static int rtw_p2p_get_status(struct net_device *dev,4099struct iw_request_info *info,4100union iwreq_data *wrqu, char *extra)4101{41024103int ret = 0;4104_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4105struct wifidirect_info *pwdinfo = &(padapter->wdinfo);41064107if (padapter->bShowGetP2PState) {4108RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),4109pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],4110pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);4111}41124113/* Commented by Albert 2010/10/12 */4114/* Because of the output size limitation, I had removed the "Role" information. */4115/* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */4116sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));4117wrqu->data.length = strlen(extra);41184119return ret;41204121}41224123/* Commented by Albert 201105204124* This function will return the config method description4125* This config method description will show us which config method the remote P2P device is intented to use4126* by sending the provisioning discovery request frame. */41274128static int rtw_p2p_get_req_cm(struct net_device *dev,4129struct iw_request_info *info,4130union iwreq_data *wrqu, char *extra)4131{41324133int ret = 0;4134_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4135struct wifidirect_info *pwdinfo = &(padapter->wdinfo);41364137sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);4138wrqu->data.length = strlen(extra);4139return ret;41404141}414241434144static int rtw_p2p_get_role(struct net_device *dev,4145struct iw_request_info *info,4146union iwreq_data *wrqu, char *extra)4147{41484149int ret = 0;4150_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4151struct wifidirect_info *pwdinfo = &(padapter->wdinfo);41524153RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),4154pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],4155pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);41564157sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));4158wrqu->data.length = strlen(extra);4159return ret;41604161}416241634164static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,4165struct iw_request_info *info,4166union iwreq_data *wrqu, char *extra)4167{41684169int ret = 0;4170_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4171struct wifidirect_info *pwdinfo = &(padapter->wdinfo);417241734174RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),4175pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],4176pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);41774178sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",4179pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],4180pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);4181wrqu->data.length = strlen(extra);4182return ret;41834184}41854186static int rtw_p2p_get_peer_devaddr(struct net_device *dev,4187struct iw_request_info *info,4188union iwreq_data *wrqu, char *extra)41894190{41914192int ret = 0;4193_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4194struct wifidirect_info *pwdinfo = &(padapter->wdinfo);41954196RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),4197pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],4198pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],4199pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);4200sprintf(extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",4201pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],4202pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],4203pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);4204wrqu->data.length = strlen(extra);4205return ret;42064207}42084209static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,4210struct iw_request_info *info,4211union iwreq_data *wrqu, char *extra)42124213{42144215int ret = 0;4216_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4217struct wifidirect_info *pwdinfo = &(padapter->wdinfo);42184219RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),4220pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],4221pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],4222pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);4223sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",4224pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],4225pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],4226pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);4227wrqu->data.length = strlen(extra);4228return ret;42294230}42314232static int rtw_p2p_get_groupid(struct net_device *dev,4233struct iw_request_info *info,4234union iwreq_data *wrqu, char *extra)42354236{42374238int ret = 0;4239_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4240struct wifidirect_info *pwdinfo = &(padapter->wdinfo);42414242sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",4243pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],4244pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],4245pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],4246pwdinfo->groupid_info.ssid);4247wrqu->data.length = strlen(extra);4248return ret;42494250}42514252static int rtw_p2p_get_op_ch(struct net_device *dev,4253struct iw_request_info *info,4254union iwreq_data *wrqu, char *extra)42554256{42574258int ret = 0;4259_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4260struct wifidirect_info *pwdinfo = &(padapter->wdinfo);426142624263RTW_INFO("[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);42644265sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);4266wrqu->data.length = strlen(extra);4267return ret;42684269}42704271static int rtw_p2p_get_wps_configmethod(struct net_device *dev,4272struct iw_request_info *info,4273union iwreq_data *wrqu, char *extra, char *subcmd)4274{42754276int ret = 0;4277_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4278u8 peerMAC[ETH_ALEN] = { 0x00 };4279struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4280_irqL irqL;4281_list *plist, *phead;4282_queue *queue = &(pmlmepriv->scanned_queue);4283struct wlan_network *pnetwork = NULL;4284u8 blnMatch = 0;4285u16 attr_content = 0;4286uint attr_contentlen = 0;4287u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };42884289/* Commented by Albert 20110727 */4290/* The input data is the MAC address which the application wants to know its WPS config method. */4291/* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */4292/* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */42934294RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);42954296macstr2num(peerMAC, subcmd);42974298_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);42994300phead = get_list_head(queue);4301plist = get_next(phead);43024303while (1) {4304if (rtw_end_of_queue_search(phead, plist) == _TRUE)4305break;43064307pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);4308if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {4309u8 *wpsie;4310uint wpsie_len = 0;43114312/* The mac address is matched. */43134314wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);4315if (wpsie) {4316rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);4317if (attr_contentlen) {4318attr_content = be16_to_cpu(attr_content);4319sprintf(attr_content_str, "\n\nM=%.4d", attr_content);4320blnMatch = 1;4321}4322}43234324break;4325}43264327plist = get_next(plist);43284329}43304331_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);43324333if (!blnMatch)4334sprintf(attr_content_str, "\n\nM=0000");43354336wrqu->data.length = strlen(attr_content_str);4337_rtw_memcpy(extra, attr_content_str, wrqu->data.length);43384339return ret;43404341}43424343#ifdef CONFIG_WFD4344static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,4345struct iw_request_info *info,4346union iwreq_data *wrqu, char *extra)4347{43484349int ret = 0;4350_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4351struct wifidirect_info *pwdinfo = &(padapter->wdinfo);43524353RTW_INFO("[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));43544355sprintf(extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport);4356RTW_INFO("[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport);43574358wrqu->data.length = strlen(extra);4359return ret;43604361}43624363static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,4364struct iw_request_info *info,4365union iwreq_data *wrqu, char *extra)4366{43674368int ret = 0;4369_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4370struct wifidirect_info *pwdinfo = &(padapter->wdinfo);43714372sprintf(extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc);4373RTW_INFO("[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc);43744375wrqu->data.length = strlen(extra);4376pwdinfo->wfd_info->wfd_pc = _FALSE; /* Reset the WFD preferred connection to P2P */4377return ret;43784379}43804381static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,4382struct iw_request_info *info,4383union iwreq_data *wrqu, char *extra)4384{43854386int ret = 0;4387_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4388struct wifidirect_info *pwdinfo = &(padapter->wdinfo);43894390sprintf(extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail);4391RTW_INFO("[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail);43924393wrqu->data.length = strlen(extra);4394pwdinfo->wfd_info->peer_session_avail = _TRUE; /* Reset the WFD session available */4395return ret;43964397}4398#endif /* CONFIG_WFD */43994400static int rtw_p2p_get_go_device_address(struct net_device *dev,4401struct iw_request_info *info,4402union iwreq_data *wrqu, char *extra, char *subcmd)4403{44044405int ret = 0;4406_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4407u8 peerMAC[ETH_ALEN] = { 0x00 };4408struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4409_irqL irqL;4410_list *plist, *phead;4411_queue *queue = &(pmlmepriv->scanned_queue);4412struct wlan_network *pnetwork = NULL;4413u8 blnMatch = 0;4414u8 *p2pie;4415uint p2pielen = 0, attr_contentlen = 0;4416u8 attr_content[100] = { 0x00 };4417u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };44184419/* Commented by Albert 20121209 */4420/* The input data is the GO's interface address which the application wants to know its device address. */4421/* Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 */44224423RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);44244425macstr2num(peerMAC, subcmd);44264427_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);44284429phead = get_list_head(queue);4430plist = get_next(phead);44314432while (1) {4433if (rtw_end_of_queue_search(phead, plist) == _TRUE)4434break;44354436pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);4437if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {4438/* Commented by Albert 2011/05/18 */4439/* Match the device address located in the P2P IE */4440/* This is for the case that the P2P device address is not the same as the P2P interface address. */44414442p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);4443if (p2pie) {4444while (p2pie) {4445/* The P2P Device ID attribute is included in the Beacon frame. */4446/* The P2P Device Info attribute is included in the probe response frame. */44474448_rtw_memset(attr_content, 0x00, 100);4449if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {4450/* Handle the P2P Device ID attribute of Beacon first */4451blnMatch = 1;4452break;44534454} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {4455/* Handle the P2P Device Info attribute of probe response */4456blnMatch = 1;4457break;4458}44594460/* Get the next P2P IE */4461p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);4462}4463}4464}44654466plist = get_next(plist);44674468}44694470_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);44714472if (!blnMatch)4473sprintf(go_devadd_str, "\n\ndev_add=NULL");4474else {4475sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",4476attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);4477}44784479wrqu->data.length = strlen(go_devadd_str);4480_rtw_memcpy(extra, go_devadd_str, wrqu->data.length);44814482return ret;44834484}44854486static int rtw_p2p_get_device_type(struct net_device *dev,4487struct iw_request_info *info,4488union iwreq_data *wrqu, char *extra, char *subcmd)4489{44904491int ret = 0;4492_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4493u8 peerMAC[ETH_ALEN] = { 0x00 };4494struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4495_irqL irqL;4496_list *plist, *phead;4497_queue *queue = &(pmlmepriv->scanned_queue);4498struct wlan_network *pnetwork = NULL;4499u8 blnMatch = 0;4500u8 dev_type[8] = { 0x00 };4501uint dev_type_len = 0;4502u8 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 */45034504/* Commented by Albert 20121209 */4505/* The input data is the MAC address which the application wants to know its device type. */4506/* Such user interface could know the device type. */4507/* Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 */45084509RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);45104511macstr2num(peerMAC, subcmd);45124513_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);45144515phead = get_list_head(queue);4516plist = get_next(phead);45174518while (1) {4519if (rtw_end_of_queue_search(phead, plist) == _TRUE)4520break;45214522pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);4523if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {4524u8 *wpsie;4525uint wpsie_len = 0;45264527/* The mac address is matched. */45284529wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);4530if (wpsie) {4531rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);4532if (dev_type_len) {4533u16 type = 0;45344535_rtw_memcpy(&type, dev_type, 2);4536type = be16_to_cpu(type);4537sprintf(dev_type_str, "\n\nN=%.2d", type);4538blnMatch = 1;4539}4540}4541break;4542}45434544plist = get_next(plist);45454546}45474548_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);45494550if (!blnMatch)4551sprintf(dev_type_str, "\n\nN=00");45524553wrqu->data.length = strlen(dev_type_str);4554_rtw_memcpy(extra, dev_type_str, wrqu->data.length);45554556return ret;45574558}45594560static int rtw_p2p_get_device_name(struct net_device *dev,4561struct iw_request_info *info,4562union iwreq_data *wrqu, char *extra, char *subcmd)4563{45644565int ret = 0;4566_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4567u8 peerMAC[ETH_ALEN] = { 0x00 };4568struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4569_irqL irqL;4570_list *plist, *phead;4571_queue *queue = &(pmlmepriv->scanned_queue);4572struct wlan_network *pnetwork = NULL;4573u8 blnMatch = 0;4574u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };4575uint dev_len = 0;4576u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };45774578/* Commented by Albert 20121225 */4579/* The input data is the MAC address which the application wants to know its device name. */4580/* Such user interface could show peer device's device name instead of ssid. */4581/* Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 */45824583RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);45844585macstr2num(peerMAC, subcmd);45864587_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);45884589phead = get_list_head(queue);4590plist = get_next(phead);45914592while (1) {4593if (rtw_end_of_queue_search(phead, plist) == _TRUE)4594break;45954596pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);4597if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {4598u8 *wpsie;4599uint wpsie_len = 0;46004601/* The mac address is matched. */46024603wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);4604if (wpsie) {4605rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);4606if (dev_len) {4607sprintf(dev_name_str, "\n\nN=%s", dev_name);4608blnMatch = 1;4609}4610}4611break;4612}46134614plist = get_next(plist);46154616}46174618_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);46194620if (!blnMatch)4621sprintf(dev_name_str, "\n\nN=0000");46224623wrqu->data.length = strlen(dev_name_str);4624_rtw_memcpy(extra, dev_name_str, wrqu->data.length);46254626return ret;46274628}46294630static int rtw_p2p_get_invitation_procedure(struct net_device *dev,4631struct iw_request_info *info,4632union iwreq_data *wrqu, char *extra, char *subcmd)4633{46344635int ret = 0;4636_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4637u8 peerMAC[ETH_ALEN] = { 0x00 };4638struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4639_irqL irqL;4640_list *plist, *phead;4641_queue *queue = &(pmlmepriv->scanned_queue);4642struct wlan_network *pnetwork = NULL;4643u8 blnMatch = 0;4644u8 *p2pie;4645uint p2pielen = 0, attr_contentlen = 0;4646u8 attr_content[2] = { 0x00 };4647u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };46484649/* Commented by Ouden 20121226 */4650/* The application wants to know P2P initation procedure is support or not. */4651/* Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 */46524653RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);46544655macstr2num(peerMAC, subcmd);46564657_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);46584659phead = get_list_head(queue);4660plist = get_next(phead);46614662while (1) {4663if (rtw_end_of_queue_search(phead, plist) == _TRUE)4664break;46654666pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);4667if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {4668/* Commented by Albert 20121226 */4669/* Match the device address located in the P2P IE */4670/* This is for the case that the P2P device address is not the same as the P2P interface address. */46714672p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);4673if (p2pie) {4674while (p2pie) {4675/* _rtw_memset( attr_content, 0x00, 2); */4676if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {4677/* Handle the P2P capability attribute */4678blnMatch = 1;4679break;46804681}46824683/* Get the next P2P IE */4684p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);4685}4686}4687}46884689plist = get_next(plist);46904691}46924693_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);46944695if (!blnMatch)4696sprintf(inv_proc_str, "\nIP=-1");4697else {4698if ((attr_content[0] & 0x20) == 0x20)4699sprintf(inv_proc_str, "\nIP=1");4700else4701sprintf(inv_proc_str, "\nIP=0");4702}47034704wrqu->data.length = strlen(inv_proc_str);4705_rtw_memcpy(extra, inv_proc_str, wrqu->data.length);47064707return ret;47084709}47104711static int rtw_p2p_connect(struct net_device *dev,4712struct iw_request_info *info,4713union iwreq_data *wrqu, char *extra)4714{47154716int ret = 0;4717_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4718struct wifidirect_info *pwdinfo = &(padapter->wdinfo);4719u8 peerMAC[ETH_ALEN] = { 0x00 };4720int jj, kk;4721struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4722_irqL irqL;4723_list *plist, *phead;4724_queue *queue = &(pmlmepriv->scanned_queue);4725struct wlan_network *pnetwork = NULL;4726uint uintPeerChannel = 0;47274728/* Commented by Albert 20110304 */4729/* The input data contains two informations. */4730/* 1. First information is the MAC address which wants to formate with */4731/* 2. Second information is the WPS PINCode or "pbc" string for push button method */4732/* Format: 00:E0:4C:00:00:05 */4733/* Format: 00:E0:4C:00:00:05 */47344735RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);47364737if (pwdinfo->p2p_state == P2P_STATE_NONE) {4738RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);4739return ret;4740}47414742if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)4743return -1;47444745for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)4746peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);47474748_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);47494750phead = get_list_head(queue);4751plist = get_next(phead);47524753while (1) {4754if (rtw_end_of_queue_search(phead, plist) == _TRUE)4755break;47564757pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);4758if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {4759if (pnetwork->network.Configuration.DSConfig != 0)4760uintPeerChannel = pnetwork->network.Configuration.DSConfig;4761else if (pwdinfo->nego_req_info.peer_ch != 0)4762uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch;4763else {4764/* Unexpected case */4765uintPeerChannel = 0;4766RTW_INFO("%s uintPeerChannel = 0\n", __func__);4767}4768break;4769}47704771plist = get_next(plist);47724773}47744775_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);47764777if (uintPeerChannel) {4778#ifdef CONFIG_CONCURRENT_MODE4779if (rtw_mi_check_status(padapter, MI_LINKED))4780_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);4781#endif /* CONFIG_CONCURRENT_MODE */47824783_rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));4784_rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));47854786pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;4787_rtw_memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);4788pwdinfo->nego_req_info.benable = _TRUE;47894790_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);4791if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {4792/* Restore to the listen state if the current p2p state is not nego OK */4793rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);4794}47954796rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));4797rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);47984799#ifdef CONFIG_CONCURRENT_MODE4800if (rtw_mi_check_status(padapter, MI_LINKED)) {4801u8 union_ch = rtw_mi_get_union_chan(padapter);4802u8 union_bw = rtw_mi_get_union_bw(padapter);4803u8 union_offset = rtw_mi_get_union_offset(padapter);48044805set_channel_bwmode(padapter, union_ch, union_offset, union_bw);4806rtw_leave_opch(padapter);4807}4808#endif /* CONFIG_CONCURRENT_MODE */48094810RTW_INFO("[%s] Start PreTx Procedure!\n", __FUNCTION__);4811_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);4812#ifdef CONFIG_CONCURRENT_MODE4813if (rtw_mi_check_status(padapter, MI_LINKED))4814_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT);4815else4816_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);4817#else4818_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);4819#endif /* CONFIG_CONCURRENT_MODE */48204821} else {4822RTW_INFO("[%s] Not Found in Scanning Queue~\n", __FUNCTION__);4823ret = -1;4824}48254826return ret;4827}48284829static int rtw_p2p_invite_req(struct net_device *dev,4830struct iw_request_info *info,4831union iwreq_data *wrqu, char *extra)4832{48334834int ret = 0;4835_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);4836struct wifidirect_info *pwdinfo = &(padapter->wdinfo);4837int jj, kk;4838struct mlme_priv *pmlmepriv = &padapter->mlmepriv;4839_list *plist, *phead;4840_queue *queue = &(pmlmepriv->scanned_queue);4841struct wlan_network *pnetwork = NULL;4842uint uintPeerChannel = 0;4843u8 attr_content[50] = { 0x00 };4844u8 *p2pie;4845uint p2pielen = 0, attr_contentlen = 0;4846_irqL irqL;4847struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;48484849/* Commented by Albert 20120321 */4850/* The input data contains two informations. */4851/* 1. First information is the P2P device address which you want to send to. */4852/* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */4853/* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */4854/* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */48554856RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);48574858if (wrqu->data.length <= 37) {4859RTW_INFO("[%s] Wrong format!\n", __FUNCTION__);4860return ret;4861}48624863if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {4864RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);4865return ret;4866} else {4867/* Reset the content of struct tx_invite_req_info */4868pinvite_req_info->benable = _FALSE;4869_rtw_memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);4870_rtw_memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);4871pinvite_req_info->ssidlen = 0x00;4872pinvite_req_info->operating_ch = pwdinfo->operating_channel;4873_rtw_memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);4874pinvite_req_info->token = 3;4875}48764877for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)4878pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);48794880_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);48814882phead = get_list_head(queue);4883plist = get_next(phead);48844885while (1) {4886if (rtw_end_of_queue_search(phead, plist) == _TRUE)4887break;48884889pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);48904891/* Commented by Albert 2011/05/18 */4892/* Match the device address located in the P2P IE */4893/* This is for the case that the P2P device address is not the same as the P2P interface address. */48944895p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);4896if (p2pie) {4897/* The P2P Device ID attribute is included in the Beacon frame. */4898/* The P2P Device Info attribute is included in the probe response frame. */48994900if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {4901/* Handle the P2P Device ID attribute of Beacon first */4902if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {4903uintPeerChannel = pnetwork->network.Configuration.DSConfig;4904break;4905}4906} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {4907/* Handle the P2P Device Info attribute of probe response */4908if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {4909uintPeerChannel = pnetwork->network.Configuration.DSConfig;4910break;4911}4912}49134914}49154916plist = get_next(plist);49174918}49194920_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);49214922#ifdef CONFIG_WFD4923if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) {4924struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;4925u8 *wfd_ie;4926uint wfd_ielen = 0;49274928wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);4929if (wfd_ie) {4930u8 *wfd_devinfo;4931uint wfd_devlen;49324933RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);4934wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);4935if (wfd_devinfo) {4936u16 wfd_devinfo_field = 0;49374938/* Commented by Albert 20120319 */4939/* The first two bytes are the WFD device information field of WFD device information subelement. */4940/* In big endian format. */4941wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);4942if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)4943pwfd_info->peer_session_avail = _TRUE;4944else4945pwfd_info->peer_session_avail = _FALSE;4946}4947}49484949if (_FALSE == pwfd_info->peer_session_avail) {4950RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);4951goto exit;4952}4953}4954#endif /* CONFIG_WFD */49554956if (uintPeerChannel) {4957#ifdef CONFIG_CONCURRENT_MODE4958if (rtw_mi_check_status(padapter, MI_LINKED))4959_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);4960#endif /* CONFIG_CONCURRENT_MODE */49614962/* Store the GO's bssid */4963for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)4964pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);49654966/* Store the GO's ssid */4967pinvite_req_info->ssidlen = wrqu->data.length - 36;4968_rtw_memcpy(pinvite_req_info->go_ssid, &extra[36], (u32) pinvite_req_info->ssidlen);4969pinvite_req_info->benable = _TRUE;4970pinvite_req_info->peer_ch = uintPeerChannel;49714972rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));4973rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);49744975#ifdef CONFIG_CONCURRENT_MODE4976if (rtw_mi_check_status(padapter, MI_LINKED)) {4977u8 union_ch = rtw_mi_get_union_chan(padapter);4978u8 union_bw = rtw_mi_get_union_bw(padapter);4979u8 union_offset = rtw_mi_get_union_offset(padapter);49804981set_channel_bwmode(padapter, union_ch, union_offset, union_bw);4982rtw_leave_opch(padapter);49834984} else4985set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);4986#else4987set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);4988#endif/*CONFIG_CONCURRENT_MODE*/49894990_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);49914992#ifdef CONFIG_CONCURRENT_MODE4993if (rtw_mi_check_status(padapter, MI_LINKED))4994_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT);4995else4996_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);4997#else4998_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);4999#endif /* CONFIG_CONCURRENT_MODE */500050015002} else5003RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);5004exit:50055006return ret;50075008}50095010static int rtw_p2p_set_persistent(struct net_device *dev,5011struct iw_request_info *info,5012union iwreq_data *wrqu, char *extra)5013{50145015int ret = 0;5016_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5017struct wifidirect_info *pwdinfo = &(padapter->wdinfo);50185019/* Commented by Albert 20120328 */5020/* The input data is 0 or 1 */5021/* 0: disable persistent group functionality */5022/* 1: enable persistent group founctionality */50235024RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);50255026if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {5027RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);5028return ret;5029} else {5030if (extra[0] == '0') /* Disable the persistent group function. */5031pwdinfo->persistent_supported = _FALSE;5032else if (extra[0] == '1') /* Enable the persistent group function. */5033pwdinfo->persistent_supported = _TRUE;5034else5035pwdinfo->persistent_supported = _FALSE;5036}5037printk("[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported);50385039return ret;50405041}50425043static int uuid_str2bin(const char *str, u8 *bin)5044{5045const char *pos;5046u8 *opos;50475048pos = str;5049opos = bin;50505051if (hexstr2bin(pos, opos, 4))5052return -1;5053pos += 8;5054opos += 4;50555056if (*pos++ != '-' || hexstr2bin(pos, opos, 2))5057return -1;5058pos += 4;5059opos += 2;50605061if (*pos++ != '-' || hexstr2bin(pos, opos, 2))5062return -1;5063pos += 4;5064opos += 2;50655066if (*pos++ != '-' || hexstr2bin(pos, opos, 2))5067return -1;5068pos += 4;5069opos += 2;50705071if (*pos++ != '-' || hexstr2bin(pos, opos, 6))5072return -1;50735074return 0;5075}50765077static int rtw_p2p_set_wps_uuid(struct net_device *dev,5078struct iw_request_info *info,5079union iwreq_data *wrqu, char *extra)5080{50815082int ret = 0;5083_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5084struct wifidirect_info *pwdinfo = &(padapter->wdinfo);50855086RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);50875088if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))5089pwdinfo->external_uuid = 1;5090else {5091pwdinfo->external_uuid = 0;5092ret = -EINVAL;5093}50945095return ret;50965097}5098#ifdef CONFIG_WFD5099static int rtw_p2p_set_pc(struct net_device *dev,5100struct iw_request_info *info,5101union iwreq_data *wrqu, char *extra)5102{51035104int ret = 0;5105_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5106struct wifidirect_info *pwdinfo = &(padapter->wdinfo);5107u8 peerMAC[ETH_ALEN] = { 0x00 };5108int jj, kk;5109struct mlme_priv *pmlmepriv = &padapter->mlmepriv;5110_list *plist, *phead;5111_queue *queue = &(pmlmepriv->scanned_queue);5112struct wlan_network *pnetwork = NULL;5113u8 attr_content[50] = { 0x00 };5114u8 *p2pie;5115uint p2pielen = 0, attr_contentlen = 0;5116_irqL irqL;5117uint uintPeerChannel = 0;51185119struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;51205121/* Commented by Albert 20120512 */5122/* 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) */5123/* Format: 00:E0:4C:00:00:05 */51245125RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);51265127if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {5128RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);5129return ret;5130}51315132for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)5133peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);51345135_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);51365137phead = get_list_head(queue);5138plist = get_next(phead);51395140while (1) {5141if (rtw_end_of_queue_search(phead, plist) == _TRUE)5142break;51435144pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);51455146/* Commented by Albert 2011/05/18 */5147/* Match the device address located in the P2P IE */5148/* This is for the case that the P2P device address is not the same as the P2P interface address. */51495150p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);5151if (p2pie) {5152/* The P2P Device ID attribute is included in the Beacon frame. */5153/* The P2P Device Info attribute is included in the probe response frame. */5154printk("[%s] Got P2P IE\n", __FUNCTION__);5155if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {5156/* Handle the P2P Device ID attribute of Beacon first */5157printk("[%s] P2P_ATTR_DEVICE_ID\n", __FUNCTION__);5158if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {5159uintPeerChannel = pnetwork->network.Configuration.DSConfig;5160break;5161}5162} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {5163/* Handle the P2P Device Info attribute of probe response */5164printk("[%s] P2P_ATTR_DEVICE_INFO\n", __FUNCTION__);5165if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {5166uintPeerChannel = pnetwork->network.Configuration.DSConfig;5167break;5168}5169}51705171}51725173plist = get_next(plist);51745175}51765177_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);5178printk("[%s] channel = %d\n", __FUNCTION__, uintPeerChannel);51795180if (uintPeerChannel) {5181u8 *wfd_ie;5182uint wfd_ielen = 0;51835184wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);5185if (wfd_ie) {5186u8 *wfd_devinfo;5187uint wfd_devlen;51885189RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);5190wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);5191if (wfd_devinfo) {5192u16 wfd_devinfo_field = 0;51935194/* Commented by Albert 20120319 */5195/* The first two bytes are the WFD device information field of WFD device information subelement. */5196/* In big endian format. */5197wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);5198if (wfd_devinfo_field & WFD_DEVINFO_PC_TDLS)5199pwfd_info->wfd_pc = _TRUE;5200else5201pwfd_info->wfd_pc = _FALSE;5202}5203}5204} else5205RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);52065207return ret;52085209}52105211static int rtw_p2p_set_wfd_device_type(struct net_device *dev,5212struct iw_request_info *info,5213union iwreq_data *wrqu, char *extra)5214{52155216int ret = 0;5217_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5218struct wifidirect_info *pwdinfo = &(padapter->wdinfo);5219struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;52205221/* Commented by Albert 20120328 */5222/* The input data is 0 or 1 */5223/* 0: specify to Miracast source device */5224/* 1 or others: specify to Miracast sink device (display device) */52255226RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);52275228if (extra[0] == '0') /* Set to Miracast source device. */5229pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;5230else /* Set to Miracast sink device. */5231pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;52325233return ret;52345235}52365237static int rtw_p2p_set_wfd_enable(struct net_device *dev,5238struct iw_request_info *info,5239union iwreq_data *wrqu, char *extra)5240{5241/* Commented by Kurt 201212065242* This function is used to set wfd enabled */52435244int ret = 0;5245_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5246struct wifidirect_info *pwdinfo = &(padapter->wdinfo);52475248if (*extra == '0')5249rtw_wfd_enable(padapter, 0);5250else if (*extra == '1')5251rtw_wfd_enable(padapter, 1);52525253RTW_INFO("[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable);52545255return ret;52565257}52585259static int rtw_p2p_set_driver_iface(struct net_device *dev,5260struct iw_request_info *info,5261union iwreq_data *wrqu, char *extra)5262{5263/* Commented by Kurt 201212065264* This function is used to set driver iface is WEXT or CFG80211 */5265int ret = 0;5266_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5267struct wifidirect_info *pwdinfo = &(padapter->wdinfo);52685269if (*extra == '1') {5270pwdinfo->driver_interface = DRIVER_WEXT;5271RTW_INFO("[%s] driver_interface = WEXT\n", __FUNCTION__);5272} else if (*extra == '2') {5273pwdinfo->driver_interface = DRIVER_CFG80211;5274RTW_INFO("[%s] driver_interface = CFG80211\n", __FUNCTION__);5275}52765277return ret;52785279}52805281/* To set the WFD session available to enable or disable */5282static int rtw_p2p_set_sa(struct net_device *dev,5283struct iw_request_info *info,5284union iwreq_data *wrqu, char *extra)5285{52865287int ret = 0;5288_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5289struct wifidirect_info *pwdinfo = &(padapter->wdinfo);52905291RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);52925293if (0) {5294RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);5295return ret;5296} else {5297if (extra[0] == '0') /* Disable the session available. */5298pwdinfo->session_available = _FALSE;5299else if (extra[0] == '1') /* Enable the session available. */5300pwdinfo->session_available = _TRUE;5301else5302pwdinfo->session_available = _FALSE;5303}5304printk("[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available);53055306return ret;53075308}5309#endif /* CONFIG_WFD */53105311static int rtw_p2p_prov_disc(struct net_device *dev,5312struct iw_request_info *info,5313union iwreq_data *wrqu, char *extra)5314{5315int ret = 0;5316_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5317struct wifidirect_info *pwdinfo = &(padapter->wdinfo);5318u8 peerMAC[ETH_ALEN] = { 0x00 };5319int jj, kk;5320struct mlme_priv *pmlmepriv = &padapter->mlmepriv;5321_list *plist, *phead;5322_queue *queue = &(pmlmepriv->scanned_queue);5323struct wlan_network *pnetwork = NULL;5324uint uintPeerChannel = 0;5325u8 attr_content[100] = { 0x00 };5326u8 *p2pie;5327uint p2pielen = 0, attr_contentlen = 0;5328_irqL irqL;53295330/* Commented by Albert 20110301 */5331/* The input data contains two informations. */5332/* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */5333/* 2. Second information is the WPS configuration method which wants to discovery */5334/* Format: 00:E0:4C:00:00:05_display */5335/* Format: 00:E0:4C:00:00:05_keypad */5336/* Format: 00:E0:4C:00:00:05_pbc */5337/* Format: 00:E0:4C:00:00:05_label */53385339RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);53405341if (pwdinfo->p2p_state == P2P_STATE_NONE) {5342RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);5343return ret;5344} else {5345/* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */5346_rtw_memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);5347_rtw_memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);5348_rtw_memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(NDIS_802_11_SSID));5349pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;5350pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;5351pwdinfo->tx_prov_disc_info.benable = _FALSE;5352}53535354for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)5355peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);53565357if (_rtw_memcmp(&extra[18], "display", 7))5358pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;5359else if (_rtw_memcmp(&extra[18], "keypad", 7))5360pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;5361else if (_rtw_memcmp(&extra[18], "pbc", 3))5362pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;5363else if (_rtw_memcmp(&extra[18], "label", 5))5364pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;5365else {5366RTW_INFO("[%s] Unknown WPS config methodn", __FUNCTION__);5367return ret ;5368}53695370_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);53715372phead = get_list_head(queue);5373plist = get_next(phead);53745375while (1) {5376if (rtw_end_of_queue_search(phead, plist) == _TRUE)5377break;53785379if (uintPeerChannel != 0)5380break;53815382pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);53835384/* Commented by Albert 2011/05/18 */5385/* Match the device address located in the P2P IE */5386/* This is for the case that the P2P device address is not the same as the P2P interface address. */53875388p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);5389if (p2pie) {5390while (p2pie) {5391/* The P2P Device ID attribute is included in the Beacon frame. */5392/* The P2P Device Info attribute is included in the probe response frame. */53935394if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {5395/* Handle the P2P Device ID attribute of Beacon first */5396if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {5397uintPeerChannel = pnetwork->network.Configuration.DSConfig;5398break;5399}5400} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {5401/* Handle the P2P Device Info attribute of probe response */5402if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {5403uintPeerChannel = pnetwork->network.Configuration.DSConfig;5404break;5405}5406}54075408/* Get the next P2P IE */5409p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);5410}54115412}54135414plist = get_next(plist);54155416}54175418_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);54195420if (uintPeerChannel) {5421#ifdef CONFIG_WFD5422if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {5423struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;5424u8 *wfd_ie;5425uint wfd_ielen = 0;54265427wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);5428if (wfd_ie) {5429u8 *wfd_devinfo;5430uint wfd_devlen;54315432RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);5433wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);5434if (wfd_devinfo) {5435u16 wfd_devinfo_field = 0;54365437/* Commented by Albert 20120319 */5438/* The first two bytes are the WFD device information field of WFD device information subelement. */5439/* In big endian format. */5440wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);5441if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)5442pwfd_info->peer_session_avail = _TRUE;5443else5444pwfd_info->peer_session_avail = _FALSE;5445}5446}54475448if (_FALSE == pwfd_info->peer_session_avail) {5449RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);5450goto exit;5451}5452}5453#endif /* CONFIG_WFD */54545455RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel);5456#ifdef CONFIG_CONCURRENT_MODE5457if (rtw_mi_check_status(padapter, MI_LINKED))5458_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);5459#endif /* CONFIG_CONCURRENT_MODE */5460_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);5461_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);5462pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16) uintPeerChannel;5463pwdinfo->tx_prov_disc_info.benable = _TRUE;5464rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));5465rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);54665467if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))5468_rtw_memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));5469else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {5470_rtw_memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);5471pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;5472}54735474#ifdef CONFIG_CONCURRENT_MODE5475if (rtw_mi_check_status(padapter, MI_LINKED)) {5476u8 union_ch = rtw_mi_get_union_chan(padapter);5477u8 union_bw = rtw_mi_get_union_bw(padapter);5478u8 union_offset = rtw_mi_get_union_offset(padapter);54795480set_channel_bwmode(padapter, union_ch, union_offset, union_bw);5481rtw_leave_opch(padapter);54825483} else5484set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);5485#else5486set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);5487#endif54885489_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);54905491#ifdef CONFIG_CONCURRENT_MODE5492if (rtw_mi_check_status(padapter, MI_LINKED))5493_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT);5494else5495_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);5496#else5497_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);5498#endif /* CONFIG_CONCURRENT_MODE */54995500} else {5501RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);5502}5503exit:55045505return ret;55065507}55085509/* Added by Albert 201103285510* This function is used to inform the driver the user had specified the pin code value or pbc5511* to application. */55125513static int rtw_p2p_got_wpsinfo(struct net_device *dev,5514struct iw_request_info *info,5515union iwreq_data *wrqu, char *extra)5516{55175518int ret = 0;5519_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5520struct wifidirect_info *pwdinfo = &(padapter->wdinfo);552155225523RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);5524/* Added by Albert 20110328 */5525/* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */5526/* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */5527/* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */5528/* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */55295530if (*extra == '0')5531pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;5532else if (*extra == '1')5533pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;5534else if (*extra == '2')5535pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;5536else if (*extra == '3')5537pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;5538else5539pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;55405541return ret;55425543}55445545#endif /* CONFIG_P2P */55465547static int rtw_p2p_set(struct net_device *dev,5548struct iw_request_info *info,5549union iwreq_data *wrqu, char *extra)5550{5551int ret = 0;5552#ifdef CONFIG_P2P5553_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);55545555RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);55565557if (_rtw_memcmp(extra, "enable=", 7))5558rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);5559else if (_rtw_memcmp(extra, "setDN=", 6)) {5560wrqu->data.length -= 6;5561rtw_p2p_setDN(dev, info, wrqu, &extra[6]);5562} else if (_rtw_memcmp(extra, "profilefound=", 13)) {5563wrqu->data.length -= 13;5564rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);5565} else if (_rtw_memcmp(extra, "prov_disc=", 10)) {5566wrqu->data.length -= 10;5567rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);5568} else if (_rtw_memcmp(extra, "nego=", 5)) {5569wrqu->data.length -= 5;5570rtw_p2p_connect(dev, info, wrqu, &extra[5]);5571} else if (_rtw_memcmp(extra, "intent=", 7)) {5572/* Commented by Albert 2011/03/23 */5573/* The wrqu->data.length will include the null character */5574/* So, we will decrease 7 + 1 */5575wrqu->data.length -= 8;5576rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);5577} else if (_rtw_memcmp(extra, "ssid=", 5)) {5578wrqu->data.length -= 5;5579rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);5580} else if (_rtw_memcmp(extra, "got_wpsinfo=", 12)) {5581wrqu->data.length -= 12;5582rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);5583} else if (_rtw_memcmp(extra, "listen_ch=", 10)) {5584/* Commented by Albert 2011/05/24 */5585/* The wrqu->data.length will include the null character */5586/* So, we will decrease (10 + 1) */5587wrqu->data.length -= 11;5588rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);5589} else if (_rtw_memcmp(extra, "op_ch=", 6)) {5590/* Commented by Albert 2011/05/24 */5591/* The wrqu->data.length will include the null character */5592/* So, we will decrease (6 + 1) */5593wrqu->data.length -= 7;5594rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);5595} else if (_rtw_memcmp(extra, "invite=", 7)) {5596wrqu->data.length -= 8;5597rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);5598} else if (_rtw_memcmp(extra, "persistent=", 11)) {5599wrqu->data.length -= 11;5600rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);5601} else if (_rtw_memcmp(extra, "uuid=", 5)) {5602wrqu->data.length -= 5;5603ret = rtw_p2p_set_wps_uuid(dev, info, wrqu, &extra[5]);5604}56055606#ifdef CONFIG_WFD5607if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {5608if (_rtw_memcmp(extra, "sa=", 3)) {5609/* sa: WFD Session Available information */5610wrqu->data.length -= 3;5611rtw_p2p_set_sa(dev, info, wrqu, &extra[3]);5612} else if (_rtw_memcmp(extra, "pc=", 3)) {5613/* pc: WFD Preferred Connection */5614wrqu->data.length -= 3;5615rtw_p2p_set_pc(dev, info, wrqu, &extra[3]);5616} else if (_rtw_memcmp(extra, "wfd_type=", 9)) {5617wrqu->data.length -= 9;5618rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]);5619} else if (_rtw_memcmp(extra, "wfd_enable=", 11)) {5620wrqu->data.length -= 11;5621rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]);5622} else if (_rtw_memcmp(extra, "driver_iface=", 13)) {5623wrqu->data.length -= 13;5624rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]);5625}5626}5627#endif /* CONFIG_WFD */56285629#endif /* CONFIG_P2P */56305631return ret;56325633}56345635static int rtw_p2p_get(struct net_device *dev,5636struct iw_request_info *info,5637union iwreq_data *wrqu, char *extra)5638{5639int ret = 0;5640#ifdef CONFIG_P2P5641_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);56425643if (padapter->bShowGetP2PState)5644RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);56455646if (_rtw_memcmp(wrqu->data.pointer, "status", 6))5647rtw_p2p_get_status(dev, info, wrqu, extra);5648else if (_rtw_memcmp(wrqu->data.pointer, "role", 4))5649rtw_p2p_get_role(dev, info, wrqu, extra);5650else if (_rtw_memcmp(wrqu->data.pointer, "peer_ifa", 8))5651rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);5652else if (_rtw_memcmp(wrqu->data.pointer, "req_cm", 6))5653rtw_p2p_get_req_cm(dev, info, wrqu, extra);5654else if (_rtw_memcmp(wrqu->data.pointer, "peer_deva", 9)) {5655/* Get the P2P device address when receiving the provision discovery request frame. */5656rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);5657} else if (_rtw_memcmp(wrqu->data.pointer, "group_id", 8))5658rtw_p2p_get_groupid(dev, info, wrqu, extra);5659else if (_rtw_memcmp(wrqu->data.pointer, "inv_peer_deva", 13)) {5660/* Get the P2P device address when receiving the P2P Invitation request frame. */5661rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);5662} else if (_rtw_memcmp(wrqu->data.pointer, "op_ch", 5))5663rtw_p2p_get_op_ch(dev, info, wrqu, extra);56645665#ifdef CONFIG_WFD5666if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {5667if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9))5668rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra);5669else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6))5670rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra);5671else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6))5672rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra);5673}5674#endif /* CONFIG_WFD */56755676#endif /* CONFIG_P2P */56775678return ret;56795680}56815682static int rtw_p2p_get2(struct net_device *dev,5683struct iw_request_info *info,5684union iwreq_data *wrqu, char *extra)5685{56865687int ret = 0;56885689#ifdef CONFIG_P2P56905691int length = wrqu->data.length;5692char *buffer = (u8 *)rtw_malloc(length);56935694if (buffer == NULL) {5695ret = -ENOMEM;5696goto bad;5697}56985699if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) {5700ret = -EFAULT;5701goto bad;5702}57035704RTW_INFO("[%s] buffer = %s\n", __FUNCTION__, buffer);57055706if (_rtw_memcmp(buffer, "wpsCM=", 6))5707ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);5708else if (_rtw_memcmp(buffer, "devN=", 5))5709ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);5710else if (_rtw_memcmp(buffer, "dev_type=", 9))5711ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);5712else if (_rtw_memcmp(buffer, "go_devadd=", 10))5713ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);5714else if (_rtw_memcmp(buffer, "InvProc=", 8))5715ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);5716else {5717snprintf(extra, sizeof("Command not found."), "Command not found.");5718wrqu->data.length = strlen(extra);5719}57205721bad:5722if (buffer)5723rtw_mfree(buffer, length);57245725#endif /* CONFIG_P2P */57265727return ret;57285729}57305731#ifdef CONFIG_MP_INCLUDED5732static int rtw_cta_test_start(struct net_device *dev,5733struct iw_request_info *info,5734union iwreq_data *wrqu, char *extra)5735{5736int ret = 0;5737_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5738HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);57395740RTW_INFO("%s %s\n", __func__, extra);5741if (!strcmp(extra, "1"))5742hal_data->in_cta_test = 1;5743else5744hal_data->in_cta_test = 0;57455746rtw_hal_rcr_set_chk_bssid(padapter, MLME_ACTION_NONE);57475748return ret;5749}5750#endif5751extern int rtw_change_ifname(_adapter *padapter, const char *ifname);5752static int rtw_rereg_nd_name(struct net_device *dev,5753struct iw_request_info *info,5754union iwreq_data *wrqu, char *extra)5755{5756int ret = 0;5757_adapter *padapter = rtw_netdev_priv(dev);5758struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);5759struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;5760char new_ifname[IFNAMSIZ];57615762if (rereg_priv->old_ifname[0] == 0) {5763char *reg_ifname;5764#ifdef CONFIG_CONCURRENT_MODE5765if (padapter->isprimary)5766reg_ifname = padapter->registrypriv.ifname;5767else5768#endif5769reg_ifname = padapter->registrypriv.if2name;57705771strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);5772rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;5773}57745775/* RTW_INFO("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); */5776if (wrqu->data.length > IFNAMSIZ)5777return -EFAULT;57785779if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))5780return -EFAULT;57815782if (0 == strcmp(rereg_priv->old_ifname, new_ifname))5783return ret;57845785RTW_INFO("%s new_ifname:%s\n", __FUNCTION__, new_ifname);5786rtw_set_rtnl_lock_holder(dvobj, current);5787ret = rtw_change_ifname(padapter, new_ifname);5788rtw_set_rtnl_lock_holder(dvobj, NULL);5789if (0 != ret)5790goto exit;57915792if (_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {5793/* rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); */5794}57955796strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);5797rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;57985799if (_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {58005801RTW_INFO("%s disable\n", __FUNCTION__);5802/* free network queue for Android's timming issue */5803rtw_free_network_queue(padapter, _TRUE);58045805/* the interface is being "disabled", we can do deeper IPS */5806/* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */5807/* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */5808}5809exit:5810return ret;58115812}58135814#ifdef CONFIG_IOL5815#include <rtw_iol.h>5816#endif5817#ifdef CONFIG_BACKGROUND_NOISE_MONITOR5818#include "../../hal/hal_dm_acs.h"5819#endif5820#ifdef DBG_CMD_QUEUE5821u8 dump_cmd_id = 0;5822#endif58235824static int rtw_dbg_port(struct net_device *dev,5825struct iw_request_info *info,5826union iwreq_data *wrqu, char *extra)5827{5828_irqL irqL;5829int ret = 0;5830u8 major_cmd, minor_cmd;5831u16 arg;5832u32 extra_arg, *pdata, val32;5833struct sta_info *psta;5834_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);5835struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);5836struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;5837struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);5838struct security_priv *psecuritypriv = &padapter->securitypriv;5839struct wlan_network *cur_network = &(pmlmepriv->cur_network);5840struct sta_priv *pstapriv = &padapter->stapriv;584158425843pdata = (u32 *)&wrqu->data;58445845val32 = *pdata;5846arg = (u16)(val32 & 0x0000ffff);5847major_cmd = (u8)(val32 >> 24);5848minor_cmd = (u8)((val32 >> 16) & 0x00ff);58495850extra_arg = *(pdata + 1);58515852switch (major_cmd) {5853case 0x70: /* read_reg */5854switch (minor_cmd) {5855case 1:5856RTW_INFO("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));5857break;5858case 2:5859RTW_INFO("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));5860break;5861case 4:5862RTW_INFO("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));5863break;5864}5865break;5866case 0x71: /* write_reg */5867switch (minor_cmd) {5868case 1:5869rtw_write8(padapter, arg, extra_arg);5870RTW_INFO("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));5871break;5872case 2:5873rtw_write16(padapter, arg, extra_arg);5874RTW_INFO("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));5875break;5876case 4:5877rtw_write32(padapter, arg, extra_arg);5878RTW_INFO("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));5879break;5880}5881break;5882case 0x72: /* read_bb */5883RTW_INFO("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));5884break;5885case 0x73: /* write_bb */5886rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);5887RTW_INFO("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));5888break;5889case 0x74: /* read_rf */5890RTW_INFO("read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));5891break;5892case 0x75: /* write_rf */5893rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);5894RTW_INFO("write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));5895break;58965897case 0x76:5898switch (minor_cmd) {5899case 0x00: /* normal mode, */5900padapter->recvpriv.is_signal_dbg = 0;5901break;5902case 0x01: /* dbg mode */5903padapter->recvpriv.is_signal_dbg = 1;5904extra_arg = extra_arg > 100 ? 100 : extra_arg;5905padapter->recvpriv.signal_strength_dbg = extra_arg;5906break;5907}5908break;5909case 0x78: /* IOL test */5910switch (minor_cmd) {5911#ifdef CONFIG_IOL5912case 0x04: { /* LLT table initialization test */5913u8 page_boundary = 0xf9;5914{5915struct xmit_frame *xmit_frame;59165917xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);5918if (xmit_frame == NULL) {5919ret = -ENOMEM;5920break;5921}59225923rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);592459255926if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))5927ret = -EPERM;5928}5929}5930break;5931case 0x05: { /* blink LED test */5932u16 reg = 0x4c;5933u32 blink_num = 50;5934u32 blink_delay_ms = 200;5935int i;59365937{5938struct xmit_frame *xmit_frame;59395940xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);5941if (xmit_frame == NULL) {5942ret = -ENOMEM;5943break;5944}59455946for (i = 0; i < blink_num; i++) {5947#ifdef CONFIG_IOL_NEW_GENERATION5948rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);5949rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);5950rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);5951rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);5952#else5953rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);5954rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);5955rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);5956rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);5957#endif5958}5959if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0))5960ret = -EPERM;5961}5962}5963break;59645965case 0x06: { /* continuous wirte byte test */5966u16 reg = arg;5967u16 start_value = 0;5968u32 write_num = extra_arg;5969int i;5970u8 final;59715972{5973struct xmit_frame *xmit_frame;59745975xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);5976if (xmit_frame == NULL) {5977ret = -ENOMEM;5978break;5979}59805981for (i = 0; i < write_num; i++) {5982#ifdef CONFIG_IOL_NEW_GENERATION5983rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);5984#else5985rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value);5986#endif5987}5988if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))5989ret = -EPERM;5990}59915992final = rtw_read8(padapter, reg);5993if (start_value + write_num - 1 == final)5994RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);5995else5996RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);5997}5998break;59996000case 0x07: { /* continuous wirte word test */6001u16 reg = arg;6002u16 start_value = 200;6003u32 write_num = extra_arg;60046005int i;6006u16 final;60076008{6009struct xmit_frame *xmit_frame;60106011xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);6012if (xmit_frame == NULL) {6013ret = -ENOMEM;6014break;6015}60166017for (i = 0; i < write_num; i++) {6018#ifdef CONFIG_IOL_NEW_GENERATION6019rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);6020#else6021rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value);6022#endif6023}6024if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))6025ret = -EPERM;6026}60276028final = rtw_read16(padapter, reg);6029if (start_value + write_num - 1 == final)6030RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);6031else6032RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);6033}6034break;60356036case 0x08: { /* continuous wirte dword test */6037u16 reg = arg;6038u32 start_value = 0x110000c7;6039u32 write_num = extra_arg;60406041int i;6042u32 final;60436044{6045struct xmit_frame *xmit_frame;60466047xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);6048if (xmit_frame == NULL) {6049ret = -ENOMEM;6050break;6051}60526053for (i = 0; i < write_num; i++) {6054#ifdef CONFIG_IOL_NEW_GENERATION6055rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);6056#else6057rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value);6058#endif6059}6060if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))6061ret = -EPERM;60626063}60646065final = rtw_read32(padapter, reg);6066if (start_value + write_num - 1 == final)6067RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);6068else6069RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);6070}6071break;6072#endif /* CONFIG_IOL */6073}6074break;6075case 0x79: {6076/*6077* dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~156078* dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~156079*/6080u8 value = extra_arg & 0x0f;6081u8 sign = minor_cmd;6082u16 write_value = 0;60836084RTW_INFO("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);60856086if (sign)6087value = value | 0x10;60886089write_value = value | (value << 5);6090rtw_write16(padapter, 0x6d9, write_value);6091}6092break;6093case 0x7a:6094receive_disconnect(padapter, pmlmeinfo->network.MacAddress6095, WLAN_REASON_EXPIRATION_CHK, _FALSE);6096break;6097case 0x7F:6098switch (minor_cmd) {6099case 0x0:6100RTW_INFO("fwstate=0x%x\n", get_fwstate(pmlmepriv));6101break;6102case 0x01:6103RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",6104psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,6105psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);6106break;6107case 0x03:6108RTW_INFO("qos_option=%d\n", pmlmepriv->qospriv.qos_option);6109#ifdef CONFIG_80211N_HT6110RTW_INFO("ht_option=%d\n", pmlmepriv->htpriv.ht_option);6111#endif /* CONFIG_80211N_HT */6112break;6113case 0x04:6114RTW_INFO("cur_ch=%d\n", pmlmeext->cur_channel);6115RTW_INFO("cur_bw=%d\n", pmlmeext->cur_bwmode);6116RTW_INFO("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);61176118RTW_INFO("oper_ch=%d\n", rtw_get_oper_ch(padapter));6119RTW_INFO("oper_bw=%d\n", rtw_get_oper_bw(padapter));6120RTW_INFO("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));61216122break;6123case 0x05:6124psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);6125if (psta) {6126RTW_INFO("SSID=%s\n", cur_network->network.Ssid.Ssid);6127RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));6128RTW_INFO("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);6129RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);6130RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",6131psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);6132#ifdef CONFIG_80211N_HT6133RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);6134RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n"6135, psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);6136RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);6137RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);6138#endif /* CONFIG_80211N_HT */61396140sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);6141} else6142RTW_INFO("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));6143break;6144case 0x06: {6145u64 tsf = 0;61466147tsf = rtw_hal_get_tsftr_by_port(padapter, extra_arg);6148RTW_INFO(" PORT-%d TSF :%21lld\n", extra_arg, tsf);6149}6150break;6151case 0x07:6152RTW_INFO("bSurpriseRemoved=%s, bDriverStopped=%s\n"6153, rtw_is_surprise_removed(padapter) ? "True" : "False"6154, rtw_is_drv_stopped(padapter) ? "True" : "False");6155break;6156case 0x08: {6157struct xmit_priv *pxmitpriv = &padapter->xmitpriv;6158struct recv_priv *precvpriv = &padapter->recvpriv;61596160RTW_INFO("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"6161", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"6162", free_recvframe_cnt=%d\n",6163pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,6164pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,6165precvpriv->free_recvframe_cnt);6166#ifdef CONFIG_USB_HCI6167RTW_INFO("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt)));6168#endif6169}6170break;6171case 0x09: {6172int i;6173_list *plist, *phead;61746175#ifdef CONFIG_AP_MODE6176RTW_INFO_DUMP("sta_dz_bitmap:", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len);6177RTW_INFO_DUMP("tim_bitmap:", pstapriv->tim_bitmap, pstapriv->aid_bmp_len);6178#endif6179_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);61806181for (i = 0; i < NUM_STA; i++) {6182phead = &(pstapriv->sta_hash[i]);6183plist = get_next(phead);61846185while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {6186psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);61876188plist = get_next(plist);61896190if (extra_arg == psta->cmn.aid) {6191RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));6192RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);6193RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",6194psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);6195#ifdef CONFIG_80211N_HT6196RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);6197RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n",6198psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m,6199psta->htpriv.sgi_40m);6200RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);6201RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);6202#endif /* CONFIG_80211N_HT */62036204#ifdef CONFIG_AP_MODE6205RTW_INFO("capability=0x%x\n", psta->capability);6206RTW_INFO("flags=0x%x\n", psta->flags);6207RTW_INFO("wpa_psk=0x%x\n", psta->wpa_psk);6208RTW_INFO("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);6209RTW_INFO("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);6210RTW_INFO("qos_info=0x%x\n", psta->qos_info);6211#endif6212RTW_INFO("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);62136214sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);6215}62166217}6218}62196220_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);62216222}6223break;62246225case 0x0b: { /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */6226/* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */6227/* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */62286229if (arg == 0) {6230RTW_INFO("disable driver ctrl vcs\n");6231padapter->driver_vcs_en = 0;6232} else if (arg == 1) {6233RTW_INFO("enable driver ctrl vcs = %d\n", extra_arg);6234padapter->driver_vcs_en = 1;62356236if (extra_arg > 2)6237padapter->driver_vcs_type = 1;6238else6239padapter->driver_vcs_type = extra_arg;6240}6241}6242break;6243case 0x0c: { /* dump rx/tx packet */6244if (arg == 0) {6245RTW_INFO("dump rx packet (%d)\n", extra_arg);6246/* pHalData->bDumpRxPkt =extra_arg; */6247rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));6248} else if (arg == 1) {6249RTW_INFO("dump tx packet (%d)\n", extra_arg);6250rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));6251}6252}6253break;6254case 0x0e: {6255if (arg == 0) {6256RTW_INFO("disable driver ctrl rx_ampdu_factor\n");6257padapter->driver_rx_ampdu_factor = 0xFF;6258} else if (arg == 1) {62596260RTW_INFO("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);62616262if (extra_arg > 0x03)6263padapter->driver_rx_ampdu_factor = 0xFF;6264else6265padapter->driver_rx_ampdu_factor = extra_arg;6266}6267}6268break;6269#ifdef DBG_CONFIG_ERROR_DETECT6270case 0x0f: {6271if (extra_arg == 0) {6272RTW_INFO("###### silent reset test.......#####\n");6273rtw_hal_sreset_reset(padapter);6274} else {6275HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);6276struct sreset_priv *psrtpriv = &pHalData->srestpriv;6277psrtpriv->dbg_trigger_point = extra_arg;6278}62796280}6281break;6282case 0x15: {6283struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);6284RTW_INFO("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);6285}6286break;62876288#endif62896290case 0x10: /* driver version display */6291dump_drv_version(RTW_DBGDUMP);6292break;6293case 0x11: { /* dump linked status */6294int pre_mode;6295pre_mode = padapter->bLinkInfoDump;6296/* linked_info_dump(padapter,extra_arg); */6297if (extra_arg == 1 || (extra_arg == 0 && pre_mode == 1)) /* not consider pwr_saving 0: */6298padapter->bLinkInfoDump = extra_arg;62996300else if ((extra_arg == 2) || (extra_arg == 0 && pre_mode == 2)) { /* consider power_saving */6301/* RTW_INFO("linked_info_dump =%s\n", (padapter->bLinkInfoDump)?"enable":"disable") */6302linked_info_dump(padapter, extra_arg);6303}6304630563066307}6308break;6309#ifdef CONFIG_80211N_HT6310case 0x12: { /* set rx_stbc */6311struct registry_priv *pregpriv = &padapter->registrypriv;6312/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */6313/* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */6314if (pregpriv && (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3)) {6315pregpriv->rx_stbc = extra_arg;6316RTW_INFO("set rx_stbc=%d\n", pregpriv->rx_stbc);6317} else6318RTW_INFO("get rx_stbc=%d\n", pregpriv->rx_stbc);63196320}6321break;6322case 0x13: { /* set ampdu_enable */6323struct registry_priv *pregpriv = &padapter->registrypriv;6324/* 0: disable, 0x1:enable */6325if (pregpriv && extra_arg < 2) {6326pregpriv->ampdu_enable = extra_arg;6327RTW_INFO("set ampdu_enable=%d\n", pregpriv->ampdu_enable);6328} else6329RTW_INFO("get ampdu_enable=%d\n", pregpriv->ampdu_enable);63306331}6332break;6333#endif6334case 0x14: { /* get wifi_spec */6335struct registry_priv *pregpriv = &padapter->registrypriv;6336RTW_INFO("get wifi_spec=%d\n", pregpriv->wifi_spec);63376338}6339break;63406341#ifdef DBG_FIXED_CHAN6342case 0x17: {6343struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);6344printk("===> Fixed channel to %d\n", extra_arg);6345pmlmeext->fixed_chan = extra_arg;63466347}6348break;6349#endif6350#ifdef CONFIG_80211N_HT6351case 0x19: {6352struct registry_priv *pregistrypriv = &padapter->registrypriv;6353/* extra_arg : */6354/* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */6355/* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */6356if (arg == 0) {6357RTW_INFO("driver disable LDPC\n");6358pregistrypriv->ldpc_cap = 0x00;6359} else if (arg == 1) {6360RTW_INFO("driver set LDPC cap = 0x%x\n", extra_arg);6361pregistrypriv->ldpc_cap = (u8)(extra_arg & 0x33);6362}6363}6364break;6365case 0x1a: {6366struct registry_priv *pregistrypriv = &padapter->registrypriv;6367/* extra_arg : */6368/* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */6369/* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */6370if (arg == 0) {6371RTW_INFO("driver disable STBC\n");6372pregistrypriv->stbc_cap = 0x00;6373} else if (arg == 1) {6374RTW_INFO("driver set STBC cap = 0x%x\n", extra_arg);6375pregistrypriv->stbc_cap = (u8)(extra_arg & 0x33);6376}6377}6378break;6379#endif /* CONFIG_80211N_HT */6380case 0x1b: {6381struct registry_priv *pregistrypriv = &padapter->registrypriv;63826383if (arg == 0) {6384RTW_INFO("disable driver ctrl max_rx_rate, reset to default_rate_set\n");6385init_mlme_default_rate_set(padapter);6386#ifdef CONFIG_80211N_HT6387pregistrypriv->ht_enable = (u8)rtw_ht_enable;6388#endif /* CONFIG_80211N_HT */6389} else if (arg == 1) {63906391int i;6392u8 max_rx_rate;63936394RTW_INFO("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);63956396max_rx_rate = (u8)extra_arg;63976398if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0->B or G -> disable HT */6399#ifdef CONFIG_80211N_HT6400pregistrypriv->ht_enable = 0;6401#endif /* CONFIG_80211N_HT */6402for (i = 0; i < NumRates; i++) {6403if (pmlmeext->datarate[i] > max_rx_rate)6404pmlmeext->datarate[i] = 0xff;6405}64066407}6408#ifdef CONFIG_80211N_HT6409else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */6410u32 mcs_bitmap = 0x0;64116412for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++)6413mcs_bitmap |= BIT(i);64146415set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);6416}6417#endif /* CONFIG_80211N_HT */6418}6419}6420break;6421case 0x1c: { /* enable/disable driver control AMPDU Density for peer sta's rx */6422if (arg == 0) {6423RTW_INFO("disable driver ctrl ampdu density\n");6424padapter->driver_ampdu_spacing = 0xFF;6425} else if (arg == 1) {64266427RTW_INFO("enable driver ctrl ampdu density = %d\n", extra_arg);64286429if (extra_arg > 0x07)6430padapter->driver_ampdu_spacing = 0xFF;6431else6432padapter->driver_ampdu_spacing = extra_arg;6433}6434}6435break;6436#ifdef CONFIG_BACKGROUND_NOISE_MONITOR6437case 0x1e: {6438RTW_INFO("===========================================\n");6439rtw_noise_measure_curchan(padapter);6440RTW_INFO("===========================================\n");6441}6442break;6443#endif644464456446#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)6447case 0x1f:6448{6449int i, j = 0, test_cnts = 0;6450static u8 test_code = 0x5A;6451static u32 data_misatch_cnt = 0, d_acc_err_cnt = 0;64526453u32 d_data, i_data;6454u32 imr;64556456test_cnts = extra_arg;6457for (i = 0; i < test_cnts; i++) {6458if (RTW_CANNOT_IO(padapter))6459break;64606461rtw_write8(padapter, 0x07, test_code);64626463d_data = rtw_read32(padapter, 0x04);6464imr = rtw_read32(padapter, 0x10250014);6465rtw_write32(padapter, 0x10250014, 0);6466rtw_msleep_os(50);64676468i_data = rtw_sd_iread32(padapter, 0x04);64696470rtw_write32(padapter, 0x10250014, imr);64716472if (d_data != i_data) {6473data_misatch_cnt++;6474RTW_ERR("d_data :0x%08x, i_data : 0x%08x\n", d_data, i_data);6475}64766477if (test_code != (i_data >> 24)) {6478d_acc_err_cnt++;6479rtw_write8(padapter, 0x07, 0xAA);6480RTW_ERR("test_code :0x%02x, i_data : 0x%08x\n", test_code, i_data);6481}6482if ((j++) == 100) {6483rtw_msleep_os(2000);6484RTW_INFO(" Indirect access testing..........%d/%d\n", i, test_cnts);6485j = 0;6486}64876488test_code = ~test_code;6489rtw_msleep_os(50);6490}6491RTW_INFO("========Indirect access test=========\n");6492RTW_INFO(" test_cnts = %d\n", test_cnts);6493RTW_INFO(" direct & indirect read32 data missatch cnts = %d\n", data_misatch_cnt);6494RTW_INFO(" indirect rdata is not equal to wdata cnts = %d\n", d_acc_err_cnt);6495RTW_INFO("========Indirect access test=========\n\n");6496data_misatch_cnt = d_acc_err_cnt = 0;64976498}6499break;6500#endif6501case 0x20:6502{6503if (arg == 0xAA) {6504u8 page_offset, page_num;65056506page_offset = (u8)(extra_arg >> 16);6507page_num = (u8)(extra_arg & 0xFF);6508rtw_dump_rsvd_page(RTW_DBGDUMP, padapter, page_offset, page_num);6509}6510#ifdef CONFIG_SUPPORT_FIFO_DUMP6511else {6512u8 fifo_sel;6513u32 addr, size;65146515fifo_sel = (u8)(arg & 0x0F);6516addr = (extra_arg >> 16) & 0xFFFF;6517size = extra_arg & 0xFFFF;6518rtw_dump_fifo(RTW_DBGDUMP, padapter, fifo_sel, addr, size);6519}6520#endif6521}6522break;65236524case 0x23: {6525RTW_INFO("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");6526padapter->bNotifyChannelChange = extra_arg;6527break;6528}6529case 0x24: {6530#ifdef CONFIG_P2P6531RTW_INFO("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");6532padapter->bShowGetP2PState = extra_arg;6533#endif /* CONFIG_P2P */6534break;6535}6536#ifdef CONFIG_GPIO_API6537case 0x25: { /* Get GPIO register */6538/*6539* dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~76540*/65416542u8 value;6543RTW_INFO("Read GPIO Value extra_arg = %d\n", extra_arg);6544value = rtw_hal_get_gpio(padapter, extra_arg);6545RTW_INFO("Read GPIO Value = %d\n", value);6546break;6547}6548case 0x26: { /* Set GPIO direction */65496550/* dbg 0x7f26000x [y], Set gpio direction,6551* x: gpio_num,4~7 y: indicate direction, 0~16552*/65536554int value;6555RTW_INFO("Set GPIO Direction! arg = %d ,extra_arg=%d\n", arg , extra_arg);6556value = rtw_hal_config_gpio(padapter, arg, extra_arg);6557RTW_INFO("Set GPIO Direction %s\n", (value == -1) ? "Fail!!!" : "Success");6558break;6559}6560case 0x27: { /* Set GPIO output direction value */6561/*6562* dbg 0x7f27000x [y], Set gpio output direction value,6563* x: gpio_num,4~7 y: indicate direction, 0~16564*/65656566int value;6567RTW_INFO("Set GPIO Value! arg = %d ,extra_arg=%d\n", arg , extra_arg);6568value = rtw_hal_set_gpio_output_value(padapter, arg, extra_arg);6569RTW_INFO("Set GPIO Value %s\n", (value == -1) ? "Fail!!!" : "Success");6570break;6571}6572#endif6573#ifdef DBG_CMD_QUEUE6574case 0x28: {6575dump_cmd_id = extra_arg;6576RTW_INFO("dump_cmd_id:%d\n", dump_cmd_id);6577}6578break;6579#endif /* DBG_CMD_QUEUE */6580case 0xaa: {6581if ((extra_arg & 0x7F) > 0x3F)6582extra_arg = 0xFF;6583RTW_INFO("chang data rate to :0x%02x\n", extra_arg);6584padapter->fix_rate = extra_arg;6585}6586break;6587case 0xdd: { /* registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg */6588if (extra_arg == 0)6589mac_reg_dump(RTW_DBGDUMP, padapter);6590else if (extra_arg == 1)6591bb_reg_dump(RTW_DBGDUMP, padapter);6592else if (extra_arg == 2)6593rf_reg_dump(RTW_DBGDUMP, padapter);6594else if (extra_arg == 11)6595bb_reg_dump_ex(RTW_DBGDUMP, padapter);6596}6597break;65986599case 0xee: {6600RTW_INFO(" === please control /proc to trun on/off PHYDM func ===\n");6601}6602break;66036604case 0xfd:6605rtw_write8(padapter, 0xc50, arg);6606RTW_INFO("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));6607rtw_write8(padapter, 0xc58, arg);6608RTW_INFO("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));6609break;6610case 0xfe:6611RTW_INFO("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));6612RTW_INFO("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));6613break;6614case 0xff: {6615RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));6616RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));6617RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));6618RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));6619RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));66206621RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));662266236624RTW_INFO("\n");66256626RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));6627RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));66286629RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));66306631RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));66326633RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));6634RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));66356636RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));6637RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));6638RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));6639RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));6640}6641break;6642}6643break;6644default:6645RTW_INFO("error dbg cmd!\n");6646break;6647}664866496650return ret;66516652}66536654static int wpa_set_param(struct net_device *dev, u8 name, u32 value)6655{6656uint ret = 0;6657_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);66586659switch (name) {6660case IEEE_PARAM_WPA_ENABLED:66616662padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */66636664/* ret = ieee80211_wpa_enable(ieee, value); */66656666switch ((value) & 0xff) {6667case 1: /* WPA */6668padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */6669padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;6670break;6671case 2: /* WPA2 */6672padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */6673padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;6674break;6675}667666776678break;66796680case IEEE_PARAM_TKIP_COUNTERMEASURES:6681/* ieee->tkip_countermeasures=value; */6682break;66836684case IEEE_PARAM_DROP_UNENCRYPTED: {6685/* HACK:6686*6687* wpa_supplicant calls set_wpa_enabled when the driver6688* is loaded and unloaded, regardless of if WPA is being6689* used. No other calls are made which can be used to6690* determine if encryption will be used or not prior to6691* association being expected. If encryption is not being6692* used, drop_unencrypted is set to false, else true -- we6693* can use this to determine if the CAP_PRIVACY_ON bit should6694* be set.6695*/66966697#if 06698struct ieee80211_security sec = {6699.flags = SEC_ENABLED,6700.enabled = value,6701};6702ieee->drop_unencrypted = value;6703/* We only change SEC_LEVEL for open mode. Others6704* are set by ipw_wpa_set_encryption.6705*/6706if (!value) {6707sec.flags |= SEC_LEVEL;6708sec.level = SEC_LEVEL_0;6709} else {6710sec.flags |= SEC_LEVEL;6711sec.level = SEC_LEVEL_1;6712}6713if (ieee->set_security)6714ieee->set_security(ieee->dev, &sec);6715#endif6716break;67176718}6719case IEEE_PARAM_PRIVACY_INVOKED:67206721/* ieee->privacy_invoked=value; */67226723break;67246725case IEEE_PARAM_AUTH_ALGS:67266727ret = wpa_set_auth_algs(dev, value);67286729break;67306731case IEEE_PARAM_IEEE_802_1X:67326733/* ieee->ieee802_1x=value; */67346735break;67366737case IEEE_PARAM_WPAX_SELECT:67386739/* added for WPA2 mixed mode */6740/*RTW_WARN("------------------------>wpax value = %x\n", value);*/6741/*6742spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);6743ieee->wpax_type_set = 1;6744ieee->wpax_type_notify = value;6745spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);6746*/67476748break;67496750default:6751675267536754ret = -EOPNOTSUPP;675567566757break;67586759}67606761return ret;67626763}67646765static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)6766{6767int ret = 0;6768_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);67696770switch (command) {6771case IEEE_MLME_STA_DEAUTH:67726773if (!rtw_set_802_11_disassociate(padapter))6774ret = -1;67756776break;67776778case IEEE_MLME_STA_DISASSOC:67796780if (!rtw_set_802_11_disassociate(padapter))6781ret = -1;67826783break;67846785default:6786ret = -EOPNOTSUPP;6787break;6788}6789#ifdef CONFIG_RTW_REPEATER_SON6790rtw_rson_do_disconnect(padapter);6791#endif6792return ret;67936794}67956796static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)6797{6798struct ieee_param *param;6799uint ret = 0;68006801/* down(&ieee->wx_sem); */68026803if (p->length < sizeof(struct ieee_param) || !p->pointer) {6804ret = -EINVAL;6805goto out;6806}68076808param = (struct ieee_param *)rtw_malloc(p->length);6809if (param == NULL) {6810ret = -ENOMEM;6811goto out;6812}68136814if (copy_from_user(param, p->pointer, p->length)) {6815rtw_mfree((u8 *)param, p->length);6816ret = -EFAULT;6817goto out;6818}68196820switch (param->cmd) {68216822case IEEE_CMD_SET_WPA_PARAM:6823ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);6824break;68256826case IEEE_CMD_SET_WPA_IE:6827/* ret = wpa_set_wpa_ie(dev, param, p->length); */6828ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);6829break;68306831case IEEE_CMD_SET_ENCRYPTION:6832ret = wpa_set_encryption(dev, param, p->length);6833break;68346835case IEEE_CMD_MLME:6836ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);6837break;68386839default:6840RTW_INFO("Unknown WPA supplicant request: %d\n", param->cmd);6841ret = -EOPNOTSUPP;6842break;68436844}68456846if (ret == 0 && copy_to_user(p->pointer, param, p->length))6847ret = -EFAULT;68486849rtw_mfree((u8 *)param, p->length);68506851out:68526853/* up(&ieee->wx_sem); */68546855return ret;68566857}68586859#ifdef CONFIG_AP_MODE6860static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)6861{6862int ret = 0;6863u32 wep_key_idx, wep_key_len, wep_total_len;6864NDIS_802_11_WEP *pwep = NULL;6865struct sta_info *psta = NULL, *pbcmc_sta = NULL;6866_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);6867struct mlme_priv *pmlmepriv = &padapter->mlmepriv;6868struct security_priv *psecuritypriv = &(padapter->securitypriv);6869struct sta_priv *pstapriv = &padapter->stapriv;68706871RTW_INFO("%s\n", __FUNCTION__);68726873param->u.crypt.err = 0;6874param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';68756876/* sizeof(struct ieee_param) = 64 bytes; */6877/* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */6878if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {6879ret = -EINVAL;6880goto exit;6881}68826883if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&6884param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&6885param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {6886if (param->u.crypt.idx >= WEP_KEYS6887#ifdef CONFIG_IEEE80211W6888&& param->u.crypt.idx > BIP_MAX_KEYID6889#endif /* CONFIG_IEEE80211W */6890) {6891ret = -EINVAL;6892goto exit;6893}6894} else {6895psta = rtw_get_stainfo(pstapriv, param->sta_addr);6896if (!psta) {6897/* ret = -EINVAL; */6898RTW_INFO("rtw_set_encryption(), sta has already been removed or never been added\n");6899goto exit;6900}6901}69026903if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {6904/* todo:clear default encryption keys */69056906psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;6907psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;6908psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;6909psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;69106911RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);69126913goto exit;6914}691569166917if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {6918RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");69196920wep_key_idx = param->u.crypt.idx;6921wep_key_len = param->u.crypt.key_len;69226923RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);69246925if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {6926ret = -EINVAL;6927goto exit;6928}692969306931if (wep_key_len > 0) {6932wep_key_len = wep_key_len <= 5 ? 5 : 13;6933wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);6934pwep = (NDIS_802_11_WEP *)rtw_malloc(wep_total_len);6935if (pwep == NULL) {6936RTW_INFO(" r871x_set_encryption: pwep allocate fail !!!\n");6937goto exit;6938}69396940_rtw_memset(pwep, 0, wep_total_len);69416942pwep->KeyLength = wep_key_len;6943pwep->Length = wep_total_len;69446945}69466947pwep->KeyIndex = wep_key_idx;69486949_rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);69506951if (param->u.crypt.set_tx) {6952RTW_INFO("wep, set_tx=1\n");69536954psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;6955psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;6956psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;6957psecuritypriv->dot118021XGrpPrivacy = _WEP40_;69586959if (pwep->KeyLength == 13) {6960psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;6961psecuritypriv->dot118021XGrpPrivacy = _WEP104_;6962}696369646965psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;69666967_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);69686969psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;69706971rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);6972} else {6973RTW_INFO("wep, set_tx=0\n");69746975/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */6976/* "psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam */69776978_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);69796980psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;69816982rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);6983}69846985goto exit;69866987}698869896990if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* */ { /* group key */6991if (param->u.crypt.set_tx == 1) {6992if (strcmp(param->u.crypt.alg, "WEP") == 0) {6993RTW_INFO(FUNC_ADPT_FMT" set WEP TX GTK idx:%u, len:%u\n"6994, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);6995_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));6996psecuritypriv->dot118021XGrpPrivacy = _WEP40_;6997if (param->u.crypt.key_len == 13)6998psecuritypriv->dot118021XGrpPrivacy = _WEP104_;69997000} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {7001RTW_INFO(FUNC_ADPT_FMT" set TKIP TX GTK idx:%u, len:%u\n"7002, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);7003psecuritypriv->dot118021XGrpPrivacy = _TKIP_;7004_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));7005/* set mic key */7006_rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);7007_rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);7008psecuritypriv->busetkipkey = _TRUE;70097010} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {7011RTW_INFO(FUNC_ADPT_FMT" set CCMP TX GTK idx:%u, len:%u\n"7012, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);7013psecuritypriv->dot118021XGrpPrivacy = _AES_;7014_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));70157016#ifdef CONFIG_IEEE80211W7017} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {7018RTW_INFO(FUNC_ADPT_FMT" set TX IGTK idx:%u, len:%u\n"7019, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);7020_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));7021psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;7022psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);7023psecuritypriv->binstallBIPkey = _TRUE;7024goto exit;7025#endif /* CONFIG_IEEE80211W */70267027} else if (strcmp(param->u.crypt.alg, "none") == 0) {7028RTW_INFO(FUNC_ADPT_FMT" clear group key, idx:%u\n"7029, FUNC_ADPT_ARG(padapter), param->u.crypt.idx);7030psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;7031} else {7032RTW_WARN(FUNC_ADPT_FMT" set group key, not support\n"7033, FUNC_ADPT_ARG(padapter));7034goto exit;7035}70367037psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;7038pbcmc_sta = rtw_get_bcmc_stainfo(padapter);7039if (pbcmc_sta) {7040pbcmc_sta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);7041pbcmc_sta->ieee8021x_blocked = _FALSE;7042pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy */7043}7044psecuritypriv->binstallGrpkey = _TRUE;7045psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */70467047rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);7048}70497050goto exit;70517052}70537054if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */7055if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {7056if (param->u.crypt.set_tx == 1) {7057_rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));70587059if (strcmp(param->u.crypt.alg, "WEP") == 0) {7060RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n"7061, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)7062, param->u.crypt.idx, param->u.crypt.key_len);7063psta->dot118021XPrivacy = _WEP40_;7064if (param->u.crypt.key_len == 13)7065psta->dot118021XPrivacy = _WEP104_;70667067} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {7068RTW_INFO(FUNC_ADPT_FMT" set TKIP PTK of "MAC_FMT" idx:%u, len:%u\n"7069, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)7070, param->u.crypt.idx, param->u.crypt.key_len);7071psta->dot118021XPrivacy = _TKIP_;7072/* set mic key */7073_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);7074_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);7075psecuritypriv->busetkipkey = _TRUE;70767077} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {7078RTW_INFO(FUNC_ADPT_FMT" set CCMP PTK of "MAC_FMT" idx:%u, len:%u\n"7079, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)7080, param->u.crypt.idx, param->u.crypt.key_len);7081psta->dot118021XPrivacy = _AES_;70827083} else if (strcmp(param->u.crypt.alg, "none") == 0) {7084RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n"7085, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)7086, param->u.crypt.idx);7087psta->dot118021XPrivacy = _NO_PRIVACY_;70887089} else {7090RTW_WARN(FUNC_ADPT_FMT" set pairwise key of "MAC_FMT", not support\n"7091, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));7092goto exit;7093}70947095psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);7096psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);7097psta->ieee8021x_blocked = _FALSE;70987099if (psta->dot118021XPrivacy != _NO_PRIVACY_) {7100psta->bpairwise_key_installed = _TRUE;71017102/* WPA2 key-handshake has completed */7103if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)7104psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);7105}71067107rtw_ap_set_pairwise_key(padapter, psta);7108} else {7109RTW_WARN(FUNC_ADPT_FMT" set group key of "MAC_FMT", not support\n"7110, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));7111goto exit;7112}71137114}71157116}71177118exit:71197120if (pwep)7121rtw_mfree((u8 *)pwep, wep_total_len);71227123return ret;71247125}71267127static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)7128{7129int ret = 0;7130_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7131struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7132struct sta_priv *pstapriv = &padapter->stapriv;7133unsigned char *pbuf = param->u.bcn_ie.buf;713471357136RTW_INFO("%s, len=%d\n", __FUNCTION__, len);71377138if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7139return -EINVAL;71407141_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);71427143if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))7144pstapriv->max_num_sta = NUM_STA;714571467147if (rtw_check_beacon_data(padapter, pbuf, (len - 12 - 2)) == _SUCCESS) /* 12 = param header, 2:no packed */7148ret = 0;7149else7150ret = -EINVAL;715171527153return ret;71547155}71567157static int rtw_hostapd_sta_flush(struct net_device *dev)7158{7159/* _irqL irqL; */7160/* _list *phead, *plist; */7161int ret = 0;7162/* struct sta_info *psta = NULL; */7163_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7164/* struct sta_priv *pstapriv = &padapter->stapriv; */71657166RTW_INFO("%s\n", __FUNCTION__);71677168flush_all_cam_entry(padapter); /* clear CAM */7169#ifdef CONFIG_AP_MODE7170ret = rtw_sta_flush(padapter, _TRUE);7171#endif7172return ret;71737174}71757176static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)7177{7178int ret = 0;7179struct sta_info *psta = NULL;7180_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7181struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7182struct sta_priv *pstapriv = &padapter->stapriv;71837184RTW_INFO("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));71857186if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)7187return -EINVAL;71887189if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&7190param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&7191param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)7192return -EINVAL;71937194#if 07195psta = rtw_get_stainfo(pstapriv, param->sta_addr);7196if (psta) {7197RTW_INFO("rtw_add_sta(), free has been added psta=%p\n", psta);7198/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */7199rtw_free_stainfo(padapter, psta);7200/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */72017202psta = NULL;7203}7204#endif7205/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */7206psta = rtw_get_stainfo(pstapriv, param->sta_addr);7207if (psta) {7208int flags = param->u.add_sta.flags;72097210/* RTW_INFO("rtw_add_sta(), init sta's variables, psta=%p\n", psta); */72117212psta->cmn.aid = param->u.add_sta.aid;/* aid=1~2007 */72137214_rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);721572167217/* check wmm cap. */7218if (WLAN_STA_WME & flags)7219psta->qos_option = 1;7220else7221psta->qos_option = 0;72227223if (pmlmepriv->qospriv.qos_option == 0)7224psta->qos_option = 0;722572267227#ifdef CONFIG_80211N_HT7228/* chec 802.11n ht cap. */7229if (padapter->registrypriv.ht_enable &&7230is_supported_ht(padapter->registrypriv.wireless_mode) &&7231(WLAN_STA_HT & flags)) {7232psta->htpriv.ht_option = _TRUE;7233psta->qos_option = 1;7234_rtw_memcpy((void *)&psta->htpriv.ht_cap, (void *)¶m->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));7235} else7236psta->htpriv.ht_option = _FALSE;72377238if (pmlmepriv->htpriv.ht_option == _FALSE)7239psta->htpriv.ht_option = _FALSE;72407241#endif724272437244update_sta_info_apmode(padapter, psta);724572467247} else7248ret = -ENOMEM;72497250return ret;72517252}72537254static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)7255{7256_irqL irqL;7257int ret = 0;7258struct sta_info *psta = NULL;7259_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7260struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7261struct sta_priv *pstapriv = &padapter->stapriv;72627263RTW_INFO("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));72647265if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)7266return -EINVAL;72677268if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&7269param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&7270param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)7271return -EINVAL;72727273psta = rtw_get_stainfo(pstapriv, param->sta_addr);7274if (psta) {7275u8 updated = _FALSE;72767277/* RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid); */72787279_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);7280if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {7281rtw_list_delete(&psta->asoc_list);7282pstapriv->asoc_list_cnt--;7283updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);72847285}7286_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);72877288associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);72897290psta = NULL;72917292} else {7293RTW_INFO("rtw_del_sta(), sta has already been removed or never been added\n");72947295/* ret = -1; */7296}729772987299return ret;73007301}73027303static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)7304{7305int ret = 0;7306struct sta_info *psta = NULL;7307_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7308struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7309struct sta_priv *pstapriv = &padapter->stapriv;7310struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;7311struct sta_data *psta_data = (struct sta_data *)param_ex->data;73127313RTW_INFO("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));73147315if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)7316return -EINVAL;73177318if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&7319param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&7320param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)7321return -EINVAL;73227323psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);7324if (psta) {7325#if 07326struct {7327u16 aid;7328u16 capability;7329int flags;7330u32 sta_set;7331u8 tx_supp_rates[16];7332u32 tx_supp_rates_len;7333struct rtw_ieee80211_ht_cap ht_cap;7334u64 rx_pkts;7335u64 rx_bytes;7336u64 rx_drops;7337u64 tx_pkts;7338u64 tx_bytes;7339u64 tx_drops;7340} get_sta;7341#endif7342psta_data->aid = (u16)psta->cmn.aid;7343psta_data->capability = psta->capability;7344psta_data->flags = psta->flags;73457346/*7347nonerp_set : BIT(0)7348no_short_slot_time_set : BIT(1)7349no_short_preamble_set : BIT(2)7350no_ht_gf_set : BIT(3)7351no_ht_set : BIT(4)7352ht_20mhz_set : BIT(5)7353*/73547355psta_data->sta_set = ((psta->nonerp_set) |7356(psta->no_short_slot_time_set << 1) |7357(psta->no_short_preamble_set << 2) |7358(psta->no_ht_gf_set << 3) |7359(psta->no_ht_set << 4) |7360(psta->ht_20mhz_set << 5));73617362psta_data->tx_supp_rates_len = psta->bssratelen;7363_rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);7364#ifdef CONFIG_80211N_HT7365if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))7366_rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));7367#endif /* CONFIG_80211N_HT */7368psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;7369psta_data->rx_bytes = psta->sta_stats.rx_bytes;7370psta_data->rx_drops = psta->sta_stats.rx_drops;73717372psta_data->tx_pkts = psta->sta_stats.tx_pkts;7373psta_data->tx_bytes = psta->sta_stats.tx_bytes;7374psta_data->tx_drops = psta->sta_stats.tx_drops;737573767377} else7378ret = -1;73797380return ret;73817382}73837384static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)7385{7386int ret = 0;7387struct sta_info *psta = NULL;7388_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7389struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7390struct sta_priv *pstapriv = &padapter->stapriv;73917392RTW_INFO("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));73937394if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)7395return -EINVAL;73967397if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&7398param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&7399param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)7400return -EINVAL;74017402psta = rtw_get_stainfo(pstapriv, param->sta_addr);7403if (psta) {7404if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {7405int wpa_ie_len;7406int copy_len;74077408wpa_ie_len = psta->wpa_ie[1];74097410copy_len = ((wpa_ie_len + 2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len + 2);74117412param->u.wpa_ie.len = copy_len;74137414_rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);7415} else {7416/* ret = -1; */7417RTW_INFO("sta's wpa_ie is NONE\n");7418}7419} else7420ret = -1;74217422return ret;74237424}74257426static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)7427{7428int ret = 0;7429unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};7430_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7431struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7432struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);7433int ie_len;74347435RTW_INFO("%s, len=%d\n", __FUNCTION__, len);74367437if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7438return -EINVAL;74397440ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */744174427443if (pmlmepriv->wps_beacon_ie) {7444rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);7445pmlmepriv->wps_beacon_ie = NULL;7446}74477448if (ie_len > 0) {7449pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);7450pmlmepriv->wps_beacon_ie_len = ie_len;7451if (pmlmepriv->wps_beacon_ie == NULL) {7452RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);7453return -EINVAL;7454}74557456_rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);74577458update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, 0);74597460pmlmeext->bstart_bss = _TRUE;74617462}746374647465return ret;74667467}74687469static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)7470{7471int ret = 0;7472_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7473struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7474int ie_len;74757476RTW_INFO("%s, len=%d\n", __FUNCTION__, len);74777478if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7479return -EINVAL;74807481ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */748274837484if (pmlmepriv->wps_probe_resp_ie) {7485rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);7486pmlmepriv->wps_probe_resp_ie = NULL;7487}74887489if (ie_len > 0) {7490pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);7491pmlmepriv->wps_probe_resp_ie_len = ie_len;7492if (pmlmepriv->wps_probe_resp_ie == NULL) {7493RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);7494return -EINVAL;7495}7496_rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);7497}749874997500return ret;75017502}75037504static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)7505{7506int ret = 0;7507_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7508struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7509int ie_len;75107511RTW_INFO("%s, len=%d\n", __FUNCTION__, len);75127513if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7514return -EINVAL;75157516ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */751775187519if (pmlmepriv->wps_assoc_resp_ie) {7520rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);7521pmlmepriv->wps_assoc_resp_ie = NULL;7522}75237524if (ie_len > 0) {7525pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);7526pmlmepriv->wps_assoc_resp_ie_len = ie_len;7527if (pmlmepriv->wps_assoc_resp_ie == NULL) {7528RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);7529return -EINVAL;7530}75317532_rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);7533}753475357536return ret;75377538}75397540static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)7541{7542int ret = 0;7543_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);7544struct mlme_priv *mlmepriv = &(adapter->mlmepriv);7545struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);7546struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);7547int ie_len;7548u8 *ssid_ie;7549char ssid[NDIS_802_11_LENGTH_SSID + 1];7550sint ssid_len = 0;7551u8 ignore_broadcast_ssid;75527553if (check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)7554return -EPERM;75557556if (param->u.bcn_ie.reserved[0] != 0xea)7557return -EINVAL;75587559mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];75607561ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */7562ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);75637564if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {7565WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;7566WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;75677568_rtw_memcpy(ssid, ssid_ie + 2, ssid_len);7569ssid[ssid_len] = 0x0;75707571if (0)7572RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),7573ssid, ssid_len,7574pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,7575pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);75767577_rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);7578pbss_network->Ssid.SsidLength = ssid_len;7579_rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);7580pbss_network_ext->Ssid.SsidLength = ssid_len;75817582if (0)7583RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),7584pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,7585pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);7586}75877588RTW_INFO(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),7589ignore_broadcast_ssid, ssid, ssid_len);75907591return ret;7592}75937594#if CONFIG_RTW_MACADDR_ACL7595static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)7596{7597int ret = 0;7598_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7599struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);76007601if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7602return -EINVAL;76037604if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&7605param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&7606param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)7607return -EINVAL;76087609ret = rtw_acl_remove_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);76107611return ret;76127613}76147615static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)7616{7617int ret = 0;7618_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7619struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);76207621if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7622return -EINVAL;76237624if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&7625param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&7626param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)7627return -EINVAL;76287629ret = rtw_acl_add_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);76307631return ret;76327633}76347635static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)7636{7637int ret = 0;7638_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7639struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);76407641if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)7642return -EINVAL;76437644rtw_set_macaddr_acl(padapter, RTW_ACL_PERIOD_BSS, param->u.mlme.command);76457646return ret;7647}7648#endif /* CONFIG_RTW_MACADDR_ACL */76497650static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)7651{7652struct ieee_param *param;7653int ret = 0;7654_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);76557656/* RTW_INFO("%s\n", __FUNCTION__); */76577658/*7659* this function is expect to call in master mode, which allows no power saving7660* so, we just check hw_init_completed7661*/76627663if (!rtw_is_hw_init_completed(padapter)) {7664ret = -EPERM;7665goto out;7666}766776687669/* if (p->length < sizeof(struct ieee_param) || !p->pointer){ */7670if (!p->pointer) {7671ret = -EINVAL;7672goto out;7673}76747675param = (struct ieee_param *)rtw_malloc(p->length);7676if (param == NULL) {7677ret = -ENOMEM;7678goto out;7679}76807681if (copy_from_user(param, p->pointer, p->length)) {7682rtw_mfree((u8 *)param, p->length);7683ret = -EFAULT;7684goto out;7685}76867687/* RTW_INFO("%s, cmd=%d\n", __FUNCTION__, param->cmd); */76887689switch (param->cmd) {7690case RTL871X_HOSTAPD_FLUSH:76917692ret = rtw_hostapd_sta_flush(dev);76937694break;76957696case RTL871X_HOSTAPD_ADD_STA:76977698ret = rtw_add_sta(dev, param);76997700break;77017702case RTL871X_HOSTAPD_REMOVE_STA:77037704ret = rtw_del_sta(dev, param);77057706break;77077708case RTL871X_HOSTAPD_SET_BEACON:77097710ret = rtw_set_beacon(dev, param, p->length);77117712break;77137714case RTL871X_SET_ENCRYPTION:77157716ret = rtw_set_encryption(dev, param, p->length);77177718break;77197720case RTL871X_HOSTAPD_GET_WPAIE_STA:77217722ret = rtw_get_sta_wpaie(dev, param);77237724break;77257726case RTL871X_HOSTAPD_SET_WPS_BEACON:77277728ret = rtw_set_wps_beacon(dev, param, p->length);77297730break;77317732case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:77337734ret = rtw_set_wps_probe_resp(dev, param, p->length);77357736break;77377738case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:77397740ret = rtw_set_wps_assoc_resp(dev, param, p->length);77417742break;77437744case RTL871X_HOSTAPD_SET_HIDDEN_SSID:77457746ret = rtw_set_hidden_ssid(dev, param, p->length);77477748break;77497750case RTL871X_HOSTAPD_GET_INFO_STA:77517752ret = rtw_ioctl_get_sta_data(dev, param, p->length);77537754break;77557756#if CONFIG_RTW_MACADDR_ACL7757case RTL871X_HOSTAPD_SET_MACADDR_ACL:7758ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);7759break;7760case RTL871X_HOSTAPD_ACL_ADD_STA:7761ret = rtw_ioctl_acl_add_sta(dev, param, p->length);7762break;7763case RTL871X_HOSTAPD_ACL_REMOVE_STA:7764ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);7765break;7766#endif /* CONFIG_RTW_MACADDR_ACL */77677768default:7769RTW_INFO("Unknown hostapd request: %d\n", param->cmd);7770ret = -EOPNOTSUPP;7771break;77727773}77747775if (ret == 0 && copy_to_user(p->pointer, param, p->length))7776ret = -EFAULT;777777787779rtw_mfree((u8 *)param, p->length);77807781out:77827783return ret;77847785}7786#endif77877788static int rtw_wx_set_priv(struct net_device *dev,7789struct iw_request_info *info,7790union iwreq_data *awrq,7791char *extra)7792{77937794#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV7795char *ext_dbg;7796#endif77977798int ret = 0;7799int len = 0;7800char *ext;7801#ifdef CONFIG_ANDROID7802int i;7803#endif78047805_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7806struct iw_point *dwrq = (struct iw_point *)awrq;78077808if (dwrq->length == 0)7809return -EFAULT;78107811len = dwrq->length;7812ext = rtw_vmalloc(len);7813if (!ext)7814return -ENOMEM;78157816if (copy_from_user(ext, dwrq->pointer, len)) {7817rtw_vmfree(ext, len);7818return -EFAULT;7819}7820782178227823#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV7824ext_dbg = rtw_vmalloc(len);7825if (!ext_dbg) {7826rtw_vmfree(ext, len);7827return -ENOMEM;7828}78297830_rtw_memcpy(ext_dbg, ext, len);7831#endif78327833/* added for wps2.0 @20110524 */7834if (dwrq->flags == 0x8766 && len > 8) {7835u32 cp_sz;7836struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7837u8 *probereq_wpsie = ext;7838int probereq_wpsie_len = len;7839u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};78407841if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&7842(_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) == _TRUE)) {7843cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;78447845if (pmlmepriv->wps_probe_req_ie) {7846u32 free_len = pmlmepriv->wps_probe_req_ie_len;7847pmlmepriv->wps_probe_req_ie_len = 0;7848rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);7849pmlmepriv->wps_probe_req_ie = NULL;7850}78517852pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);7853if (pmlmepriv->wps_probe_req_ie == NULL) {7854printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);7855ret = -EINVAL;7856goto FREE_EXT;78577858}78597860_rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);7861pmlmepriv->wps_probe_req_ie_len = cp_sz;78627863}78647865goto FREE_EXT;78667867}78687869if (len >= WEXT_CSCAN_HEADER_SIZE7870&& _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE7871) {7872ret = rtw_wx_set_scan(dev, info, awrq, ext);7873goto FREE_EXT;7874}78757876#ifdef CONFIG_ANDROID7877/* RTW_INFO("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); */78787879i = rtw_android_cmdstr_to_num(ext);78807881switch (i) {7882case ANDROID_WIFI_CMD_START:7883indicate_wx_custom_event(padapter, "START");7884break;7885case ANDROID_WIFI_CMD_STOP:7886indicate_wx_custom_event(padapter, "STOP");7887break;7888case ANDROID_WIFI_CMD_RSSI: {7889struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);7890struct wlan_network *pcur_network = &pmlmepriv->cur_network;78917892if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)7893sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);7894else7895sprintf(ext, "OK");7896}7897break;7898case ANDROID_WIFI_CMD_LINKSPEED: {7899u16 mbps = rtw_get_cur_max_rate(padapter) / 10;7900sprintf(ext, "LINKSPEED %d", mbps);7901}7902break;7903case ANDROID_WIFI_CMD_MACADDR:7904sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));7905break;7906case ANDROID_WIFI_CMD_SCAN_ACTIVE: {7907/* rtw_set_scan_mode(padapter, SCAN_ACTIVE); */7908sprintf(ext, "OK");7909}7910break;7911case ANDROID_WIFI_CMD_SCAN_PASSIVE: {7912/* rtw_set_scan_mode(padapter, SCAN_PASSIVE); */7913sprintf(ext, "OK");7914}7915break;79167917case ANDROID_WIFI_CMD_COUNTRY: {7918char country_code[10];7919sscanf(ext, "%*s %s", country_code);7920rtw_set_country(padapter, country_code);7921sprintf(ext, "OK");7922}7923break;7924default:7925#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV7926RTW_INFO("%s: %s unknowned req=%s\n", __FUNCTION__,7927dev->name, ext_dbg);7928#endif79297930sprintf(ext, "OK");79317932}79337934if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext) + 1))))7935ret = -EFAULT;79367937#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV7938RTW_INFO("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,7939dev->name, ext_dbg , ext, dwrq->length, (u16)(strlen(ext) + 1));7940#endif7941#endif /* end of CONFIG_ANDROID */794279437944FREE_EXT:79457946rtw_vmfree(ext, len);7947#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV7948rtw_vmfree(ext_dbg, len);7949#endif79507951/* RTW_INFO("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", */7952/* dev->name, ret); */79537954return ret;79557956}7957#ifdef CONFIG_WOWLAN7958static int rtw_wowlan_ctrl(struct net_device *dev,7959struct iw_request_info *info,7960union iwreq_data *wrqu, char *extra)7961{7962_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);7963struct wowlan_ioctl_param poidparam;7964struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);7965struct mlme_priv *pmlmepriv = &padapter->mlmepriv;7966int ret = 0;7967systime start_time = rtw_get_current_time();7968poidparam.subcode = 0;79697970RTW_INFO("+rtw_wowlan_ctrl: %s\n", extra);79717972if (!check_fwstate(pmlmepriv, _FW_LINKED) &&7973check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&7974!WOWLAN_IS_STA_MIX_MODE(padapter)) {7975#ifdef CONFIG_PNO_SUPPORT7976pwrctrlpriv->wowlan_pno_enable = _TRUE;7977#else7978RTW_INFO("[%s] WARNING: Please Connect With AP First!!\n", __func__);7979goto _rtw_wowlan_ctrl_exit_free;7980#endif /* CONFIG_PNO_SUPPORT */7981}79827983if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))7984rtw_scan_abort(padapter);79857986if (_rtw_memcmp(extra, "enable", 6))798779887989rtw_suspend_common(padapter);79907991else if (_rtw_memcmp(extra, "disable", 7)) {7992#ifdef CONFIG_USB_HCI7993RTW_ENABLE_FUNC(padapter, DF_RX_BIT);7994RTW_ENABLE_FUNC(padapter, DF_TX_BIT);7995#endif7996rtw_resume_common(padapter);79977998#ifdef CONFIG_PNO_SUPPORT7999pwrctrlpriv->wowlan_pno_enable = _FALSE;8000#endif /* CONFIG_PNO_SUPPORT */80018002} else {8003RTW_INFO("[%s] Invalid Parameter.\n", __func__);8004goto _rtw_wowlan_ctrl_exit_free;8005}8006/* mutex_lock(&ioctl_mutex); */8007_rtw_wowlan_ctrl_exit_free:8008RTW_INFO("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);8009RTW_PRINT("%s in %d ms\n", __func__,8010rtw_get_passing_time_ms(start_time));8011return ret;8012}80138014/*8015* IP filter This pattern if for a frame containing a ip packet:8016* 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:II8017*8018* A: Ethernet destination address8019* B: Ethernet source address8020* C: Ethernet protocol type8021* D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20)8022* E: IP protocol8023* F: IP source address ( 192.168.0.4: C0:A8:00:2C )8024* G: IP destination address ( 192.168.0.4: C0:A8:00:2C )8025* H: Source port (1024: 04:00)8026* I: Destination port (1024: 04:00)8027*/80288029static int rtw_wowlan_set_pattern(struct net_device *dev,8030struct iw_request_info *info,8031union iwreq_data *wrqu, char *extra)8032{8033_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);8034struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);8035struct mlme_priv *pmlmepriv = &padapter->mlmepriv;8036struct wowlan_ioctl_param poidparam;8037int ret = 0;8038u8 input[wrqu->data.length];8039u8 index = 0;80408041poidparam.subcode = 0;80428043if (!check_fwstate(pmlmepriv, _FW_LINKED) &&8044check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {8045ret = -EFAULT;8046RTW_INFO("Please Connect With AP First!!\n");8047goto _rtw_wowlan_set_pattern_exit;8048}80498050if (wrqu->data.length <= 0) {8051ret = -EFAULT;8052RTW_INFO("ERROR: parameter length <= 0\n");8053goto _rtw_wowlan_set_pattern_exit;8054} else {8055/* set pattern */8056if (copy_from_user(input,8057wrqu->data.pointer, wrqu->data.length))8058return -EFAULT;8059/* leave PS first */8060rtw_ps_deny(padapter, PS_DENY_IOCTL);8061LeaveAllPowerSaveModeDirect(padapter);8062if (strncmp(input, "pattern=", 8) == 0) {8063if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_CAM_NUM) {8064RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n",8065pwrpriv->wowlan_pattern_idx);8066RTW_INFO("WARNING: please clean priv-pattern first\n");8067ret = -EINVAL;8068goto _rtw_wowlan_set_pattern_exit;8069} else {8070index = pwrpriv->wowlan_pattern_idx;8071ret = rtw_wowlan_parser_pattern_cmd(input,8072pwrpriv->patterns[index].content,8073&pwrpriv->patterns[index].len,8074pwrpriv->patterns[index].mask);80758076if (ret == _TRUE)8077pwrpriv->wowlan_pattern_idx++;8078}8079} else if (strncmp(input, "clean", 5) == 0) {8080poidparam.subcode = WOWLAN_PATTERN_CLEAN;8081rtw_hal_set_hwreg(padapter,8082HW_VAR_WOWLAN, (u8 *)&poidparam);8083} else if (strncmp(input, "show", 4) == 0) {8084rtw_wow_pattern_cam_dump(padapter);8085rtw_wow_pattern_sw_dump(padapter);8086} else {8087RTW_INFO("ERROR: incorrect parameter!\n");8088ret = -EINVAL;8089}8090rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);8091}8092_rtw_wowlan_set_pattern_exit:8093return ret;8094}8095#endif /* CONFIG_WOWLAN */80968097#ifdef CONFIG_AP_WOWLAN8098static int rtw_ap_wowlan_ctrl(struct net_device *dev,8099struct iw_request_info *info,8100union iwreq_data *wrqu, char *extra)8101{8102_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);8103struct wowlan_ioctl_param poidparam;8104struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);8105struct mlme_priv *pmlmepriv = &padapter->mlmepriv;8106struct sta_info *psta = NULL;8107int ret = 0;8108systime start_time = rtw_get_current_time();8109poidparam.subcode = 0;81108111RTW_INFO("+rtw_ap_wowlan_ctrl: %s\n", extra);81128113if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {8114RTW_INFO("[%s] It is not AP mode!!\n", __func__);8115goto _rtw_ap_wowlan_ctrl_exit_free;8116}81178118if (_rtw_memcmp(extra, "enable", 6)) {81198120pwrctrlpriv->wowlan_ap_mode = _TRUE;81218122rtw_suspend_common(padapter);8123} else if (_rtw_memcmp(extra, "disable", 7)) {8124#ifdef CONFIG_USB_HCI8125RTW_ENABLE_FUNC(padapter, DF_RX_BIT);8126RTW_ENABLE_FUNC(padapter, DF_TX_BIT);8127#endif8128rtw_resume_common(padapter);8129} else {8130RTW_INFO("[%s] Invalid Parameter.\n", __func__);8131goto _rtw_ap_wowlan_ctrl_exit_free;8132}8133/* mutex_lock(&ioctl_mutex); */8134_rtw_ap_wowlan_ctrl_exit_free:8135RTW_INFO("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);8136RTW_PRINT("%s in %d ms\n", __func__,8137rtw_get_passing_time_ms(start_time));8138_rtw_ap_wowlan_ctrl_exit:8139return ret;8140}8141#endif /* CONFIG_AP_WOWLAN */81428143static int rtw_pm_set(struct net_device *dev,8144struct iw_request_info *info,8145union iwreq_data *wrqu, char *extra)8146{8147int ret = 0;8148unsigned mode = 0;8149_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);81508151RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);81528153if (_rtw_memcmp(extra, "lps=", 4)) {8154sscanf(extra + 4, "%u", &mode);8155ret = rtw_pm_set_lps(padapter, mode);8156} else if (_rtw_memcmp(extra, "ips=", 4)) {8157sscanf(extra + 4, "%u", &mode);8158ret = rtw_pm_set_ips(padapter, mode);8159} else if (_rtw_memcmp(extra, "lps_level=", 10)) {8160if (sscanf(extra + 10, "%u", &mode) > 0)8161ret = rtw_pm_set_lps_level(padapter, mode);8162#ifdef CONFIG_LPS_1T1R8163} else if (_rtw_memcmp(extra, "lps_1t1r=", 9)) {8164if (sscanf(extra + 9, "%u", &mode) > 0)8165ret = rtw_pm_set_lps_1t1r(padapter, mode);8166#endif8167}8168#ifdef CONFIG_WOWLAN8169else if (_rtw_memcmp(extra, "wow_lps=", 8)) {8170sscanf(extra + 8, "%u", &mode);8171ret = rtw_pm_set_wow_lps(padapter, mode);8172} else if (_rtw_memcmp(extra, "wow_lps_level=", 14)) {8173if (sscanf(extra + 14, "%u", &mode) > 0)8174ret = rtw_pm_set_wow_lps_level(padapter, mode);8175#ifdef CONFIG_LPS_1T1R8176} else if (_rtw_memcmp(extra, "wow_lps_1t1r=", 13)) {8177if (sscanf(extra + 13, "%u", &mode) > 0)8178ret = rtw_pm_set_wow_lps_1t1r(padapter, mode);8179#endif8180}8181#endif /* CONFIG_WOWLAN */8182else8183ret = -EINVAL;81848185return ret;8186}8187#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE81888189int rtw_vendor_ie_get_raw_data(struct net_device *dev, u32 vendor_ie_num,8190char *extra, u32 length)8191{8192int j;8193_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);8194struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);8195u32 vendor_ie_mask = 0;8196char *pstring;81978198if (vendor_ie_num >= WLAN_MAX_VENDOR_IE_NUM) {8199RTW_INFO("[%s] only support %d vendor ie\n", __func__ ,8200WLAN_MAX_VENDOR_IE_NUM);8201return -EFAULT;8202}82038204if (pmlmepriv->vendor_ielen[vendor_ie_num] == 0) {8205RTW_INFO("[%s] Fail, vendor_ie_num: %d is not set\n", __func__,8206vendor_ie_num);8207return -EFAULT;8208}82098210if (length < 2 * pmlmepriv->vendor_ielen[vendor_ie_num] + 5) {8211RTW_INFO("[%s] Fail, buffer size is too small\n", __func__);8212return -EFAULT;8213}82148215vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];8216_rtw_memset(extra, 0, length);82178218pstring = extra;8219pstring += sprintf(pstring, "%d,%x,", vendor_ie_num, vendor_ie_mask);82208221for (j = 0; j < pmlmepriv->vendor_ielen[vendor_ie_num]; j++)8222pstring += sprintf(pstring, "%02x", pmlmepriv->vendor_ie[vendor_ie_num][j]);82238224length = pstring - extra;8225return length;8226}82278228int rtw_vendor_ie_get_data(struct net_device *dev, int vendor_ie_num, char *extra)8229{8230int j;8231char *pstring;8232_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);8233struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);8234u32 vendor_ie_mask = 0;8235__u16 length = 0;82368237vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];8238pstring = extra;8239pstring += sprintf(pstring , "\nVendor IE num %d , Mask:%x " , vendor_ie_num , vendor_ie_mask);82408241if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)8242pstring += sprintf(pstring , "[Beacon]");8243if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)8244pstring += sprintf(pstring , "[Probe Req]");8245if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)8246pstring += sprintf(pstring , "[Probe Resp]");8247if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)8248pstring += sprintf(pstring , "[Assoc Req]");8249if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)8250pstring += sprintf(pstring , "[Assoc Resp]");8251#ifdef CONFIG_P2P8252if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)8253pstring += sprintf(pstring , "[P2P_Probe Req]");8254if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)8255pstring += sprintf(pstring , "[P2P_Probe Resp]");8256#endif82578258pstring += sprintf(pstring , "\nVendor IE:\n");8259for (j = 0 ; j < pmlmepriv->vendor_ielen[vendor_ie_num] ; j++)8260pstring += sprintf(pstring , "%02x" , pmlmepriv->vendor_ie[vendor_ie_num][j]);82618262length = pstring - extra;8263return length;82648265}82668267int rtw_vendor_ie_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)8268{8269int ret = 0, vendor_ie_num = 0, cmdlen;8270struct iw_point *p;8271u8 *ptmp;82728273p = &wrqu->data;8274cmdlen = p->length;8275if (0 == cmdlen)8276return -EINVAL;82778278ptmp = (u8 *)rtw_malloc(cmdlen);8279if (NULL == ptmp)8280return -ENOMEM;82818282if (copy_from_user(ptmp, p->pointer, cmdlen)) {8283ret = -EFAULT;8284goto exit;8285}8286ret = sscanf(ptmp , "%d", &vendor_ie_num);8287if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {8288ret = -EFAULT;8289goto exit;8290}82918292wrqu->data.length = rtw_vendor_ie_get_data(dev, vendor_ie_num, extra);82938294exit:8295rtw_mfree(ptmp, cmdlen);82968297return 0;8298}82998300int rtw_vendor_ie_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)8301{8302int ret = 0, i , len = 0 , totoal_ie_len = 0 , total_ie_len_byte = 0;8303_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);8304struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);8305u32 vendor_ie_mask = 0;8306u32 vendor_ie_num = 0;8307u32 vendor_ie_mask_max = BIT(WLAN_MAX_VENDOR_IE_MASK_MAX) - 1;8308u32 id, elen;83098310ret = sscanf(extra, "%d,%x,%*s", &vendor_ie_num , &vendor_ie_mask);8311if (strrchr(extra , ','))8312extra = strrchr(extra , ',') + 1;8313else8314return -EINVAL;8315totoal_ie_len = strlen(extra);8316RTW_INFO("[%s] vendor_ie_num = %d , vendor_ie_mask = 0x%x , vendor_ie = %s , len = %d\n", __func__ , vendor_ie_num , vendor_ie_mask , extra , totoal_ie_len);83178318if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {8319RTW_INFO("[%s] Fail, only support %d vendor ie\n", __func__ , WLAN_MAX_VENDOR_IE_NUM);8320return -EFAULT;8321}83228323if (totoal_ie_len > WLAN_MAX_VENDOR_IE_LEN) {8324RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_VENDOR_IE_LEN);8325return -EFAULT;8326}83278328if (vendor_ie_mask > vendor_ie_mask_max) {8329RTW_INFO("[%s] Fail, not support vendor_ie_mask more than 0x%x\n", __func__ , vendor_ie_mask_max);8330return -EFAULT;8331}83328333if (vendor_ie_mask == 0) {8334RTW_INFO("[%s] Clear vendor_ie_num %d group\n", __func__ , vendor_ie_num);8335goto _clear_path;8336}83378338if (totoal_ie_len % 2 != 0) {8339RTW_INFO("[%s] Fail , IE length = %zu is odd\n" , __func__ , strlen(extra));8340return -EFAULT;8341}83428343if (totoal_ie_len > 0) {8344for (i = 0 ; i < strlen(extra) ; i += 2) {8345pmlmepriv->vendor_ie[vendor_ie_num][len] = key_2char2num(extra[i] , extra[i + 1]);8346if (len == 0) {8347id = pmlmepriv->vendor_ie[vendor_ie_num][len];8348if (id != WLAN_EID_VENDOR_SPECIFIC) {8349RTW_INFO("[%s] Fail , VENDOR SPECIFIC IE ID \"%x\" was not correct\n", __func__ , id);8350goto _clear_path;8351}8352} else if (len == 1) {8353total_ie_len_byte = (totoal_ie_len / 2) - 2;8354elen = pmlmepriv->vendor_ie[vendor_ie_num][len];8355if (elen != total_ie_len_byte) {8356RTW_INFO("[%s] Fail , Input IE length = \"%d\"(hex:%x) bytes , not match input total IE context length \"%d\" bytes\n", __func__ , elen , elen ,8357total_ie_len_byte);8358goto _clear_path;8359}8360}8361len++;8362}8363pmlmepriv->vendor_ielen[vendor_ie_num] = len;8364} else8365pmlmepriv->vendor_ielen[vendor_ie_num] = 0;8366836783688369if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)8370RTW_INFO("[%s] Beacon append vendor ie\n", __func__);8371if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)8372RTW_INFO("[%s] Probe Req append vendor ie\n", __func__);8373if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)8374RTW_INFO("[%s] Probe Resp append vendor ie\n", __func__);8375if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)8376RTW_INFO("[%s] Assoc Req append vendor ie\n", __func__);8377if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)8378RTW_INFO("[%s] Assoc Resp append vendor ie\n", __func__);8379#ifdef CONFIG_P2P8380if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)8381RTW_INFO("[%s] P2P Probe Req append vendor ie\n", __func__);8382if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)8383RTW_INFO("[%s] P2P Probe Resp append vendor ie\n", __func__);8384#endif83858386pmlmepriv->vendor_ie_mask[vendor_ie_num] = vendor_ie_mask;83878388return ret;83898390_clear_path:8391_rtw_memset(pmlmepriv->vendor_ie[vendor_ie_num] , 0 , sizeof(u32) * WLAN_MAX_VENDOR_IE_LEN);8392pmlmepriv->vendor_ielen[vendor_ie_num] = 0;8393pmlmepriv->vendor_ie_mask[vendor_ie_num] = 0;8394return -EFAULT;8395}8396#endif83978398static int rtw_mp_efuse_get(struct net_device *dev,8399struct iw_request_info *info,8400union iwreq_data *wdata, char *extra)8401{8402PADAPTER padapter = rtw_netdev_priv(dev);8403HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);84048405PEFUSE_HAL pEfuseHal;8406struct iw_point *wrqu;84078408u8 ips_mode = IPS_NUM; /* init invalid value */8409u8 lps_mode = PS_MODE_NUM; /* init invalid value */8410struct pwrctrl_priv *pwrctrlpriv ;8411u8 *data = NULL;8412u8 *rawdata = NULL;8413char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};8414u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;8415u16 max_available_len = 0, raw_cursize = 0, raw_maxsize = 0;8416u16 mask_len;8417u8 mask_buf[64] = "";8418int err;8419char *pextra = NULL;8420#ifdef CONFIG_IOL8421u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */8422#endif84238424wrqu = (struct iw_point *)wdata;8425pwrctrlpriv = adapter_to_pwrctl(padapter);8426pEfuseHal = &pHalData->EfuseHal;84278428err = 0;8429data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);8430if (data == NULL) {8431err = -ENOMEM;8432goto exit;8433}8434rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);8435if (rawdata == NULL) {8436err = -ENOMEM;8437goto exit;8438}84398440if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {8441err = -EFAULT;8442goto exit;8443}84448445*(extra + wrqu->length) = '\0';84468447#ifdef CONFIG_LPS8448lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */8449rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);8450#endif84518452#ifdef CONFIG_IPS8453ips_mode = pwrctrlpriv->ips_mode;/* keep org value */8454rtw_pm_set_ips(padapter, IPS_NONE);8455#endif84568457pch = extra;8458RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);84598460i = 0;8461/* mac 16 "00e04c871200" rmap,00,2 */8462while ((token = strsep(&pch, ",")) != NULL) {8463if (i > 2)8464break;8465tmp[i] = token;8466i++;8467}8468#ifdef CONFIG_IOL8469padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */8470#endif84718472if (strcmp(tmp[0], "status") == 0) {8473sprintf(extra, "Load File efuse=%s,Load File MAC=%s"8474, pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK"8475, pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK"8476);8477goto exit;8478} else if (strcmp(tmp[0], "drvmap") == 0) {8479static u8 drvmaporder = 0;8480u8 *efuse;8481u32 shift, cnt;8482u32 blksz = 0x200; /* The size of one time show, default 512 */8483EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);84848485efuse = pHalData->efuse_eeprom_data;84868487shift = blksz * drvmaporder;8488efuse += shift;8489cnt = mapLen - shift;84908491if (cnt > blksz) {8492cnt = blksz;8493drvmaporder++;8494} else8495drvmaporder = 0;84968497sprintf(extra, "\n");8498for (i = 0; i < cnt; i += 16) {8499pextra = extra + strlen(extra);8500pextra += sprintf(pextra, "0x%02x\t", shift + i);8501for (j = 0; j < 8; j++)8502pextra += sprintf(pextra, "%02X ", efuse[i + j]);8503pextra += sprintf(pextra, "\t");8504for (; j < 16; j++)8505pextra += sprintf(pextra, "%02X ", efuse[i + j]);8506pextra += sprintf(pextra, "\n");8507}8508if ((shift + cnt) < mapLen)8509pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);85108511} else if (strcmp(tmp[0], "realmap") == 0) {8512static u8 order = 0;8513u8 *efuse;8514u32 shift, cnt;8515u32 blksz = 0x200; /* The size of one time show, default 512 */85168517EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);8518efuse = pEfuseHal->fakeEfuseInitMap;8519if (rtw_efuse_mask_map_read(padapter, 0, mapLen, efuse) == _FAIL) {8520RTW_INFO("%s: read realmap Fail!!\n", __FUNCTION__);8521err = -EFAULT;8522goto exit;8523}85248525#if 08526RTW_INFO("OFFSET\tVALUE(hex)\n");8527for (i = 0; i < mapLen; i += 16) {8528RTW_INFO("0x%02x\t", i);8529for (j = 0; j < 8; j++)8530RTW_INFO("%02X ", efuse[i + j]);8531RTW_INFO("\t");8532for (; j < 16; j++)8533RTW_INFO("%02X ", efuse[i + j]);8534RTW_INFO("\n");8535}8536RTW_INFO("\n");8537#endif85388539shift = blksz * order;8540efuse += shift;8541cnt = mapLen - shift;8542if (cnt > blksz) {8543cnt = blksz;8544order++;8545} else8546order = 0;85478548sprintf(extra, "\n");8549for (i = 0; i < cnt; i += 16) {8550pextra = extra + strlen(extra);8551pextra += sprintf(pextra, "0x%02x\t", shift + i);8552for (j = 0; j < 8; j++)8553pextra += sprintf(pextra, "%02X ", efuse[i + j]);8554pextra += sprintf(pextra, "\t");8555for (; j < 16; j++)8556pextra += sprintf(pextra, "%02X ", efuse[i + j]);8557pextra += sprintf(pextra, "\n");8558}8559if ((shift + cnt) < mapLen)8560pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);8561} else if (strcmp(tmp[0], "rmap") == 0) {8562if ((tmp[1] == NULL) || (tmp[2] == NULL)) {8563RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);8564err = -EINVAL;8565goto exit;8566}85678568/* rmap addr cnts */8569addr = simple_strtoul(tmp[1], &ptmp, 16);8570RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);85718572cnts = simple_strtoul(tmp[2], &ptmp, 10);8573if (cnts == 0) {8574RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);8575err = -EINVAL;8576goto exit;8577}8578RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);85798580EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&max_available_len, _FALSE);8581if ((addr + cnts) > max_available_len) {8582RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);8583err = -EINVAL;8584goto exit;8585}85868587if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {8588RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);8589err = -EFAULT;8590goto exit;8591}85928593/* RTW_INFO("%s: data={", __FUNCTION__); */8594*extra = 0;8595pextra = extra;8596for (i = 0; i < cnts; i++) {8597/* RTW_INFO("0x%02x ", data[i]); */8598pextra += sprintf(pextra, "0x%02X ", data[i]);8599}8600/* RTW_INFO("}\n"); */8601} else if (strcmp(tmp[0], "realraw") == 0) {8602static u8 raw_order = 0;8603u32 shift, cnt;8604u32 blksz = 0x200; /* The size of one time show, default 512 */86058606addr = 0;8607EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN , (void *)&mapLen, _FALSE);8608RTW_INFO("Real content len = %d\n",mapLen );86098610if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {8611RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);8612err = -EFAULT;8613goto exit;8614}86158616_rtw_memset(extra, '\0', strlen(extra));86178618shift = blksz * raw_order;8619rawdata += shift;8620cnt = mapLen - shift;8621if (cnt > blksz) {8622cnt = blksz;8623raw_order++;8624} else8625raw_order = 0;86268627sprintf(extra, "\n");8628for (i = 0; i < cnt; i += 16) {8629pextra = extra + strlen(extra);8630pextra += sprintf(pextra, "0x%02x\t", shift + i);8631for (j = 0; j < 8; j++)8632pextra += sprintf(pextra, "%02X ", rawdata[i + j]);8633pextra += sprintf(pextra, "\t");8634for (; j < 16; j++)8635pextra += sprintf(pextra, "%02X ", rawdata[i + j]);8636pextra += sprintf(pextra, "\n");8637}8638if ((shift + cnt) < mapLen)8639pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);86408641} else if (strcmp(tmp[0], "btrealraw") == 0) {8642static u8 bt_raw_order = 0;8643u32 shift, cnt;8644u32 blksz = 0x200; /* The size of one time show, default 512 */86458646addr = 0;8647EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&mapLen, _FALSE);8648RTW_INFO("Real content len = %d\n", mapLen);8649#ifdef RTW_HALMAC8650if (rtw_efuse_bt_access(padapter, _FALSE, 0, mapLen, rawdata) == _FAIL) {8651RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);8652err = -EFAULT;8653goto exit;8654}8655#else8656rtw_write8(padapter, 0x35, 0x1);86578658if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {8659RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);8660err = -EFAULT;8661goto exit;8662}8663#endif8664_rtw_memset(extra, '\0', strlen(extra));86658666shift = blksz * bt_raw_order;8667rawdata += shift;8668cnt = mapLen - shift;8669if (cnt > blksz) {8670cnt = blksz;8671bt_raw_order++;8672} else8673bt_raw_order = 0;86748675sprintf(extra, "\n");8676for (i = 0; i < cnt; i += 16) {8677pextra = extra + strlen(extra);8678pextra += sprintf(pextra, "0x%02x\t", shift + i);8679for (j = 0; j < 8; j++)8680pextra += sprintf(pextra, "%02X ", rawdata[i + j]);8681pextra += sprintf(pextra, "\t");8682for (; j < 16; j++)8683pextra += sprintf(pextra, "%02X ", rawdata[i + j]);8684pextra += sprintf(pextra, "\n");8685}8686if ((shift + cnt) < mapLen)8687pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);86888689} else if (strcmp(tmp[0], "mac") == 0) {8690if (hal_efuse_macaddr_offset(padapter) == -1) {8691err = -EFAULT;8692goto exit;8693}86948695addr = hal_efuse_macaddr_offset(padapter);8696cnts = 6;86978698EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);8699if ((addr + cnts) > max_available_len) {8700RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);8701err = -EFAULT;8702goto exit;8703}87048705if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {8706RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);8707err = -EFAULT;8708goto exit;8709}87108711/* RTW_INFO("%s: MAC address={", __FUNCTION__); */8712*extra = 0;8713pextra = extra;8714for (i = 0; i < cnts; i++) {8715/* RTW_INFO("%02X", data[i]); */8716pextra += sprintf(pextra, "%02X", data[i]);8717if (i != (cnts - 1)) {8718/* RTW_INFO(":"); */8719pextra += sprintf(pextra, ":");8720}8721}8722/* RTW_INFO("}\n"); */8723} else if (strcmp(tmp[0], "vidpid") == 0) {8724#ifdef CONFIG_RTL8188E8725#ifdef CONFIG_USB_HCI8726addr = EEPROM_VID_88EU;8727#endif8728#ifdef CONFIG_PCI_HCI8729addr = EEPROM_VID_88EE;8730#endif8731#endif /* CONFIG_RTL8188E */87328733#ifdef CONFIG_RTL8192E8734#ifdef CONFIG_USB_HCI8735addr = EEPROM_VID_8192EU;8736#endif8737#ifdef CONFIG_PCI_HCI8738addr = EEPROM_VID_8192EE;8739#endif8740#endif /* CONFIG_RTL8192E */8741#ifdef CONFIG_RTL8723B8742addr = EEPROM_VID_8723BU;8743#endif /* CONFIG_RTL8192E */87448745#ifdef CONFIG_RTL8188F8746addr = EEPROM_VID_8188FU;8747#endif /* CONFIG_RTL8188F */87488749#ifdef CONFIG_RTL8188GTV8750addr = EEPROM_VID_8188GTVU;8751#endif87528753#ifdef CONFIG_RTL8703B8754#ifdef CONFIG_USB_HCI8755addr = EEPROM_VID_8703BU;8756#endif8757#endif /* CONFIG_RTL8703B */87588759#ifdef CONFIG_RTL8723D8760#ifdef CONFIG_USB_HCI8761addr = EEPROM_VID_8723DU;8762#endif /* CONFIG_USB_HCI */8763#endif /* CONFIG_RTL8723D */87648765cnts = 4;87668767EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);8768if ((addr + cnts) > max_available_len) {8769RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);8770err = -EFAULT;8771goto exit;8772}8773if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {8774RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);8775err = -EFAULT;8776goto exit;8777}87788779/* RTW_INFO("%s: {VID,PID}={", __FUNCTION__); */8780*extra = 0;8781pextra = extra;8782for (i = 0; i < cnts; i++) {8783/* RTW_INFO("0x%02x", data[i]); */8784pextra += sprintf(pextra, "0x%02X", data[i]);8785if (i != (cnts - 1)) {8786/* RTW_INFO(","); */8787pextra += sprintf(pextra, ",");8788}8789}8790/* RTW_INFO("}\n"); */8791} else if (strcmp(tmp[0], "ableraw") == 0) {8792#ifdef RTW_HALMAC8793raw_maxsize = efuse_GetavailableSize(padapter);8794#else8795efuse_GetCurrentSize(padapter, &raw_cursize);8796raw_maxsize = efuse_GetMaxSize(padapter);8797#endif8798sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);8799} else if (strcmp(tmp[0], "btableraw") == 0) {8800efuse_bt_GetCurrentSize(padapter, &raw_cursize);8801raw_maxsize = efuse_bt_GetMaxSize(padapter);8802sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);8803} else if (strcmp(tmp[0], "btfmap") == 0) {88048805BTEfuse_PowerSwitch(padapter, 1, _TRUE);88068807mapLen = EFUSE_BT_MAX_MAP_LEN;8808if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {8809RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);8810err = -EFAULT;8811goto exit;8812}88138814/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */8815sprintf(extra, "\n");8816for (i = 0; i < 512; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */8817/* RTW_INFO("0x%03x\t", i); */8818pextra = extra + strlen(extra);8819pextra += sprintf(pextra, "0x%03x\t", i);8820for (j = 0; j < 8; j++) {8821/* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */8822pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);8823}8824/* RTW_INFO("\t"); */8825pextra += sprintf(pextra, "\t");8826for (; j < 16; j++) {8827/* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */8828pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);8829}8830/* RTW_INFO("\n"); */8831pextra += sprintf(pextra, "\n");8832}8833/* RTW_INFO("\n"); */8834} else if (strcmp(tmp[0], "btbmap") == 0) {8835BTEfuse_PowerSwitch(padapter, 1, _TRUE);88368837mapLen = EFUSE_BT_MAX_MAP_LEN;8838if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {8839RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);8840err = -EFAULT;8841goto exit;8842}88438844/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */8845sprintf(extra, "\n");8846for (i = 512; i < 1024 ; i += 16) {8847/* RTW_INFO("0x%03x\t", i); */8848pextra = extra + strlen(extra);8849pextra += sprintf(pextra, "0x%03x\t", i);8850for (j = 0; j < 8; j++) {8851/* RTW_INFO("%02X ", data[i+j]); */8852pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);8853}8854/* RTW_INFO("\t"); */8855pextra += sprintf(pextra, "\t");8856for (; j < 16; j++) {8857/* RTW_INFO("%02X ", data[i+j]); */8858pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);8859}8860/* RTW_INFO("\n"); */8861pextra += sprintf(pextra, "\n");8862}8863/* RTW_INFO("\n"); */8864} else if (strcmp(tmp[0], "btrmap") == 0) {8865u8 BTStatus;88668867rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */8868BTStatus = rtw_read8(padapter, 0xa0);88698870RTW_INFO("%s: Check 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);8871if (BTStatus != 0x04) {8872sprintf(extra, "BT Status not Active ,can't to read BT eFuse\n");8873goto exit;8874}88758876if ((tmp[1] == NULL) || (tmp[2] == NULL)) {8877err = -EINVAL;8878goto exit;8879}88808881BTEfuse_PowerSwitch(padapter, 1, _TRUE);88828883/* rmap addr cnts */8884addr = simple_strtoul(tmp[1], &ptmp, 16);8885RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);88868887cnts = simple_strtoul(tmp[2], &ptmp, 10);8888if (cnts == 0) {8889RTW_INFO("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);8890err = -EINVAL;8891goto exit;8892}8893RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);8894#ifndef RTW_HALMAC8895EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);8896if ((addr + cnts) > max_available_len) {8897RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);8898err = -EFAULT;8899goto exit;8900}8901#endif8902if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {8903RTW_INFO("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);8904err = -EFAULT;8905goto exit;8906}89078908*extra = 0;8909pextra = extra;8910/* RTW_INFO("%s: bt efuse data={", __FUNCTION__); */8911for (i = 0; i < cnts; i++) {8912/* RTW_INFO("0x%02x ", data[i]); */8913pextra += sprintf(pextra, " 0x%02X ", data[i]);8914}8915/* RTW_INFO("}\n"); */8916RTW_INFO(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);8917} else if (strcmp(tmp[0], "btffake") == 0) {8918/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */8919sprintf(extra, "\n");8920for (i = 0; i < 512; i += 16) {8921/* RTW_INFO("0x%03x\t", i); */8922pextra = extra + strlen(extra);8923pextra += sprintf(pextra, "0x%03x\t", i);8924for (j = 0; j < 8; j++) {8925/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */8926pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);8927}8928/* RTW_INFO("\t"); */8929pextra += sprintf(pextra, "\t");8930for (; j < 16; j++) {8931/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */8932pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);8933}8934/* RTW_INFO("\n"); */8935pextra += sprintf(pextra, "\n");8936}8937/* RTW_INFO("\n"); */8938} else if (strcmp(tmp[0], "btbfake") == 0) {8939/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */8940sprintf(extra, "\n");8941for (i = 512; i < 1024; i += 16) {8942/* RTW_INFO("0x%03x\t", i); */8943pextra = extra + strlen(extra);8944pextra += sprintf(pextra, "0x%03x\t", i);8945for (j = 0; j < 8; j++) {8946/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */8947pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);8948}8949/* RTW_INFO("\t"); */8950pextra += sprintf(pextra, "\t");8951for (; j < 16; j++) {8952/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */8953pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);8954}8955/* RTW_INFO("\n"); */8956pextra += sprintf(pextra, "\n");8957}8958/* RTW_INFO("\n"); */8959} else if (strcmp(tmp[0], "wlrfkmap") == 0) {8960static u8 fk_order = 0;8961u8 *efuse;8962u32 shift, cnt;8963u32 blksz = 0x200; /* The size of one time show, default 512 */89648965EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);8966efuse = pEfuseHal->fakeEfuseModifiedMap;89678968shift = blksz * fk_order;8969efuse += shift;8970cnt = mapLen - shift;8971if (cnt > blksz) {8972cnt = blksz;8973fk_order++;8974} else8975fk_order = 0;89768977sprintf(extra, "\n");8978for (i = 0; i < cnt; i += 16) {8979pextra = extra + strlen(extra);8980pextra += sprintf(pextra, "0x%02x\t", shift + i);8981for (j = 0; j < 8; j++)8982pextra += sprintf(pextra, "%02X ", efuse[i + j]);8983pextra += sprintf(pextra, "\t");8984for (; j < 16; j++)8985pextra += sprintf(pextra, "%02X ", efuse[i + j]);8986pextra += sprintf(pextra, "\n");8987}8988if ((shift + cnt) < mapLen)8989pextra += sprintf(pextra, "\t...more\n");89908991} else if (strcmp(tmp[0], "wlrfkrmap") == 0) {8992if ((tmp[1] == NULL) || (tmp[2] == NULL)) {8993RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);8994err = -EINVAL;8995goto exit;8996}8997/* rmap addr cnts */8998addr = simple_strtoul(tmp[1], &ptmp, 16);8999RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);90009001cnts = simple_strtoul(tmp[2], &ptmp, 10);9002if (cnts == 0) {9003RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);9004err = -EINVAL;9005goto exit;9006}9007RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);90089009/* RTW_INFO("%s: data={", __FUNCTION__); */9010*extra = 0;9011pextra = extra;9012for (i = 0; i < cnts; i++) {9013RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeEfuseModifiedMap[addr + i]);9014pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeEfuseModifiedMap[addr+i]);9015}9016} else if (strcmp(tmp[0], "btrfkrmap") == 0) {9017if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9018RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);9019err = -EINVAL;9020goto exit;9021}9022/* rmap addr cnts */9023addr = simple_strtoul(tmp[1], &ptmp, 16);9024RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);90259026cnts = simple_strtoul(tmp[2], &ptmp, 10);9027if (cnts == 0) {9028RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);9029err = -EINVAL;9030goto exit;9031}9032RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);90339034/* RTW_INFO("%s: data={", __FUNCTION__); */9035*extra = 0;9036pextra = extra;9037for (i = 0; i < cnts; i++) {9038RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeBTEfuseModifiedMap[addr + i]);9039pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);9040}9041} else if (strcmp(tmp[0], "mask") == 0) {9042*extra = 0;9043mask_len = sizeof(u8) * rtw_get_efuse_mask_arraylen(padapter);9044rtw_efuse_mask_array(padapter, mask_buf);90459046if (padapter->registrypriv.bFileMaskEfuse == _TRUE)9047_rtw_memcpy(mask_buf, maskfileBuffer, mask_len);90489049sprintf(extra, "\n");9050pextra = extra + strlen(extra);9051for (i = 0; i < mask_len; i++)9052pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);90539054} else if (strcmp(tmp[0], "btmask") == 0) {9055*extra = 0;9056mask_len = sizeof(u8) * rtw_get_bt_efuse_mask_arraylen(padapter);9057rtw_bt_efuse_mask_array(padapter, mask_buf);90589059if (padapter->registrypriv.bBTFileMaskEfuse == _TRUE)9060_rtw_memcpy(mask_buf, btmaskfileBuffer, mask_len);90619062sprintf(extra, "\n");9063pextra = extra + strlen(extra);9064for (i = 0; i < mask_len; i++)9065pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);90669067} else9068sprintf(extra, "Command not found!");90699070exit:9071if (data)9072rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);9073if (rawdata)9074rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);9075if (!err)9076wrqu->length = strlen(extra);90779078if (padapter->registrypriv.mp_mode == 0) {9079#ifdef CONFIG_IPS9080rtw_pm_set_ips(padapter, ips_mode);9081#endif /* CONFIG_IPS */90829083#ifdef CONFIG_LPS9084rtw_pm_set_lps(padapter, lps_mode);9085#endif /* CONFIG_LPS */9086}90879088#ifdef CONFIG_IOL9089padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */9090#endif9091return err;9092}909390949095#ifdef CONFIG_MP_INCLUDED9096static int rtw_mp_efuse_set(struct net_device *dev,9097struct iw_request_info *info,9098union iwreq_data *wdata, char *extra)9099{9100struct iw_point *wrqu;9101PADAPTER padapter;9102struct pwrctrl_priv *pwrctrlpriv ;9103PHAL_DATA_TYPE pHalData;9104PEFUSE_HAL pEfuseHal;9105struct hal_ops *pHalFunc;9106struct mp_priv *pmp_priv;91079108u8 ips_mode = IPS_NUM; /* init invalid value */9109u8 lps_mode = PS_MODE_NUM; /* init invalid value */9110u32 i = 0, j = 0, jj, kk;9111u8 *setdata = NULL;9112u8 *ShadowMapBT = NULL;9113u8 *ShadowMapWiFi = NULL;9114u8 *setrawdata = NULL;9115char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};9116u16 addr = 0xFF, cnts = 0, BTStatus = 0 , max_available_len = 0;9117u16 wifimaplen;9118int err;9119boolean bcmpchk = _TRUE;912091219122wrqu = (struct iw_point *)wdata;9123padapter = rtw_netdev_priv(dev);9124pwrctrlpriv = adapter_to_pwrctl(padapter);9125pHalData = GET_HAL_DATA(padapter);9126pEfuseHal = &pHalData->EfuseHal;9127pHalFunc = &padapter->hal_func;9128pmp_priv = &padapter->mppriv;91299130err = 0;91319132if (copy_from_user(extra, wrqu->pointer, wrqu->length))9133return -EFAULT;91349135*(extra + wrqu->length) = '\0';91369137EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&wifimaplen, _FALSE);91389139setdata = rtw_zmalloc(1024);9140if (setdata == NULL) {9141err = -ENOMEM;9142goto exit;9143}9144ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);9145if (ShadowMapBT == NULL) {9146err = -ENOMEM;9147goto exit;9148}9149ShadowMapWiFi = rtw_malloc(wifimaplen);9150if (ShadowMapWiFi == NULL) {9151err = -ENOMEM;9152goto exit;9153}9154setrawdata = rtw_malloc(EFUSE_MAX_SIZE);9155if (setrawdata == NULL) {9156err = -ENOMEM;9157goto exit;9158}91599160#ifdef CONFIG_LPS9161lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */9162rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);9163#endif91649165#ifdef CONFIG_IPS9166ips_mode = pwrctrlpriv->ips_mode;/* keep org value */9167rtw_pm_set_ips(padapter, IPS_NONE);9168#endif91699170pch = extra;9171RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);91729173i = 0;9174while ((token = strsep(&pch, ",")) != NULL) {9175if (i > 2)9176break;9177tmp[i] = token;9178i++;9179}91809181/* tmp[0],[1],[2] */9182/* wmap,addr,00e04c871200 */9183if (strcmp(tmp[0], "wmap") == 0) {9184if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9185err = -EINVAL;9186goto exit;9187}91889189#ifndef RTW_HALMAC9190/* unknown bug workaround, need to fix later */9191addr = 0x1ff;9192rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));9193rtw_msleep_os(10);9194rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));9195rtw_msleep_os(10);9196rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);9197rtw_msleep_os(10);9198rtw_read8(padapter, EFUSE_CTRL);9199#endif /* RTW_HALMAC */92009201addr = simple_strtoul(tmp[1], &ptmp, 16);9202addr &= 0xFFF;92039204cnts = strlen(tmp[2]);9205if (cnts % 2) {9206err = -EINVAL;9207goto exit;9208}9209cnts /= 2;9210if (cnts == 0) {9211err = -EINVAL;9212goto exit;9213}92149215RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9216RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9217RTW_INFO("%s: map data=%s\n", __FUNCTION__, tmp[2]);92189219for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9220setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);92219222EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);92239224if ((addr + cnts) > max_available_len) {9225RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);9226err = -EFAULT;9227goto exit;9228}92299230if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {9231RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);9232err = -EFAULT;9233goto exit;9234}9235*extra = 0;9236RTW_INFO("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__);9237if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS) {9238if (_rtw_memcmp((void *)ShadowMapWiFi , (void *)setdata, cnts)) {9239RTW_INFO("%s: WiFi write map afterf compare success\n", __FUNCTION__);9240sprintf(extra, "WiFi write map compare OK\n");9241err = 0;9242goto exit;9243} else {9244sprintf(extra, "WiFi write map compare FAIL\n");9245RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);9246err = 0;9247goto exit;9248}9249}9250} else if (strcmp(tmp[0], "wraw") == 0) {9251if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9252err = -EINVAL;9253goto exit;9254}92559256addr = simple_strtoul(tmp[1], &ptmp, 16);9257addr &= 0xFFF;92589259cnts = strlen(tmp[2]);9260if (cnts % 2) {9261err = -EINVAL;9262goto exit;9263}9264cnts /= 2;9265if (cnts == 0) {9266err = -EINVAL;9267goto exit;9268}92699270RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9271RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9272RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);92739274for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9275setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);92769277if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {9278RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);9279err = -EFAULT;9280goto exit;9281}9282} else if (strcmp(tmp[0], "btwraw") == 0) {9283if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9284err = -EINVAL;9285goto exit;9286}92879288addr = simple_strtoul(tmp[1], &ptmp, 16);9289addr &= 0xFFF;92909291cnts = strlen(tmp[2]);9292if (cnts % 2) {9293err = -EINVAL;9294goto exit;9295}9296cnts /= 2;9297if (cnts == 0) {9298err = -EINVAL;9299goto exit;9300}93019302RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9303RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9304RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);93059306for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9307setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);9308#ifdef RTW_HALMAC9309if (rtw_efuse_bt_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {9310RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);9311err = -EFAULT;9312goto exit;9313}9314#else9315rtw_write8(padapter, 0x35, 1); /* switch bank 1 (BT)*/9316if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {9317RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);9318rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/9319err = -EFAULT;9320goto exit;9321}9322rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/9323#endif9324} else if (strcmp(tmp[0], "mac") == 0) {9325if (tmp[1] == NULL) {9326err = -EINVAL;9327goto exit;9328}93299330/* mac,00e04c871200 */93319332if (hal_efuse_macaddr_offset(padapter) == -1) {9333err = -EFAULT;9334goto exit;9335}93369337addr = hal_efuse_macaddr_offset(padapter);9338cnts = strlen(tmp[1]);9339if (cnts % 2) {9340err = -EINVAL;9341goto exit;9342}9343cnts /= 2;9344if (cnts == 0) {9345err = -EINVAL;9346goto exit;9347}9348if (cnts > 6) {9349RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);9350err = -EFAULT;9351goto exit;9352}93539354RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9355RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9356RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);93579358for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9359setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);93609361EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);93629363if ((addr + cnts) > max_available_len) {9364RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);9365err = -EFAULT;9366goto exit;9367}93689369if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {9370RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);9371err = -EFAULT;9372goto exit;9373}9374} else if (strcmp(tmp[0], "vidpid") == 0) {9375if (tmp[1] == NULL) {9376err = -EINVAL;9377goto exit;9378}93799380/* pidvid,da0b7881 */9381#ifdef CONFIG_RTL8188E9382#ifdef CONFIG_USB_HCI9383addr = EEPROM_VID_88EU;9384#endif9385#ifdef CONFIG_PCI_HCI9386addr = EEPROM_VID_88EE;9387#endif9388#endif /* CONFIG_RTL8188E */93899390#ifdef CONFIG_RTL8192E9391#ifdef CONFIG_USB_HCI9392addr = EEPROM_VID_8192EU;9393#endif9394#ifdef CONFIG_PCI_HCI9395addr = EEPROM_VID_8192EE;9396#endif9397#endif /* CONFIG_RTL8188E */93989399#ifdef CONFIG_RTL8723B9400addr = EEPROM_VID_8723BU;9401#endif94029403#ifdef CONFIG_RTL8188F9404addr = EEPROM_VID_8188FU;9405#endif94069407#ifdef CONFIG_RTL8188GTV9408addr = EEPROM_VID_8188GTVU;9409#endif94109411#ifdef CONFIG_RTL8703B9412#ifdef CONFIG_USB_HCI9413addr = EEPROM_VID_8703BU;9414#endif /* CONFIG_USB_HCI */9415#endif /* CONFIG_RTL8703B */94169417#ifdef CONFIG_RTL8723D9418#ifdef CONFIG_USB_HCI9419addr = EEPROM_VID_8723DU;9420#endif /* CONFIG_USB_HCI */9421#endif /* CONFIG_RTL8723D */94229423cnts = strlen(tmp[1]);9424if (cnts % 2) {9425err = -EINVAL;9426goto exit;9427}9428cnts /= 2;9429if (cnts == 0) {9430err = -EINVAL;9431goto exit;9432}94339434RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9435RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9436RTW_INFO("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);94379438for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9439setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);94409441EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);9442if ((addr + cnts) > max_available_len) {9443RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);9444err = -EFAULT;9445goto exit;9446}94479448if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {9449RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);9450err = -EFAULT;9451goto exit;9452}9453} else if (strcmp(tmp[0], "wldumpfake") == 0) {9454if (wifimaplen > EFUSE_MAX_MAP_LEN)9455cnts = EFUSE_MAX_MAP_LEN;9456else9457cnts = wifimaplen;9458if (rtw_efuse_mask_map_read(padapter, 0, cnts, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS)9459RTW_INFO("%s: WiFi hw efuse dump to Fake map success\n", __func__);9460else {9461RTW_INFO("%s: WiFi hw efuse dump to Fake map Fail\n", __func__);9462err = -EFAULT;9463}9464} else if (strcmp(tmp[0], "btwmap") == 0) {9465rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */9466BTStatus = rtw_read8(padapter, 0xa0);9467RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);9468if (BTStatus != 0x04) {9469sprintf(extra, "BT Status not Active ,can't do Write\n");9470goto exit;9471}94729473if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9474err = -EINVAL;9475goto exit;9476}94779478#ifndef RTW_HALMAC9479BTEfuse_PowerSwitch(padapter, 1, _TRUE);9480addr = 0x1ff;9481rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));9482rtw_msleep_os(10);9483rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));9484rtw_msleep_os(10);9485rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);9486rtw_msleep_os(10);9487rtw_read8(padapter, EFUSE_CTRL);9488BTEfuse_PowerSwitch(padapter, 1, _FALSE);9489#endif /* RTW_HALMAC */94909491addr = simple_strtoul(tmp[1], &ptmp, 16);9492addr &= 0xFFF;94939494cnts = strlen(tmp[2]);9495if (cnts % 2) {9496err = -EINVAL;9497goto exit;9498}9499cnts /= 2;9500if (cnts == 0) {9501err = -EINVAL;9502goto exit;9503}95049505RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9506RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9507RTW_INFO("%s: BT data=%s\n", __FUNCTION__, tmp[2]);95089509for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9510setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);9511#ifndef RTW_HALMAC9512EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);9513if ((addr + cnts) > max_available_len) {9514RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);9515err = -EFAULT;9516goto exit;9517}9518#endif9519if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {9520RTW_INFO("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);9521err = -EFAULT;9522goto exit;9523}9524*extra = 0;9525RTW_INFO("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __FUNCTION__);9526if ((rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT) == _SUCCESS)) {9527if (_rtw_memcmp((void *)ShadowMapBT , (void *)setdata, cnts)) {9528RTW_INFO("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__, BTStatus);9529sprintf(extra, "BT write map compare OK");9530err = 0;9531goto exit;9532} else {9533sprintf(extra, "BT write map compare FAIL");9534RTW_INFO("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__, BTStatus);9535err = 0;9536goto exit;9537}9538}9539} else if (strcmp(tmp[0], "btwfake") == 0) {9540if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9541err = -EINVAL;9542goto exit;9543}9544if (pmp_priv->bprocess_mp_mode != _TRUE) {9545RTW_INFO("%s: btwfake not to be exec, please first to mp_start\n", __FUNCTION__);9546sprintf(extra, "Error, btwfake cant to be exec, please first to mp_start !!!!\n");9547err = 0;9548goto exit;9549}9550addr = simple_strtoul(tmp[1], &ptmp, 16);9551addr &= 0xFFF;95529553cnts = strlen(tmp[2]);9554if (cnts % 2) {9555err = -EINVAL;9556goto exit;9557}9558cnts /= 2;9559if (cnts == 0) {9560err = -EINVAL;9561goto exit;9562}95639564RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9565RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9566RTW_INFO("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);95679568for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9569pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);9570} else if (strcmp(tmp[0], "btdumpfake") == 0) {9571if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS)9572RTW_INFO("%s: BT read all map success\n", __FUNCTION__);9573else {9574RTW_INFO("%s: BT read all map Fail!\n", __FUNCTION__);9575err = -EFAULT;9576}9577} else if (strcmp(tmp[0], "btfk2map") == 0) {95789579if (padapter->registrypriv.bBTFileMaskEfuse != _TRUE && pmp_priv->bloadBTefusemap == _TRUE) {9580RTW_INFO("%s: File BT eFuse mask file not to be loaded\n", __FUNCTION__);9581sprintf(extra, "Not load BT eFuse mask file yet, Please advance to use [ efuse_bt_mask ], now remove the Adapter.!!!!\n");9582rtw_set_surprise_removed(padapter);9583err = 0;9584goto exit;9585}95869587rtw_write8(padapter, 0xa3, 0x05);9588BTStatus = rtw_read8(padapter, 0xa0);9589RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);9590if (BTStatus != 0x04) {9591sprintf(extra, "BT Status not Active Write FAIL\n");9592goto exit;9593}9594if (pmp_priv->bprocess_mp_mode != _TRUE) {9595RTW_INFO("%s: btfk2map not to be exec, please first to mp_start\n", __FUNCTION__);9596sprintf(extra, "Error, btfk2map cant to be exec, please first to mp_start !!!!\n");9597err = 0;9598goto exit;9599}9600#ifndef RTW_HALMAC9601BTEfuse_PowerSwitch(padapter, 1, _TRUE);9602addr = 0x1ff;9603rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));9604rtw_msleep_os(10);9605rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));9606rtw_msleep_os(10);9607rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);9608rtw_msleep_os(10);9609rtw_read8(padapter, EFUSE_CTRL);9610BTEfuse_PowerSwitch(padapter, 1, _FALSE);9611#endif /* RTW_HALMAC */9612_rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);96139614if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {9615RTW_INFO("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);9616err = -EFAULT;9617goto exit;9618}96199620RTW_INFO("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");9621for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {9622printk("0x%02x\t", i);9623for (j = 0; j < 8; j++)9624printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);9625printk("\t");96269627for (; j < 16; j++)9628printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);9629printk("\n");9630}9631printk("\n");9632#if 19633err = -EFAULT;9634RTW_INFO("%s: rtw_BT_efuse_map_read _rtw_memcmp\n", __FUNCTION__);9635if ((rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)) {9636if (_rtw_memcmp((void *)pEfuseHal->fakeBTEfuseModifiedMap, (void *)pEfuseHal->fakeBTEfuseInitMap, EFUSE_BT_MAX_MAP_LEN)) {9637sprintf(extra, "BT write map compare OK");9638RTW_INFO("%s: BT write map afterf compare success BTStatus=0x%x\n", __FUNCTION__, BTStatus);9639err = 0;9640goto exit;9641} else {9642sprintf(extra, "BT write map compare FAIL");9643if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)9644RTW_INFO("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__, i);96459646if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS) {9647RTW_INFO("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");96489649for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {9650printk("0x%02x\t", i);9651for (j = 0; j < 8; j++)9652printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);9653printk("\t");9654for (; j < 16; j++)9655printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);9656printk("\n");9657}9658printk("\n");9659}9660RTW_INFO("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__, BTStatus);9661goto exit;9662}9663}9664#endif96659666} else if (strcmp(tmp[0], "wlfk2map") == 0) {9667*extra = 0;96689669if (padapter->registrypriv.bFileMaskEfuse != _TRUE && pmp_priv->bloadefusemap == _TRUE) {9670RTW_INFO("%s: File eFuse mask file not to be loaded\n", __FUNCTION__);9671sprintf(extra, "Not load eFuse mask file yet, Please use the efuse_mask CMD, now remove the interface !!!!\n");9672rtw_set_surprise_removed(padapter);9673err = 0;9674goto exit;9675}96769677if (pmp_priv->bprocess_mp_mode != _TRUE) {9678RTW_INFO("%s: wlfk2map not to be exec, please first to mp_start\n", __FUNCTION__);9679sprintf(extra, "Error, wlfk2map cant to be exec, please first to mp_start !!!!\n");9680err = 0;9681goto exit;9682}9683if (wifimaplen > EFUSE_MAX_MAP_LEN)9684cnts = EFUSE_MAX_MAP_LEN;9685else9686cnts = wifimaplen;9687if (rtw_efuse_map_write(padapter, 0x00, cnts, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {9688RTW_INFO("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);9689err = -EFAULT;9690goto exit;9691}96929693if (rtw_efuse_mask_map_read(padapter, 0x00, wifimaplen, ShadowMapWiFi) == _SUCCESS) {9694addr = 0x00;9695err = _TRUE;96969697for (i = 0; i < cnts; i++) {9698if (padapter->registrypriv.boffefusemask == 0) {9699if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {9700if (rtw_file_efuse_IsMasked(padapter, addr + i, maskfileBuffer) == _TRUE) /*use file efuse mask. */9701bcmpchk = _FALSE;9702} else {9703if (efuse_IsMasked(padapter, addr + i) == _TRUE)9704bcmpchk = _FALSE;9705}9706}97079708if (bcmpchk == _TRUE) {9709RTW_INFO("compare readMapWiFi[0x%02x] = %x, ModifiedMap = %x\n", addr + i, ShadowMapWiFi[ addr + i], pEfuseHal->fakeEfuseModifiedMap[addr + i]);9710if (_rtw_memcmp((void *) &ShadowMapWiFi[addr + i], (void *)&pEfuseHal->fakeEfuseModifiedMap[addr + i], 1) == _FALSE){9711err = _FALSE;9712break;9713}9714}9715bcmpchk = _TRUE;9716}9717}97189719if (err) {9720RTW_INFO("%s: WiFi write map afterf compare OK\n", __FUNCTION__);9721sprintf(extra, "WiFi write map compare OK\n");9722err = 0;9723goto exit;9724} else {9725sprintf(extra, "WiFi write map compare FAIL\n");9726RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);9727err = 0;9728goto exit;9729}9730} else if (strcmp(tmp[0], "wlwfake") == 0) {9731if ((tmp[1] == NULL) || (tmp[2] == NULL)) {9732err = -EINVAL;9733goto exit;9734}9735if (pmp_priv->bprocess_mp_mode != _TRUE) {9736RTW_INFO("%s: wlwfake not to be exec, please first to mp_start\n", __FUNCTION__);9737sprintf(extra, "Error, wlwfake cant to be exec, please first to mp_start !!!!\n");9738err = 0;9739goto exit;9740}9741addr = simple_strtoul(tmp[1], &ptmp, 16);9742addr &= 0xFFF;97439744cnts = strlen(tmp[2]);9745if (cnts % 2) {9746err = -EINVAL;9747goto exit;9748}9749cnts /= 2;9750if (cnts == 0) {9751err = -EINVAL;9752goto exit;9753}97549755RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9756RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9757RTW_INFO("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);97589759for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9760pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);9761_rtw_memset(extra, '\0', strlen(extra));9762sprintf(extra, "wlwfake OK\n");97639764}9765else if (strcmp(tmp[0], "wfakemac") == 0) {9766if (tmp[1] == NULL) {9767err = -EINVAL;9768goto exit;9769}9770if (pmp_priv->bprocess_mp_mode != _TRUE) {9771RTW_INFO("%s: wfakemac not to be exec, please first to mp_start\n", __FUNCTION__);9772sprintf(extra, "Error, wfakemac cant to be exec, please first to mp_start !!!!\n");9773err = 0;9774goto exit;9775}9776/* wfakemac,00e04c871200 */9777if (hal_efuse_macaddr_offset(padapter) == -1) {9778err = -EFAULT;9779goto exit;9780}97819782addr = hal_efuse_macaddr_offset(padapter);9783cnts = strlen(tmp[1]);9784if (cnts % 2) {9785err = -EINVAL;9786goto exit;9787}9788cnts /= 2;9789if (cnts == 0) {9790err = -EINVAL;9791goto exit;9792}9793if (cnts > 6) {9794RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);9795err = -EFAULT;9796goto exit;9797}97989799RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);9800RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);9801RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);98029803for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)9804pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);98059806_rtw_memset(extra, '\0', strlen(extra));9807sprintf(extra, "write mac addr to fake map OK\n");9808} else if(strcmp(tmp[0], "update") == 0) {9809RTW_INFO("To Use new eFuse map\n");9810/*step read efuse/eeprom data and get mac_addr*/9811rtw_hal_read_chip_info(padapter);9812/* set mac addr*/9813rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter));9814_rtw_memcpy(padapter->pnetdev->dev_addr, get_hal_mac_addr(padapter), ETH_ALEN); /* set mac addr to net_device */98159816#ifdef CONFIG_P2P9817rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));9818#endif9819#ifdef CONFIG_MI_WITH_MBSSID_CAM9820rtw_hal_change_macaddr_mbid(padapter, adapter_mac_addr(padapter));9821#else9822rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR, adapter_mac_addr(padapter)); /* set mac addr to mac register */9823#endif9824/*pHalFunc->hal_deinit(padapter);*/9825if (pHalFunc->hal_init(padapter) == _FAIL) {9826err = -EINVAL;9827goto exit;9828}9829_rtw_memset(extra, '\0', strlen(extra));9830sprintf(extra, "eFuse Update OK\n");9831} else if (strcmp(tmp[0], "analyze") == 0) {98329833rtw_efuse_analyze(padapter, EFUSE_WIFI, 0);9834_rtw_memset(extra, '\0', strlen(extra));9835sprintf(extra, "eFuse Analyze OK,please to check kernel log\n");9836}9837exit:9838if (setdata)9839rtw_mfree(setdata, 1024);9840if (ShadowMapBT)9841rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);9842if (ShadowMapWiFi)9843rtw_mfree(ShadowMapWiFi, wifimaplen);9844if (setrawdata)9845rtw_mfree(setrawdata, EFUSE_MAX_SIZE);98469847wrqu->length = strlen(extra);98489849if (padapter->registrypriv.mp_mode == 0) {9850#ifdef CONFIG_IPS9851rtw_pm_set_ips(padapter, ips_mode);9852#endif /* CONFIG_IPS */98539854#ifdef CONFIG_LPS9855rtw_pm_set_lps(padapter, lps_mode);9856#endif /* CONFIG_LPS */9857}98589859return err;9860}98619862#ifdef CONFIG_RTW_CUSTOMER_STR9863static int rtw_mp_customer_str(9864struct net_device *dev,9865struct iw_request_info *info,9866union iwreq_data *wrqu, char *extra)9867{9868_adapter *adapter = rtw_netdev_priv(dev);9869u32 len;9870u8 *pbuf = NULL, *pch;9871char *ptmp;9872u8 param[RTW_CUSTOMER_STR_LEN];9873u8 count = 0;9874u8 tmp;9875u8 i;9876u32 pos;9877u8 ret;9878u8 read = 0;98799880if (adapter->registrypriv.mp_mode != 19881|| !adapter->registrypriv.mp_customer_str)9882return -EFAULT;98839884len = wrqu->data.length + 1;98859886pbuf = (u8 *)rtw_zmalloc(len);9887if (pbuf == NULL) {9888RTW_WARN("%s: no memory!\n", __func__);9889return -ENOMEM;9890}98919892if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length)) {9893rtw_mfree(pbuf, len);9894RTW_WARN("%s: copy from user fail!\n", __func__);9895return -EFAULT;9896}9897RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);98989899ptmp = (char *)pbuf;9900pch = strsep(&ptmp, ",");9901if ((pch == NULL) || (strlen(pch) == 0)) {9902rtw_mfree(pbuf, len);9903RTW_INFO("%s: parameter error(no cmd)!\n", __func__);9904return -EFAULT;9905}99069907_rtw_memset(param, 0xFF, RTW_CUSTOMER_STR_LEN);99089909if (strcmp(pch, "read") == 0) {9910read = 1;9911ret = rtw_hal_customer_str_read(adapter, param);99129913} else if (strcmp(pch, "write") == 0) {9914do {9915pch = strsep(&ptmp, ":");9916if ((pch == NULL) || (strlen(pch) == 0))9917break;9918if (strlen(pch) != 29919|| IsHexDigit(*pch) == _FALSE9920|| IsHexDigit(*(pch + 1)) == _FALSE9921|| sscanf(pch, "%hhx", &tmp) != 19922) {9923RTW_WARN("%s: invalid 8-bit hex!\n", __func__);9924rtw_mfree(pbuf, len);9925return -EFAULT;9926}99279928param[count++] = tmp;99299930} while (count < RTW_CUSTOMER_STR_LEN);99319932if (count == 0) {9933rtw_mfree(pbuf, len);9934RTW_WARN("%s: no input!\n", __func__);9935return -EFAULT;9936}9937ret = rtw_hal_customer_str_write(adapter, param);9938} else {9939rtw_mfree(pbuf, len);9940RTW_INFO("%s: parameter error(unknown cmd)!\n", __func__);9941return -EFAULT;9942}99439944pos = sprintf(extra, "%s: ", read ? "read" : "write");9945if (read == 0 || ret == _SUCCESS) {9946for (i = 0; i < RTW_CUSTOMER_STR_LEN; i++)9947pos += sprintf(extra + pos, "%02x:", param[i]);9948extra[pos] = 0;9949pos--;9950}9951pos += sprintf(extra + pos, " %s", ret == _SUCCESS ? "OK" : "FAIL");99529953wrqu->data.length = strlen(extra) + 1;99549955rtw_mfree(pbuf, len);9956return 0;9957}9958#endif /* CONFIG_RTW_CUSTOMER_STR */99599960static int rtw_priv_mp_set(struct net_device *dev,9961struct iw_request_info *info,9962union iwreq_data *wdata, char *extra)9963{99649965struct iw_point *wrqu = (struct iw_point *)wdata;9966u32 subcmd = wrqu->flags;9967PADAPTER padapter = rtw_netdev_priv(dev);9968int status = 0;99699970#ifdef CONFIG_CONCURRENT_MODE9971if (!is_primary_adapter(padapter)) {9972RTW_INFO("MP mode only primary Adapter support\n");9973return -EIO;9974}9975#endif99769977RTW_INFO("%s mutx in %d\n", __func__, subcmd);9978_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);9979switch (subcmd) {9980case CTA_TEST:9981RTW_INFO("set CTA_TEST\n");9982status = rtw_cta_test_start(dev, info, wdata, extra);9983break;9984case MP_DISABLE_BT_COEXIST:9985RTW_INFO("set case MP_DISABLE_BT_COEXIST\n");9986status = rtw_mp_disable_bt_coexist(dev, info, wdata, extra);9987break;9988case MP_IQK:9989RTW_INFO("set MP_IQK\n");9990status = rtw_mp_iqk(dev, info, wrqu, extra);9991break;9992case MP_LCK:9993RTW_INFO("set MP_LCK\n");9994status = rtw_mp_lck(dev, info, wrqu, extra);9995break;99969997default:9998status = -EIO;9999}10000_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);10001RTW_INFO("%s mutx done %d\n", __func__, subcmd);1000210003return status;10004}1000510006static int rtw_priv_mp_get(struct net_device *dev,10007struct iw_request_info *info,10008union iwreq_data *wdata, char *extra)10009{1001010011struct iw_point *wrqu = (struct iw_point *)wdata;10012u32 subcmd = wrqu->flags;10013PADAPTER padapter = rtw_netdev_priv(dev);10014int status = 0;1001510016#ifdef CONFIG_CONCURRENT_MODE10017if (!is_primary_adapter(padapter)) {10018RTW_INFO("MP mode only primary Adapter support\n");10019return -EIO;10020}10021#endif1002210023RTW_INFO("%s mutx in %d\n", __func__, subcmd);10024_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);1002510026switch (subcmd) {10027case MP_START:10028RTW_INFO("set case mp_start\n");10029status = rtw_mp_start(dev, info, wrqu, extra);10030break;10031case MP_STOP:10032RTW_INFO("set case mp_stop\n");10033status = rtw_mp_stop(dev, info, wrqu, extra);10034break;10035case MP_BANDWIDTH:10036RTW_INFO("set case mp_bandwidth\n");10037status = rtw_mp_bandwidth(dev, info, wrqu, extra);10038break;10039case MP_RESET_STATS:10040RTW_INFO("set case MP_RESET_STATS\n");10041status = rtw_mp_reset_stats(dev, info, wrqu, extra);10042break;10043case MP_SetRFPathSwh:10044RTW_INFO("set MP_SetRFPathSwitch\n");10045status = rtw_mp_SetRFPath(dev, info, wrqu, extra);10046break;10047case WRITE_REG:10048status = rtw_mp_write_reg(dev, info, wrqu, extra);10049break;10050case WRITE_RF:10051status = rtw_mp_write_rf(dev, info, wrqu, extra);10052break;10053case MP_PHYPARA:10054RTW_INFO("mp_get MP_PHYPARA\n");10055status = rtw_mp_phypara(dev, info, wrqu, extra);10056break;10057case MP_CHANNEL:10058RTW_INFO("set case mp_channel\n");10059status = rtw_mp_channel(dev , info, wrqu, extra);10060break;10061case MP_CHL_OFFSET:10062RTW_INFO("set case mp_ch_offset\n");10063status = rtw_mp_ch_offset(dev , info, wrqu, extra);10064break;10065case READ_REG:10066RTW_INFO("mp_get READ_REG\n");10067status = rtw_mp_read_reg(dev, info, wrqu, extra);10068break;10069case READ_RF:10070RTW_INFO("mp_get READ_RF\n");10071status = rtw_mp_read_rf(dev, info, wrqu, extra);10072break;10073case MP_RATE:10074RTW_INFO("set case mp_rate\n");10075status = rtw_mp_rate(dev, info, wrqu, extra);10076break;10077case MP_TXPOWER:10078RTW_INFO("set case MP_TXPOWER\n");10079status = rtw_mp_txpower(dev, info, wrqu, extra);10080break;10081case MP_ANT_TX:10082RTW_INFO("set case MP_ANT_TX\n");10083status = rtw_mp_ant_tx(dev, info, wrqu, extra);10084break;10085case MP_ANT_RX:10086RTW_INFO("set case MP_ANT_RX\n");10087status = rtw_mp_ant_rx(dev, info, wrqu, extra);10088break;10089case MP_QUERY:10090status = rtw_mp_trx_query(dev, info, wrqu, extra);10091break;10092case MP_CTX:10093RTW_INFO("set case MP_CTX\n");10094status = rtw_mp_ctx(dev, info, wrqu, extra);10095break;10096case MP_ARX:10097RTW_INFO("set case MP_ARX\n");10098status = rtw_mp_arx(dev, info, wrqu, extra);10099break;10100case MP_DUMP:10101RTW_INFO("set case MP_DUMP\n");10102status = rtw_mp_dump(dev, info, wrqu, extra);10103break;10104case MP_PSD:10105RTW_INFO("set case MP_PSD\n");10106status = rtw_mp_psd(dev, info, wrqu, extra);10107break;10108case MP_THER:10109RTW_INFO("set case MP_THER\n");10110status = rtw_mp_thermal(dev, info, wrqu, extra);10111break;10112case MP_PwrCtlDM:10113RTW_INFO("set MP_PwrCtlDM\n");10114status = rtw_mp_PwrCtlDM(dev, info, wrqu, extra);10115break;10116case MP_QueryDrvStats:10117RTW_INFO("mp_get MP_QueryDrvStats\n");10118status = rtw_mp_QueryDrv(dev, info, wdata, extra);10119break;10120case MP_PWRTRK:10121RTW_INFO("set case MP_PWRTRK\n");10122status = rtw_mp_pwrtrk(dev, info, wrqu, extra);10123break;10124#ifdef CONFIG_MP_INCLUDED10125case EFUSE_SET:10126RTW_INFO("set case efuse set\n");10127status = rtw_mp_efuse_set(dev, info, wdata, extra);10128break;10129#endif10130case EFUSE_GET:10131RTW_INFO("efuse get EFUSE_GET\n");10132status = rtw_mp_efuse_get(dev, info, wdata, extra);10133break;10134case MP_GET_TXPOWER_INX:10135RTW_INFO("mp_get MP_GET_TXPOWER_INX\n");10136status = rtw_mp_txpower_index(dev, info, wrqu, extra);10137break;10138case MP_GETVER:10139RTW_INFO("mp_get MP_GETVER\n");10140status = rtw_mp_getver(dev, info, wdata, extra);10141break;10142case MP_MON:10143RTW_INFO("mp_get MP_MON\n");10144status = rtw_mp_mon(dev, info, wdata, extra);10145break;10146case EFUSE_BT_MASK:10147RTW_INFO("mp_get EFUSE_BT_MASK\n");10148status = rtw_bt_efuse_mask_file(dev, info, wdata, extra);10149break;10150case EFUSE_MASK:10151RTW_INFO("mp_get EFUSE_MASK\n");10152status = rtw_efuse_mask_file(dev, info, wdata, extra);10153break;10154case EFUSE_FILE:10155RTW_INFO("mp_get EFUSE_FILE\n");10156status = rtw_efuse_file_map(dev, info, wdata, extra);10157break;10158case MP_TX:10159RTW_INFO("mp_get MP_TX\n");10160status = rtw_mp_tx(dev, info, wdata, extra);10161break;10162case MP_RX:10163RTW_INFO("mp_get MP_RX\n");10164status = rtw_mp_rx(dev, info, wdata, extra);10165break;10166case MP_HW_TX_MODE:10167RTW_INFO("mp_get MP_HW_TX_MODE\n");10168status = rtw_mp_hwtx(dev, info, wdata, extra);10169break;10170#ifdef CONFIG_RTW_CUSTOMER_STR10171case MP_CUSTOMER_STR:10172RTW_INFO("customer str\n");10173status = rtw_mp_customer_str(dev, info, wdata, extra);10174break;10175#endif10176case MP_PWRLMT:10177RTW_INFO("mp_get MP_SETPWRLMT\n");10178status = rtw_mp_pwrlmt(dev, info, wdata, extra);10179break;10180case MP_PWRBYRATE:10181RTW_INFO("mp_get MP_SETPWRBYRATE\n");10182status = rtw_mp_pwrbyrate(dev, info, wdata, extra);10183break;10184case BT_EFUSE_FILE:10185RTW_INFO("mp_get BT EFUSE_FILE\n");10186status = rtw_bt_efuse_file_map(dev, info, wdata, extra);10187break;10188case MP_SWRFPath:10189RTW_INFO("mp_get MP_SWRFPath\n");10190status = rtw_mp_switch_rf_path(dev, info, wrqu, extra);10191break;10192case MP_LINK:10193RTW_INFO("mp_get MP_LINK\n");10194status = rtw_mp_link(dev, info, wrqu, extra);10195break;10196case MP_DPK_TRK:10197RTW_INFO("mp_get MP_DPK_TRK\n");10198status = rtw_mp_dpk_track(dev, info, wdata, extra);10199break;10200case MP_DPK:10201RTW_INFO("set MP_DPK\n");10202status = rtw_mp_dpk(dev, info, wdata, extra);10203break;10204default:10205status = -EIO;10206}1020710208_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);10209RTW_INFO("%s mutx done_%d\n", __func__, subcmd);1021010211return status;10212}10213#endif /*#if defined(CONFIG_MP_INCLUDED)*/102141021510216#ifdef CONFIG_SDIO_INDIRECT_ACCESS10217#define DBG_MP_SDIO_INDIRECT_ACCESS 110218static int rtw_mp_sd_iread(struct net_device *dev10219, struct iw_request_info *info10220, struct iw_point *wrqu10221, char *extra)10222{10223char input[16];10224u8 width;10225unsigned long addr;10226u32 ret = 0;10227PADAPTER padapter = rtw_netdev_priv(dev);1022810229if (wrqu->length > 16) {10230RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);10231ret = -EINVAL;10232goto exit;10233}1023410235if (copy_from_user(input, wrqu->pointer, wrqu->length)) {10236RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));10237ret = -EFAULT;10238goto exit;10239}1024010241_rtw_memset(extra, 0, wrqu->length);1024210243if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) {10244RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));10245ret = -EINVAL;10246goto exit;10247}1024810249if (addr > 0x3FFF) {10250RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);10251ret = -EINVAL;10252goto exit;10253}1025410255if (DBG_MP_SDIO_INDIRECT_ACCESS)10256RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr);1025710258switch (width) {10259case 1:10260sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr));10261wrqu->length = strlen(extra);10262break;10263case 2:10264sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr));10265wrqu->length = strlen(extra);10266break;10267case 4:10268sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr));10269wrqu->length = strlen(extra);10270break;10271default:10272wrqu->length = 0;10273ret = -EINVAL;10274break;10275}1027610277exit:10278return ret;10279}1028010281static int rtw_mp_sd_iwrite(struct net_device *dev10282, struct iw_request_info *info10283, struct iw_point *wrqu10284, char *extra)10285{10286char width;10287unsigned long addr, data;10288int ret = 0;10289PADAPTER padapter = rtw_netdev_priv(dev);10290char input[32];1029110292if (wrqu->length > 32) {10293RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);10294ret = -EINVAL;10295goto exit;10296}1029710298if (copy_from_user(input, wrqu->pointer, wrqu->length)) {10299RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));10300ret = -EFAULT;10301goto exit;10302}1030310304_rtw_memset(extra, 0, wrqu->length);1030510306if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) {10307RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));10308ret = -EINVAL;10309goto exit;10310}1031110312if (addr > 0x3FFF) {10313RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);10314ret = -EINVAL;10315goto exit;10316}1031710318if (DBG_MP_SDIO_INDIRECT_ACCESS)10319RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data);1032010321switch (width) {10322case 1:10323if (data > 0xFF) {10324ret = -EINVAL;10325break;10326}10327rtw_sd_iwrite8(padapter, addr, data);10328break;10329case 2:10330if (data > 0xFFFF) {10331ret = -EINVAL;10332break;10333}10334rtw_sd_iwrite16(padapter, addr, data);10335break;10336case 4:10337rtw_sd_iwrite32(padapter, addr, data);10338break;10339default:10340wrqu->length = 0;10341ret = -EINVAL;10342break;10343}1034410345exit:10346return ret;10347}10348#endif /* CONFIG_SDIO_INDIRECT_ACCESS */1034910350static int rtw_priv_set(struct net_device *dev,10351struct iw_request_info *info,10352union iwreq_data *wdata, char *extra)10353{10354struct iw_point *wrqu = (struct iw_point *)wdata;10355u32 subcmd = wrqu->flags;10356PADAPTER padapter = rtw_netdev_priv(dev);1035710358if (padapter == NULL)10359return -ENETDOWN;1036010361if (padapter->bup == _FALSE) {10362RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);10363return -ENETDOWN;10364}1036510366if (RTW_CANNOT_RUN(padapter)) {10367RTW_INFO("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__);10368return -ENETDOWN;10369}1037010371if (extra == NULL) {10372wrqu->length = 0;10373return -EIO;10374}1037510376if (subcmd < MP_NULL) {10377#ifdef CONFIG_MP_INCLUDED10378rtw_priv_mp_set(dev, info, wdata, extra);10379#endif10380return 0;10381}1038210383switch (subcmd) {10384#ifdef CONFIG_WOWLAN10385case MP_WOW_ENABLE:10386RTW_INFO("set case MP_WOW_ENABLE: %s\n", extra);1038710388rtw_wowlan_ctrl(dev, info, wdata, extra);10389break;10390case MP_WOW_SET_PATTERN:10391RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra);10392rtw_wowlan_set_pattern(dev, info, wdata, extra);10393break;10394#endif10395#ifdef CONFIG_AP_WOWLAN10396case MP_AP_WOW_ENABLE:10397RTW_INFO("set case MP_AP_WOW_ENABLE: %s\n", extra);10398rtw_ap_wowlan_ctrl(dev, info, wdata, extra);10399break;10400#endif10401#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE10402case VENDOR_IE_SET:10403RTW_INFO("set case VENDOR_IE_SET\n");10404rtw_vendor_ie_set(dev , info , wdata , extra);10405break;10406#endif10407default:10408return -EIO;10409}1041010411return 0;10412}104131041410415static int rtw_priv_get(struct net_device *dev,10416struct iw_request_info *info,10417union iwreq_data *wdata, char *extra)10418{10419struct iw_point *wrqu = (struct iw_point *)wdata;10420u32 subcmd = wrqu->flags;10421PADAPTER padapter = rtw_netdev_priv(dev);104221042310424if (padapter == NULL)10425return -ENETDOWN;1042610427if (padapter->bup == _FALSE) {10428RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);10429return -ENETDOWN;10430}1043110432if (RTW_CANNOT_RUN(padapter)) {10433RTW_INFO("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__);10434return -ENETDOWN;10435}1043610437if (extra == NULL) {10438wrqu->length = 0;10439return -EIO;10440}1044110442if (subcmd < MP_NULL) {10443#ifdef CONFIG_MP_INCLUDED10444rtw_priv_mp_get(dev, info, wdata, extra);10445rtw_msleep_os(10); /* delay 5ms for sending pkt before exit adb shell operation */10446#endif10447} else {10448switch (subcmd) {10449#if defined(CONFIG_RTL8723B)10450case MP_SetBT:10451RTW_INFO("set MP_SetBT\n");10452rtw_mp_SetBT(dev, info, wdata, extra);10453break;10454#endif10455#ifdef CONFIG_SDIO_INDIRECT_ACCESS10456case MP_SD_IREAD:10457rtw_mp_sd_iread(dev, info, wrqu, extra);10458break;10459case MP_SD_IWRITE:10460rtw_mp_sd_iwrite(dev, info, wrqu, extra);10461break;10462#endif10463#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE10464case VENDOR_IE_GET:10465RTW_INFO("get case VENDOR_IE_GET\n");10466rtw_vendor_ie_get(dev , info , wdata , extra);10467break;10468#endif10469default:10470return -EIO;10471}10472}1047310474return 0;10475}104761047710478#ifdef CONFIG_TDLS10479static int rtw_wx_tdls_wfd_enable(struct net_device *dev,10480struct iw_request_info *info,10481union iwreq_data *wrqu, char *extra)10482{10483int ret = 0;1048410485#ifdef CONFIG_WFD1048610487_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1048810489RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1049010491if (extra[0] == '0')10492rtw_tdls_wfd_enable(padapter, 0);10493else10494rtw_tdls_wfd_enable(padapter, 1);1049510496#endif /* CONFIG_WFD */1049710498return ret;10499}1050010501static int rtw_tdls_weaksec(struct net_device *dev,10502struct iw_request_info *info,10503union iwreq_data *wrqu, char *extra)10504{10505int ret = 0;1050610507#ifdef CONFIG_TDLS1050810509u8 i, j;10510_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1051110512RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1051310514if (extra[0] == '0')10515padapter->wdinfo.wfd_tdls_weaksec = 0;10516else10517padapter->wdinfo.wfd_tdls_weaksec = 1;1051810519#endif /* CONFIG_TDLS */1052010521return ret;10522}105231052410525static int rtw_tdls_enable(struct net_device *dev,10526struct iw_request_info *info,10527union iwreq_data *wrqu, char *extra)10528{10529int ret = 0;1053010531#ifdef CONFIG_TDLS10532_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1053310534RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1053510536if (extra[0] == '0')10537rtw_disable_tdls_func(padapter, _TRUE);10538else if (extra[0] == '1')10539rtw_enable_tdls_func(padapter);10540#endif /* CONFIG_TDLS */1054110542return ret;10543}1054410545static int rtw_tdls_setup(struct net_device *dev,10546struct iw_request_info *info,10547union iwreq_data *wrqu, char *extra)10548{10549int ret = 0;10550#ifdef CONFIG_TDLS10551u8 i, j;10552_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10553struct tdls_txmgmt txmgmt;10554#ifdef CONFIG_WFD10555struct wifidirect_info *pwdinfo = &(padapter->wdinfo);10556#endif /* CONFIG_WFD */1055710558RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1055910560if (wrqu->data.length - 1 != 17) {10561RTW_INFO("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length - 1));10562return ret;10563}1056410565_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));10566for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)10567txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));1056810569#ifdef CONFIG_WFD10570if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {10571/* Weak Security situation with AP. */10572if (0 == pwdinfo->wfd_tdls_weaksec) {10573/* Can't send the tdls setup request out!! */10574RTW_INFO("[%s] Current link is not AES, "10575"SKIP sending the tdls setup request!!\n", __FUNCTION__);10576} else10577issue_tdls_setup_req(padapter, &txmgmt, _TRUE);10578} else10579#endif /* CONFIG_WFD */10580{10581issue_tdls_setup_req(padapter, &txmgmt, _TRUE);10582}10583#endif /* CONFIG_TDLS */1058410585return ret;10586}1058710588static int rtw_tdls_teardown(struct net_device *dev,10589struct iw_request_info *info,10590union iwreq_data *wrqu, char *extra)10591{10592int ret = 0;1059310594#ifdef CONFIG_TDLS1059510596u8 i, j;10597_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10598struct sta_info *ptdls_sta = NULL;10599struct tdls_txmgmt txmgmt;1060010601RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1060210603if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) {10604RTW_INFO("[%s] length:%d != 17 or 19\n",10605__FUNCTION__, (wrqu->data.length - 1));10606return ret;10607}1060810609_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));10610for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)10611txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));1061210613ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);1061410615if (ptdls_sta != NULL) {10616txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;10617if (wrqu->data.length - 1 == 19)10618issue_tdls_teardown(padapter, &txmgmt, _FALSE);10619else10620issue_tdls_teardown(padapter, &txmgmt, _TRUE);10621} else10622RTW_INFO("TDLS peer not found\n");10623#endif /* CONFIG_TDLS */1062410625return ret;10626}1062710628static int rtw_tdls_discovery(struct net_device *dev,10629struct iw_request_info *info,10630union iwreq_data *wrqu, char *extra)10631{10632int ret = 0;1063310634#ifdef CONFIG_TDLS1063510636_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10637struct tdls_txmgmt txmgmt;10638int i = 0, j = 0;1063910640RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1064110642_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));10643for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)10644txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));1064510646issue_tdls_dis_req(padapter, &txmgmt);1064710648#endif /* CONFIG_TDLS */1064910650return ret;10651}1065210653static int rtw_tdls_ch_switch(struct net_device *dev,10654struct iw_request_info *info,10655union iwreq_data *wrqu, char *extra)10656{10657int ret = 0;1065810659#ifdef CONFIG_TDLS10660#ifdef CONFIG_TDLS_CH_SW10661_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10662struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;10663u8 i, j;10664struct sta_info *ptdls_sta = NULL;10665u8 take_care_iqk;1066610667RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1066810669if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {10670RTW_INFO("TDLS channel switch is not allowed\n");10671return ret;10672}1067310674for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)10675pchsw_info->addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));1067610677ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr);10678if (ptdls_sta == NULL)10679return ret;1068010681pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE;1068210683if (ptdls_sta != NULL) {10684if (pchsw_info->off_ch_num == 0)10685pchsw_info->off_ch_num = 11;10686} else10687RTW_INFO("TDLS peer not found\n");1068810689rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);1069010691rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);10692if (take_care_iqk == _TRUE) {10693u8 central_chnl;10694u8 bw_mode;1069510696bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;10697central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);10698if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) >= 0)10699rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);10700else10701rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE);10702} else10703rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);1070410705/* issue_tdls_ch_switch_req(padapter, ptdls_sta); */10706/* RTW_INFO("issue tdls ch switch req\n"); */1070710708#endif /* CONFIG_TDLS_CH_SW */10709#endif /* CONFIG_TDLS */1071010711return ret;10712}1071310714static int rtw_tdls_ch_switch_off(struct net_device *dev,10715struct iw_request_info *info,10716union iwreq_data *wrqu, char *extra)10717{10718int ret = 0;1071910720#ifdef CONFIG_TDLS10721#ifdef CONFIG_TDLS_CH_SW1072210723_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10724struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;10725u8 i, j, mac_addr[ETH_ALEN];10726struct sta_info *ptdls_sta = NULL;10727struct tdls_txmgmt txmgmt;1072810729_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));1073010731RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1073210733if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {10734RTW_INFO("TDLS channel switch is not allowed\n");10735return ret;10736}1073710738if (wrqu->data.length >= 17) {10739for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)10740mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));10741ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);10742}1074310744if (ptdls_sta == NULL)10745return ret;1074610747rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);1074810749pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |10750TDLS_CH_SWITCH_ON_STATE |10751TDLS_PEER_AT_OFF_STATE);10752_rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);1075310754ptdls_sta->ch_switch_time = 0;10755ptdls_sta->ch_switch_timeout = 0;10756_cancel_timer_ex(&ptdls_sta->ch_sw_timer);10757_cancel_timer_ex(&ptdls_sta->delay_timer);10758_cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);10759_cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);1076010761rtw_pm_set_lps(padapter, PS_MODE_MAX);10762#endif /* CONFIG_TDLS_CH_SW */10763#endif /* CONFIG_TDLS */1076410765return ret;10766}1076710768static int rtw_tdls_dump_ch(struct net_device *dev,10769struct iw_request_info *info,10770union iwreq_data *wrqu, char *extra)10771{10772int ret = 0;1077310774#ifdef CONFIG_TDLS10775#ifdef CONFIG_TDLS_CH_SW10776_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10777struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;1077810779RTW_INFO("[%s] dump_stack:%s\n", __FUNCTION__, extra);1078010781extra[wrqu->data.length] = 0x00;10782ptdlsinfo->chsw_info.dump_stack = rtw_atoi(extra);1078310784return ret;1078510786#endif10787#endif /* CONFIG_TDLS */1078810789return ret;10790}1079110792static int rtw_tdls_off_ch_num(struct net_device *dev,10793struct iw_request_info *info,10794union iwreq_data *wrqu, char *extra)10795{10796int ret = 0;1079710798#ifdef CONFIG_TDLS10799#ifdef CONFIG_TDLS_CH_SW10800_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10801struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;1080210803RTW_INFO("[%s] off_ch_num:%s\n", __FUNCTION__, extra);1080410805extra[wrqu->data.length] = 0x00;10806ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra);1080710808return ret;1080910810#endif10811#endif /* CONFIG_TDLS */1081210813return ret;10814}1081510816static int rtw_tdls_ch_offset(struct net_device *dev,10817struct iw_request_info *info,10818union iwreq_data *wrqu, char *extra)10819{10820int ret = 0;1082110822#ifdef CONFIG_TDLS10823#ifdef CONFIG_TDLS_CH_SW10824_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10825struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;1082610827RTW_INFO("[%s] ch_offset:%s\n", __FUNCTION__, extra);1082810829extra[wrqu->data.length] = 0x00;10830switch (rtw_atoi(extra)) {10831case SCA:10832ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;10833break;1083410835case SCB:10836ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;10837break;1083810839default:10840ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;10841break;10842}1084310844return ret;1084510846#endif10847#endif /* CONFIG_TDLS */1084810849return ret;10850}1085110852static int rtw_tdls_pson(struct net_device *dev,10853struct iw_request_info *info,10854union iwreq_data *wrqu, char *extra)10855{10856int ret = 0;1085710858#ifdef CONFIG_TDLS1085910860_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10861u8 i, j, mac_addr[ETH_ALEN];10862struct sta_info *ptdls_sta = NULL;1086310864RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1086510866for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)10867mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));1086810869ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);1087010871issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 1, 3, 500);1087210873#endif /* CONFIG_TDLS */1087410875return ret;10876}1087710878static int rtw_tdls_psoff(struct net_device *dev,10879struct iw_request_info *info,10880union iwreq_data *wrqu, char *extra)10881{10882int ret = 0;1088310884#ifdef CONFIG_TDLS1088510886_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10887u8 i, j, mac_addr[ETH_ALEN];10888struct sta_info *ptdls_sta = NULL;1088910890RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1089110892for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)10893mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));1089410895ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);1089610897if (ptdls_sta)10898issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 0, 3, 500);1089910900#endif /* CONFIG_TDLS */1090110902return ret;10903}1090410905static int rtw_tdls_setip(struct net_device *dev,10906struct iw_request_info *info,10907union iwreq_data *wrqu, char *extra)10908{10909int ret = 0;1091010911#ifdef CONFIG_TDLS10912#ifdef CONFIG_WFD1091310914_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10915struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;10916struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;10917u8 i = 0, j = 0, k = 0, tag = 0;1091810919RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);1092010921while (i < 4) {10922for (j = 0; j < 4; j++) {10923if (*(extra + j + tag) == '.' || *(extra + j + tag) == '\0') {10924if (j == 1)10925pwfd_info->ip_address[i] = convert_ip_addr('0', '0', *(extra + (j - 1) + tag));10926if (j == 2)10927pwfd_info->ip_address[i] = convert_ip_addr('0', *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));10928if (j == 3)10929pwfd_info->ip_address[i] = convert_ip_addr(*(extra + (j - 3) + tag), *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));1093010931tag += j + 1;10932break;10933}10934}10935i++;10936}1093710938RTW_INFO("[%s] Set IP = %u.%u.%u.%u\n", __FUNCTION__,10939ptdlsinfo->wfd_info->ip_address[0],10940ptdlsinfo->wfd_info->ip_address[1],10941ptdlsinfo->wfd_info->ip_address[2],10942ptdlsinfo->wfd_info->ip_address[3]);1094310944#endif /* CONFIG_WFD */10945#endif /* CONFIG_TDLS */1094610947return ret;10948}1094910950static int rtw_tdls_getip(struct net_device *dev,10951struct iw_request_info *info,10952union iwreq_data *wrqu, char *extra)10953{10954int ret = 0;1095510956#ifdef CONFIG_TDLS10957#ifdef CONFIG_WFD1095810959_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10960struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;10961struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;1096210963RTW_INFO("[%s]\n", __FUNCTION__);1096410965sprintf(extra, "\n\n%u.%u.%u.%u\n",10966pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],10967pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);1096810969RTW_INFO("[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,10970pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],10971pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);1097210973wrqu->data.length = strlen(extra);1097410975#endif /* CONFIG_WFD */10976#endif /* CONFIG_TDLS */1097710978return ret;10979}1098010981static int rtw_tdls_getport(struct net_device *dev,10982struct iw_request_info *info,10983union iwreq_data *wrqu, char *extra)10984{1098510986int ret = 0;1098710988#ifdef CONFIG_TDLS10989#ifdef CONFIG_WFD1099010991_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);10992struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;10993struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;1099410995RTW_INFO("[%s]\n", __FUNCTION__);1099610997sprintf(extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport);10998RTW_INFO("[%s] remote port = %d\n",10999__FUNCTION__, pwfd_info->peer_rtsp_ctrlport);1100011001wrqu->data.length = strlen(extra);1100211003#endif /* CONFIG_WFD */11004#endif /* CONFIG_TDLS */1100511006return ret;1100711008}1100911010/* WFDTDLS, for sigma test */11011static int rtw_tdls_dis_result(struct net_device *dev,11012struct iw_request_info *info,11013union iwreq_data *wrqu, char *extra)11014{1101511016int ret = 0;1101711018#ifdef CONFIG_TDLS11019#ifdef CONFIG_WFD1102011021_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);11022struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;1102311024RTW_INFO("[%s]\n", __FUNCTION__);1102511026if (ptdlsinfo->dev_discovered == _TRUE) {11027sprintf(extra, "\n\nDis=1\n");11028ptdlsinfo->dev_discovered = _FALSE;11029}1103011031wrqu->data.length = strlen(extra);1103211033#endif /* CONFIG_WFD */11034#endif /* CONFIG_TDLS */1103511036return ret;1103711038}1103911040/* WFDTDLS, for sigma test */11041static int rtw_wfd_tdls_status(struct net_device *dev,11042struct iw_request_info *info,11043union iwreq_data *wrqu, char *extra)11044{1104511046int ret = 0;1104711048#ifdef CONFIG_TDLS1104911050_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);11051struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;1105211053RTW_INFO("[%s]\n", __FUNCTION__);1105411055sprintf(extra, "\nlink_established:%d\n"11056"sta_cnt:%d\n"11057"sta_maximum:%d\n"11058"cur_channel:%d\n"11059"tdls_enable:%d"11060#ifdef CONFIG_TDLS_CH_SW11061"ch_sw_state:%08x\n"11062"chsw_on:%d\n"11063"off_ch_num:%d\n"11064"cur_time:%d\n"11065"ch_offset:%d\n"11066"delay_swtich_back:%d"11067#endif11068,11069ptdlsinfo->link_established, ptdlsinfo->sta_cnt,11070ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel,11071rtw_is_tdls_enabled(padapter)11072#ifdef CONFIG_TDLS_CH_SW11073,11074ptdlsinfo->chsw_info.ch_sw_state,11075ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on),11076ptdlsinfo->chsw_info.off_ch_num,11077ptdlsinfo->chsw_info.cur_time,11078ptdlsinfo->chsw_info.ch_offset,11079ptdlsinfo->chsw_info.delay_switch_back11080#endif11081);1108211083wrqu->data.length = strlen(extra);1108411085#endif /* CONFIG_TDLS */1108611087return ret;1108811089}1109011091static int rtw_tdls_getsta(struct net_device *dev,11092struct iw_request_info *info,11093union iwreq_data *wrqu, char *extra)11094{1109511096int ret = 0;11097#ifdef CONFIG_TDLS11098u8 i, j;11099_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);11100u8 addr[ETH_ALEN] = {0};11101char charmac[17];11102struct sta_info *ptdls_sta = NULL;1110311104RTW_INFO("[%s] %s %d\n", __FUNCTION__,11105(char *)wrqu->data.pointer, wrqu->data.length - 1);1110611107if (copy_from_user(charmac, wrqu->data.pointer + 9, 17)) {11108ret = -EFAULT;11109goto exit;11110}1111111112RTW_INFO("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);11113for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)11114addr[i] = key_2char2num(*(charmac + j), *(charmac + j + 1));1111511116RTW_INFO("[%s] %d, charmac:%s, addr:"MAC_FMT"\n",11117__FUNCTION__, __LINE__, charmac, MAC_ARG(addr));11118ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);11119if (ptdls_sta) {11120sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state);11121RTW_INFO("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);11122} else {11123sprintf(extra, "\n\nNot found this sta\n");11124RTW_INFO("\n\nNot found this sta\n");11125}11126wrqu->data.length = strlen(extra);1112711128exit:11129#endif /* CONFIG_TDLS */11130return ret;1113111132}1113311134static int rtw_tdls_get_best_ch(struct net_device *dev,11135struct iw_request_info *info,11136union iwreq_data *wrqu, char *extra)11137{11138#ifdef CONFIG_FIND_BEST_CHANNEL11139_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);11140struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);11141u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;1114211143for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {11144if (rfctl->channel_set[i].ChannelNum == 1)11145index_24G = i;11146if (rfctl->channel_set[i].ChannelNum == 36)11147index_5G = i;11148}1114911150for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {11151/* 2.4G */11152if (rfctl->channel_set[i].ChannelNum == 6 || rfctl->channel_set[i].ChannelNum == 11) {11153if (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_24G].rx_count) {11154index_24G = i;11155best_channel_24G = rfctl->channel_set[i].ChannelNum;11156}11157}1115811159/* 5G */11160if (rfctl->channel_set[i].ChannelNum >= 3611161&& rfctl->channel_set[i].ChannelNum < 140) {11162/* Find primary channel */11163if (((rfctl->channel_set[i].ChannelNum - 36) % 8 == 0)11164&& (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {11165index_5G = i;11166best_channel_5G = rfctl->channel_set[i].ChannelNum;11167}11168}1116911170if (rfctl->channel_set[i].ChannelNum >= 14911171&& rfctl->channel_set[i].ChannelNum < 165) {11172/* Find primary channel */11173if (((rfctl->channel_set[i].ChannelNum - 149) % 8 == 0)11174&& (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {11175index_5G = i;11176best_channel_5G = rfctl->channel_set[i].ChannelNum;11177}11178}11179#if 1 /* debug */11180RTW_INFO("The rx cnt of channel %3d = %d\n",11181rfctl->channel_set[i].ChannelNum,11182rfctl->channel_set[i].rx_count);11183#endif11184}1118511186sprintf(extra, "\nbest_channel_24G = %d\n", best_channel_24G);11187RTW_INFO("best_channel_24G = %d\n", best_channel_24G);1118811189if (index_5G != 0) {11190sprintf(extra, "best_channel_5G = %d\n", best_channel_5G);11191RTW_INFO("best_channel_5G = %d\n", best_channel_5G);11192}1119311194wrqu->data.length = strlen(extra);1119511196#endif1119711198return 0;1119911200}11201#endif /*#ifdef CONFIG_TDLS*/11202static int rtw_tdls(struct net_device *dev,11203struct iw_request_info *info,11204union iwreq_data *wrqu, char *extra)11205{11206int ret = 0;1120711208#ifdef CONFIG_TDLS1120911210_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);1121111212RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);1121311214if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {11215RTW_INFO("Discard tdls oper since hal doesn't support tdls\n");11216return 0;11217}1121811219if (rtw_is_tdls_enabled(padapter) == _FALSE) {11220RTW_INFO("TDLS is not enabled\n");11221return 0;11222}1122311224/* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */1122511226if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {11227if (_rtw_memcmp(extra, "wfdenable=", 10)) {11228wrqu->data.length -= 10;11229rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]);11230return ret;11231}11232}1123311234if (_rtw_memcmp(extra, "weaksec=", 8)) {11235wrqu->data.length -= 8;11236rtw_tdls_weaksec(dev, info, wrqu, &extra[8]);11237return ret;11238} else if (_rtw_memcmp(extra, "tdlsenable=", 11)) {11239wrqu->data.length -= 11;11240rtw_tdls_enable(dev, info, wrqu, &extra[11]);11241return ret;11242}1124311244if (_rtw_memcmp(extra, "setup=", 6)) {11245wrqu->data.length -= 6;11246rtw_tdls_setup(dev, info, wrqu, &extra[6]);11247} else if (_rtw_memcmp(extra, "tear=", 5)) {11248wrqu->data.length -= 5;11249rtw_tdls_teardown(dev, info, wrqu, &extra[5]);11250} else if (_rtw_memcmp(extra, "dis=", 4)) {11251wrqu->data.length -= 4;11252rtw_tdls_discovery(dev, info, wrqu, &extra[4]);11253} else if (_rtw_memcmp(extra, "swoff=", 6)) {11254wrqu->data.length -= 6;11255rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]);11256} else if (_rtw_memcmp(extra, "sw=", 3)) {11257wrqu->data.length -= 3;11258rtw_tdls_ch_switch(dev, info, wrqu, &extra[3]);11259} else if (_rtw_memcmp(extra, "dumpstack=", 10)) {11260wrqu->data.length -= 10;11261rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]);11262} else if (_rtw_memcmp(extra, "offchnum=", 9)) {11263wrqu->data.length -= 9;11264rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]);11265} else if (_rtw_memcmp(extra, "choffset=", 9)) {11266wrqu->data.length -= 9;11267rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]);11268} else if (_rtw_memcmp(extra, "pson=", 5)) {11269wrqu->data.length -= 5;11270rtw_tdls_pson(dev, info, wrqu, &extra[5]);11271} else if (_rtw_memcmp(extra, "psoff=", 6)) {11272wrqu->data.length -= 6;11273rtw_tdls_psoff(dev, info, wrqu, &extra[6]);11274}1127511276#ifdef CONFIG_WFD11277if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {11278if (_rtw_memcmp(extra, "setip=", 6)) {11279wrqu->data.length -= 6;11280rtw_tdls_setip(dev, info, wrqu, &extra[6]);11281} else if (_rtw_memcmp(extra, "tprobe=", 6))11282issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));11283}11284#endif /* CONFIG_WFD */1128511286#endif /* CONFIG_TDLS */1128711288return ret;11289}112901129111292static int rtw_tdls_get(struct net_device *dev,11293struct iw_request_info *info,11294union iwreq_data *wrqu, char *extra)11295{11296int ret = 0;1129711298#ifdef CONFIG_TDLS1129911300RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);1130111302if (_rtw_memcmp(wrqu->data.pointer, "ip", 2))11303rtw_tdls_getip(dev, info, wrqu, extra);11304else if (_rtw_memcmp(wrqu->data.pointer, "port", 4))11305rtw_tdls_getport(dev, info, wrqu, extra);11306/* WFDTDLS, for sigma test */11307else if (_rtw_memcmp(wrqu->data.pointer, "dis", 3))11308rtw_tdls_dis_result(dev, info, wrqu, extra);11309else if (_rtw_memcmp(wrqu->data.pointer, "status", 6))11310rtw_wfd_tdls_status(dev, info, wrqu, extra);11311else if (_rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9))11312rtw_tdls_getsta(dev, info, wrqu, extra);11313else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7))11314rtw_tdls_get_best_ch(dev, info, wrqu, extra);11315#endif /* CONFIG_TDLS */1131611317return ret;11318}1131911320#ifdef CONFIG_MAC_LOOPBACK_DRIVER1132111322#if defined(CONFIG_RTL8188E)11323#include <rtl8188e_hal.h>11324extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);11325#define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum11326#ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)11327extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);11328#define fill_default_txdesc rtl8188es_fill_default_txdesc11329#endif /* CONFIG_SDIO_HCI */11330#endif /* CONFIG_RTL8188E */11331#if defined(CONFIG_RTL8723B)11332extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);11333#define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum11334extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);11335#define fill_default_txdesc rtl8723b_fill_default_txdesc11336#endif /* CONFIG_RTL8723B */1133711338#if defined(CONFIG_RTL8703B)11339/* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */11340#define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum11341/* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */11342#define fill_default_txdesc rtl8703b_fill_default_txdesc11343#endif /* CONFIG_RTL8703B */1134411345#if defined(CONFIG_RTL8723D)11346/* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */11347#define cal_txdesc_chksum rtl8723d_cal_txdesc_chksum11348/* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */11349#define fill_default_txdesc rtl8723d_fill_default_txdesc11350#endif /* CONFIG_RTL8723D */1135111352#if defined(CONFIG_RTL8710B)11353#define cal_txdesc_chksum rtl8710b_cal_txdesc_chksum11354#define fill_default_txdesc rtl8710b_fill_default_txdesc11355#endif /* CONFIG_RTL8710B */1135611357#if defined(CONFIG_RTL8192E)11358extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc);11359#define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum11360#ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)11361extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);11362#define fill_default_txdesc rtl8192es_fill_default_txdesc11363#endif /* CONFIG_SDIO_HCI */11364#endif /* CONFIG_RTL8192E */1136511366#if defined(CONFIG_RTL8192F)11367/* extern void rtl8192f_cal_txdesc_chksum(struct tx_desc *ptxdesc); */11368#define cal_txdesc_chksum rtl8192f_cal_txdesc_chksum11369/* extern void rtl8192f_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */11370#define fill_default_txdesc rtl8192f_fill_default_txdesc11371#endif /* CONFIG_RTL8192F */1137211373static s32 initLoopback(PADAPTER padapter)11374{11375PLOOPBACKDATA ploopback;113761137711378if (padapter->ploopback == NULL) {11379ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));11380if (ploopback == NULL)11381return -ENOMEM;1138211383_rtw_init_sema(&ploopback->sema, 0);11384ploopback->bstop = _TRUE;11385ploopback->cnt = 0;11386ploopback->size = 300;11387_rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));1138811389padapter->ploopback = ploopback;11390}1139111392return 0;11393}1139411395static void freeLoopback(PADAPTER padapter)11396{11397PLOOPBACKDATA ploopback;113981139911400ploopback = padapter->ploopback;11401if (ploopback) {11402rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA));11403padapter->ploopback = NULL;11404}11405}1140611407static s32 initpseudoadhoc(PADAPTER padapter)11408{11409NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;11410s32 err;1141111412networkType = Ndis802_11IBSS;11413err = rtw_set_802_11_infrastructure_mode(padapter, networkType, 0);11414if (err == _FALSE)11415return _FAIL;1141611417err = rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);11418if (err == _FAIL)11419return _FAIL;1142011421return _SUCCESS;11422}1142311424static s32 createpseudoadhoc(PADAPTER padapter)11425{11426NDIS_802_11_AUTHENTICATION_MODE authmode;11427struct mlme_priv *pmlmepriv;11428NDIS_802_11_SSID *passoc_ssid;11429WLAN_BSSID_EX *pdev_network;11430u8 *pibss;11431u8 ssid[] = "pseduo_ad-hoc";11432s32 err;11433_irqL irqL;114341143511436pmlmepriv = &padapter->mlmepriv;1143711438authmode = Ndis802_11AuthModeOpen;11439err = rtw_set_802_11_authentication_mode(padapter, authmode);11440if (err == _FALSE)11441return _FAIL;1144211443passoc_ssid = &pmlmepriv->assoc_ssid;11444_rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));11445passoc_ssid->SsidLength = sizeof(ssid) - 1;11446_rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);1144711448pdev_network = &padapter->registrypriv.dev_network;11449pibss = padapter->registrypriv.dev_network.MacAddress;11450_rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));1145111452rtw_update_registrypriv_dev_network(padapter);11453rtw_generate_random_ibss(pibss);1145411455_enter_critical_bh(&pmlmepriv->lock, &irqL);11456/*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/11457init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);1145811459_exit_critical_bh(&pmlmepriv->lock, &irqL);1146011461#if 011462err = rtw_create_ibss_cmd(padapter, 0);11463if (err == _FAIL)11464return _FAIL;11465#else11466{11467struct wlan_network *pcur_network;11468struct sta_info *psta;1146911470/* 3 create a new psta */11471pcur_network = &pmlmepriv->cur_network;1147211473/* clear psta in the cur_network, if any */11474psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);11475if (psta)11476rtw_free_stainfo(padapter, psta);1147711478psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);11479if (psta == NULL)11480return _FAIL;1148111482/* 3 join psudo AdHoc */11483pcur_network->join_res = 1;11484pcur_network->aid = psta->cmn.aid = 1;11485_rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));1148611487/* set msr to WIFI_FW_ADHOC_STATE */11488padapter->hw_port = HW_PORT0;11489Set_MSR(padapter, WIFI_FW_ADHOC_STATE);1149011491}11492#endif1149311494return _SUCCESS;11495}1149611497static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size)11498{11499struct xmit_priv *pxmitpriv;11500struct xmit_frame *pframe;11501struct xmit_buf *pxmitbuf;11502struct pkt_attrib *pattrib;11503struct tx_desc *desc;11504u8 *pkt_start, *pkt_end, *ptr;11505struct rtw_ieee80211_hdr *hdr;11506s32 bmcast;11507_irqL irqL;115081150911510if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ)11511return NULL;1151211513pxmitpriv = &padapter->xmitpriv;11514pframe = NULL;1151511516/* 2 1. allocate xmit frame */11517pframe = rtw_alloc_xmitframe(pxmitpriv);11518if (pframe == NULL)11519return NULL;11520pframe->padapter = padapter;1152111522/* 2 2. allocate xmit buffer */11523_enter_critical_bh(&pxmitpriv->lock, &irqL);11524pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);11525_exit_critical_bh(&pxmitpriv->lock, &irqL);11526if (pxmitbuf == NULL) {11527rtw_free_xmitframe(pxmitpriv, pframe);11528return NULL;11529}1153011531pframe->pxmitbuf = pxmitbuf;11532pframe->buf_addr = pxmitbuf->pbuf;11533pxmitbuf->priv_data = pframe;1153411535/* 2 3. update_attrib() */11536pattrib = &pframe->attrib;1153711538/* init xmitframe attribute */11539_rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));1154011541pattrib->ether_type = 0x8723;11542_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);11543_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);11544_rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);11545_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);1154611547/* pattrib->dhcp_pkt = 0;11548* pattrib->pktlen = 0; */11549pattrib->ack_policy = 0;11550/* pattrib->pkt_hdrlen = ETH_HLEN; */11551pattrib->hdrlen = WLAN_HDR_A3_LEN;11552pattrib->subtype = WIFI_DATA;11553pattrib->priority = 0;11554pattrib->qsel = pattrib->priority;11555/* do_queue_select(padapter, pattrib); */11556pattrib->nr_frags = 1;11557pattrib->encrypt = 0;11558pattrib->bswenc = _FALSE;11559pattrib->qos_en = _FALSE;1156011561bmcast = IS_MCAST(pattrib->ra);11562if (bmcast)11563pattrib->psta = rtw_get_bcmc_stainfo(padapter);11564else11565pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));1156611567pattrib->mac_id = pattrib->psta->cmn.mac_id;11568pattrib->pktlen = size;11569pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;1157011571/* 2 4. fill TX descriptor */11572desc = (struct tx_desc *)pframe->buf_addr;11573_rtw_memset(desc, 0, TXDESC_SIZE);1157411575fill_default_txdesc(pframe, (u8 *)desc);1157611577/* Hw set sequence number */11578((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable11579* ((PTXDESC)desc)->hwseq_sel = 0; */ /* HWSEQ_SEL */1158011581((PTXDESC)desc)->disdatafb = 1;1158211583/* convert to little endian */11584desc->txdw0 = cpu_to_le32(desc->txdw0);11585desc->txdw1 = cpu_to_le32(desc->txdw1);11586desc->txdw2 = cpu_to_le32(desc->txdw2);11587desc->txdw3 = cpu_to_le32(desc->txdw3);11588desc->txdw4 = cpu_to_le32(desc->txdw4);11589desc->txdw5 = cpu_to_le32(desc->txdw5);11590desc->txdw6 = cpu_to_le32(desc->txdw6);11591desc->txdw7 = cpu_to_le32(desc->txdw7);11592#ifdef CONFIG_PCI_HCI11593desc->txdw8 = cpu_to_le32(desc->txdw8);11594desc->txdw9 = cpu_to_le32(desc->txdw9);11595desc->txdw10 = cpu_to_le32(desc->txdw10);11596desc->txdw11 = cpu_to_le32(desc->txdw11);11597desc->txdw12 = cpu_to_le32(desc->txdw12);11598desc->txdw13 = cpu_to_le32(desc->txdw13);11599desc->txdw14 = cpu_to_le32(desc->txdw14);11600desc->txdw15 = cpu_to_le32(desc->txdw15);11601#endif1160211603cal_txdesc_chksum(desc);1160411605/* 2 5. coalesce */11606pkt_start = pframe->buf_addr + TXDESC_SIZE;11607pkt_end = pkt_start + pattrib->last_txcmdsz;1160811609/* 3 5.1. make wlan header, make_wlanhdr() */11610hdr = (struct rtw_ieee80211_hdr *)pkt_start;11611set_frame_sub_type(&hdr->frame_ctl, pattrib->subtype);11612_rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */11613_rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */11614_rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */1161511616/* 3 5.2. make payload */11617ptr = pkt_start + pattrib->hdrlen;11618get_random_bytes(ptr, pkt_end - ptr);1161911620pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;11621pxmitbuf->ptail += pxmitbuf->len;1162211623return pframe;11624}1162511626static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)11627{11628struct xmit_priv *pxmitpriv;11629struct xmit_buf *pxmitbuf;116301163111632pxmitpriv = &padapter->xmitpriv;11633pxmitbuf = pframe->pxmitbuf;1163411635rtw_free_xmitframe(pxmitpriv, pframe);11636rtw_free_xmitbuf(pxmitpriv, pxmitbuf);11637}1163811639static void printdata(u8 *pbuf, u32 len)11640{11641u32 i, val;116421164311644for (i = 0; (i + 4) <= len; i += 4) {11645printk("%08X", *(u32 *)(pbuf + i));11646if ((i + 4) & 0x1F)11647printk(" ");11648else11649printk("\n");11650}1165111652if (i < len) {11653#ifdef CONFIG_BIG_ENDIAN11654for (; i < len, i++)11655printk("%02X", pbuf + i);11656#else /* CONFIG_LITTLE_ENDIAN */11657#if 011658val = 0;11659_rtw_memcpy(&val, pbuf + i, len - i);11660printk("%8X", val);11661#else11662u8 str[9];11663u8 n;11664val = 0;11665n = len - i;11666_rtw_memcpy(&val, pbuf + i, n);11667sprintf(str, "%08X", val);11668n = (4 - n) * 2;11669printk("%8s", str + n);11670#endif11671#endif /* CONFIG_LITTLE_ENDIAN */11672}11673printk("\n");11674}1167511676static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)11677{11678PHAL_DATA_TYPE phal;11679struct recv_stat *prxstat;11680struct recv_stat report;11681PRXREPORT prxreport;11682u32 drvinfosize;11683u32 rxpktsize;11684u8 fcssize;11685u8 ret = _FALSE;1168611687prxstat = (struct recv_stat *)rxbuf;11688report.rxdw0 = le32_to_cpu(prxstat->rxdw0);11689report.rxdw1 = le32_to_cpu(prxstat->rxdw1);11690report.rxdw2 = le32_to_cpu(prxstat->rxdw2);11691report.rxdw3 = le32_to_cpu(prxstat->rxdw3);11692report.rxdw4 = le32_to_cpu(prxstat->rxdw4);11693report.rxdw5 = le32_to_cpu(prxstat->rxdw5);1169411695prxreport = (PRXREPORT)&report;11696drvinfosize = prxreport->drvinfosize << 3;11697rxpktsize = prxreport->pktlen;1169811699phal = GET_HAL_DATA(padapter);11700if (rtw_hal_rcr_check(padapter, RCR_APPFCS))11701fcssize = IEEE80211_FCS_LEN;11702else11703fcssize = 0;1170411705if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {11706RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n",11707__func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);11708ret = _FALSE;11709} else {11710ret = _rtw_memcmp(txbuf + TXDESC_SIZE, \11711rxbuf + RXDESC_SIZE + drvinfosize, \11712txsz - TXDESC_SIZE);11713if (ret == _FALSE)11714RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__);11715}1171611717if (ret == _FALSE) {11718RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n",11719__func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);11720RTW_INFO("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);11721printdata(txbuf, TXDESC_SIZE);11722RTW_INFO("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);11723printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);1172411725RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",11726__func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);11727if (rxpktsize != 0) {11728RTW_INFO("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);11729printdata(rxbuf, RXDESC_SIZE);11730RTW_INFO("%s: RX drvinfo size=%d\n", __func__, drvinfosize);11731printdata(rxbuf + RXDESC_SIZE, drvinfosize);11732RTW_INFO("%s: RX content size=%d\n", __func__, rxpktsize);11733printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);11734} else {11735RTW_INFO("%s: RX data size=%d\n", __func__, rxsz);11736printdata(rxbuf, rxsz);11737}11738}1173911740return ret;11741}1174211743thread_return lbk_thread(thread_context context)11744{11745s32 err;11746PADAPTER padapter;11747PLOOPBACKDATA ploopback;11748struct xmit_frame *pxmitframe;11749u32 cnt, ok, fail, headerlen;11750u32 pktsize;11751u32 ff_hwaddr;117521175311754padapter = (PADAPTER)context;11755ploopback = padapter->ploopback;11756if (ploopback == NULL)11757return -1;11758cnt = 0;11759ok = 0;11760fail = 0;1176111762daemonize("%s", "RTW_LBK_THREAD");11763allow_signal(SIGTERM);1176411765do {11766if (ploopback->size == 0) {11767get_random_bytes(&pktsize, 4);11768pktsize = (pktsize % 1535) + 1; /* 1~1535 */11769} else11770pktsize = ploopback->size;1177111772pxmitframe = createloopbackpkt(padapter, pktsize);11773if (pxmitframe == NULL) {11774sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");11775break;11776}1177711778ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;11779_rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);11780ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);11781cnt++;11782RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);11783pxmitframe->pxmitbuf->pdata = ploopback->txbuf;11784rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);1178511786/* wait for rx pkt */11787_rtw_down_sema(&ploopback->sema);1178811789err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);11790if (err == _TRUE)11791ok++;11792else11793fail++;1179411795ploopback->txsize = 0;11796_rtw_memset(ploopback->txbuf, 0, 0x8000);11797ploopback->rxsize = 0;11798_rtw_memset(ploopback->rxbuf, 0, 0x8000);1179911800freeloopbackpkt(padapter, pxmitframe);11801pxmitframe = NULL;1180211803flush_signals_thread();1180411805if ((ploopback->bstop == _TRUE) ||11806((ploopback->cnt != 0) && (ploopback->cnt == cnt))) {11807u32 ok_rate, fail_rate, all;11808all = cnt;11809ok_rate = (ok * 100) / all;11810fail_rate = (fail * 100) / all;11811sprintf(ploopback->msg, \11812"loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)", \11813ok_rate, ok, all, fail_rate, fail, all);11814break;11815}11816} while (1);1181711818ploopback->bstop = _TRUE;1181911820thread_exit(NULL);11821return 0;11822}1182311824static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg)11825{11826PLOOPBACKDATA ploopback;11827u32 len;11828s32 err;118291183011831ploopback = padapter->ploopback;1183211833if (ploopback) {11834if (ploopback->bstop == _FALSE) {11835ploopback->bstop = _TRUE;11836_rtw_up_sema(&ploopback->sema);11837}11838len = 0;11839do {11840len = strlen(ploopback->msg);11841if (len)11842break;11843rtw_msleep_os(1);11844} while (1);11845_rtw_memcpy(pmsg, ploopback->msg, len + 1);11846freeLoopback(padapter);1184711848return;11849}1185011851/* disable dynamic algorithm */11852rtw_phydm_ability_backup(padapter);11853rtw_phydm_func_disable_all(padapter);1185411855/* create pseudo ad-hoc connection */11856err = initpseudoadhoc(padapter);11857if (err == _FAIL) {11858sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");11859return;11860}1186111862err = createpseudoadhoc(padapter);11863if (err == _FAIL) {11864sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");11865return;11866}1186711868err = initLoopback(padapter);11869if (err) {11870sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);11871return;11872}1187311874ploopback = padapter->ploopback;1187511876ploopback->bstop = _FALSE;11877ploopback->cnt = cnt;11878ploopback->size = size;11879ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");11880if (IS_ERR(padapter->lbkthread)) {11881freeLoopback(padapter);11882ploopback->lbkthread = NULL;11883sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);11884return;11885}1188611887sprintf(pmsg, "loopback start! cnt=%d", cnt);11888}11889#endif /* CONFIG_MAC_LOOPBACK_DRIVER */1189011891static int rtw_test(11892struct net_device *dev,11893struct iw_request_info *info,11894union iwreq_data *wrqu, char *extra)11895{11896u32 len;11897u8 *pbuf, *pch;11898char *ptmp;11899u8 *delim = ",";11900PADAPTER padapter = rtw_netdev_priv(dev);119011190211903RTW_INFO("+%s\n", __func__);11904len = wrqu->data.length;1190511906pbuf = (u8 *)rtw_zmalloc(len + 1);11907if (pbuf == NULL) {11908RTW_INFO("%s: no memory!\n", __func__);11909return -ENOMEM;11910}1191111912if (copy_from_user(pbuf, wrqu->data.pointer, len)) {11913rtw_mfree(pbuf, len + 1);11914RTW_INFO("%s: copy from user fail!\n", __func__);11915return -EFAULT;11916}1191711918pbuf[len] = '\0';1191911920RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);1192111922ptmp = (char *)pbuf;11923pch = strsep(&ptmp, delim);11924if ((pch == NULL) || (strlen(pch) == 0)) {11925rtw_mfree(pbuf, len);11926RTW_INFO("%s: parameter error(level 1)!\n", __func__);11927return -EFAULT;11928}1192911930#ifdef CONFIG_MAC_LOOPBACK_DRIVER11931if (strcmp(pch, "loopback") == 0) {11932s32 cnt = 0;11933u32 size = 64;1193411935pch = strsep(&ptmp, delim);11936if ((pch == NULL) || (strlen(pch) == 0)) {11937rtw_mfree(pbuf, len);11938RTW_INFO("%s: parameter error(level 2)!\n", __func__);11939return -EFAULT;11940}1194111942sscanf(pch, "%d", &cnt);11943RTW_INFO("%s: loopback cnt=%d\n", __func__, cnt);1194411945pch = strsep(&ptmp, delim);11946if ((pch == NULL) || (strlen(pch) == 0)) {11947rtw_mfree(pbuf, len);11948RTW_INFO("%s: parameter error(level 2)!\n", __func__);11949return -EFAULT;11950}1195111952sscanf(pch, "%d", &size);11953RTW_INFO("%s: loopback size=%d\n", __func__, size);1195411955loopbackTest(padapter, cnt, size, extra);11956wrqu->data.length = strlen(extra) + 1;1195711958goto free_buf;11959}11960#endif119611196211963#ifdef CONFIG_BT_COEXIST11964if (strcmp(pch, "bton") == 0) {11965rtw_btcoex_SetManualControl(padapter, _FALSE);11966goto free_buf;11967} else if (strcmp(pch, "btoff") == 0) {11968rtw_btcoex_SetManualControl(padapter, _TRUE);11969goto free_buf;11970}11971#endif1197211973if (strcmp(pch, "h2c") == 0) {11974u8 param[8];11975u8 count = 0;11976u32 tmp;11977u8 i;11978u32 pos;11979u8 ret;1198011981do {11982pch = strsep(&ptmp, delim);11983if ((pch == NULL) || (strlen(pch) == 0))11984break;1198511986sscanf(pch, "%x", &tmp);11987param[count++] = (u8)tmp;11988} while (count < 8);1198911990if (count == 0) {11991rtw_mfree(pbuf, len);11992RTW_INFO("%s: parameter error(level 2)!\n", __func__);11993return -EFAULT;11994}1199511996ret = rtw_test_h2c_cmd(padapter, param, count);1199711998pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);11999for (i = 1; i < count; i++)12000pos += sprintf(extra + pos, "%02x,", param[i]);12001extra[pos] = 0;12002pos--;12003pos += sprintf(extra + pos, " %s", ret == _FAIL ? "FAIL" : "OK");1200412005wrqu->data.length = strlen(extra) + 1;1200612007goto free_buf;12008}1200912010free_buf:12011rtw_mfree(pbuf, len);12012return 0;12013}1201412015static iw_handler rtw_handlers[] = {12016NULL, /* SIOCSIWCOMMIT */12017rtw_wx_get_name, /* SIOCGIWNAME */12018dummy, /* SIOCSIWNWID */12019dummy, /* SIOCGIWNWID */12020rtw_wx_set_freq, /* SIOCSIWFREQ */12021rtw_wx_get_freq, /* SIOCGIWFREQ */12022rtw_wx_set_mode, /* SIOCSIWMODE */12023rtw_wx_get_mode, /* SIOCGIWMODE */12024dummy, /* SIOCSIWSENS */12025rtw_wx_get_sens, /* SIOCGIWSENS */12026NULL, /* SIOCSIWRANGE */12027rtw_wx_get_range, /* SIOCGIWRANGE */12028rtw_wx_set_priv, /* SIOCSIWPRIV */12029NULL, /* SIOCGIWPRIV */12030NULL, /* SIOCSIWSTATS */12031NULL, /* SIOCGIWSTATS */12032dummy, /* SIOCSIWSPY */12033dummy, /* SIOCGIWSPY */12034NULL, /* SIOCGIWTHRSPY */12035NULL, /* SIOCWIWTHRSPY */12036rtw_wx_set_wap, /* SIOCSIWAP */12037rtw_wx_get_wap, /* SIOCGIWAP */12038rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */12039dummy, /* SIOCGIWAPLIST -- depricated */12040rtw_wx_set_scan, /* SIOCSIWSCAN */12041rtw_wx_get_scan, /* SIOCGIWSCAN */12042rtw_wx_set_essid, /* SIOCSIWESSID */12043rtw_wx_get_essid, /* SIOCGIWESSID */12044dummy, /* SIOCSIWNICKN */12045rtw_wx_get_nick, /* SIOCGIWNICKN */12046NULL, /* -- hole -- */12047NULL, /* -- hole -- */12048rtw_wx_set_rate, /* SIOCSIWRATE */12049rtw_wx_get_rate, /* SIOCGIWRATE */12050rtw_wx_set_rts, /* SIOCSIWRTS */12051rtw_wx_get_rts, /* SIOCGIWRTS */12052rtw_wx_set_frag, /* SIOCSIWFRAG */12053rtw_wx_get_frag, /* SIOCGIWFRAG */12054dummy, /* SIOCSIWTXPOW */12055dummy, /* SIOCGIWTXPOW */12056dummy, /* SIOCSIWRETRY */12057rtw_wx_get_retry, /* SIOCGIWRETRY */12058rtw_wx_set_enc, /* SIOCSIWENCODE */12059rtw_wx_get_enc, /* SIOCGIWENCODE */12060dummy, /* SIOCSIWPOWER */12061rtw_wx_get_power, /* SIOCGIWPOWER */12062NULL, /*---hole---*/12063NULL, /*---hole---*/12064rtw_wx_set_gen_ie, /* SIOCSIWGENIE */12065NULL, /* SIOCGWGENIE */12066rtw_wx_set_auth, /* SIOCSIWAUTH */12067NULL, /* SIOCGIWAUTH */12068rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */12069NULL, /* SIOCGIWENCODEEXT */12070rtw_wx_set_pmkid, /* SIOCSIWPMKSA */12071NULL, /*---hole---*/12072};120731207412075static const struct iw_priv_args rtw_private_args[] = {12076{12077SIOCIWFIRSTPRIV + 0x0,12078IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"12079},12080{12081SIOCIWFIRSTPRIV + 0x1,12082IW_PRIV_TYPE_CHAR | 0x7FF,12083IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"12084},12085{12086SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"12087},12088{12089SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"12090},12091{12092SIOCIWFIRSTPRIV + 0x4,12093IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"12094},12095{12096SIOCIWFIRSTPRIV + 0x5,12097IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"12098},12099{12100SIOCIWFIRSTPRIV + 0x6,12101IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"12102},12103/* for PLATFORM_MT53XX */12104{12105SIOCIWFIRSTPRIV + 0x7,12106IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"12107},12108{12109SIOCIWFIRSTPRIV + 0x8,12110IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"12111},12112{12113SIOCIWFIRSTPRIV + 0x9,12114IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"12115},1211612117/* for RTK_DMP_PLATFORM */12118{12119SIOCIWFIRSTPRIV + 0xA,12120IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"12121},1212212123{12124SIOCIWFIRSTPRIV + 0xB,12125IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"12126},12127{12128SIOCIWFIRSTPRIV + 0xC,12129IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"12130},12131{12132SIOCIWFIRSTPRIV + 0xD,12133IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"12134},12135#if 012136{12137SIOCIWFIRSTPRIV + 0xE, 0, 0, "wowlan_ctrl"12138},12139#endif12140{12141SIOCIWFIRSTPRIV + 0x10,12142IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"12143},12144{12145SIOCIWFIRSTPRIV + 0x11,12146IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"12147},12148{12149SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"12150},12151{12152SIOCIWFIRSTPRIV + 0x13,12153IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"12154},12155{12156SIOCIWFIRSTPRIV + 0x14,12157IW_PRIV_TYPE_CHAR | 64, 0, "tdls"12158},12159{12160SIOCIWFIRSTPRIV + 0x15,12161IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"12162},12163{12164SIOCIWFIRSTPRIV + 0x16,12165IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"12166},12167#ifdef CONFIG_RTW_80211K12168{12169SIOCIWFIRSTPRIV + 0x17,12170IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "rrm"12171},12172#else12173{SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 1024 , 0 , "NULL"},12174#endif12175{SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},12176#ifdef CONFIG_MP_INCLUDED12177{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},12178{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},12179#else12180{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},12181{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},12182#endif12183{12184SIOCIWFIRSTPRIV + 0x1D,12185IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"12186},1218712188{ SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, /* set */12189{ SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},/* get12190* --- sub-ioctls definitions --- */1219112192#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE12193{ VENDOR_IE_SET, IW_PRIV_TYPE_CHAR | 1024 , 0 , "vendor_ie_set" },12194{ VENDOR_IE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "vendor_ie_get" },12195#endif12196#if defined(CONFIG_RTL8723B)12197{ MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },12198{ MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},12199#endif12200#ifdef CONFIG_WOWLAN12201{ MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },12202{ MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },12203#endif12204#ifdef CONFIG_AP_WOWLAN12205{ MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */12206#endif12207#ifdef CONFIG_SDIO_INDIRECT_ACCESS12208{ MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },12209{ MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },12210#endif12211};122121221312214static const struct iw_priv_args rtw_mp_private_args[] = {12215/* --- sub-ioctls definitions --- */12216#ifdef CONFIG_MP_INCLUDED12217{ MP_START , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_start" },12218{ MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },12219{ MP_STOP , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_stop" },12220{ MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },12221{ MP_CHL_OFFSET , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ch_offset" },12222{ MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_bandwidth"},12223{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },12224{ MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_reset_stats"},12225{ MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"},12226{ READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },12227{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },12228{ READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },12229{ MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},12230{ MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },12231{ MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},12232{ MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},12233{ MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},12234{ WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },12235{ WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },12236{ MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},12237{ MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},12238{ MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},12239{ EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },12240{ EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },12241{ MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrtrk"},12242{ MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },12243{ MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},12244{ MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setrfpath" },12245{ MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },12246{ MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },12247{ MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },12248{ MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },12249{ EFUSE_BT_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_bt_mask" },12250{ EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },12251{ EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },12252{ MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },12253{ MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },12254{ MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },12255{ MP_PWRLMT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrlmt" },12256{ MP_PWRBYRATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrbyrate" },12257{ CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},12258{ MP_IQK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_iqk"},12259{ MP_LCK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_lck"},12260{ BT_EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bt_efuse_file" },12261{ MP_SWRFPath, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_swrfpath" },12262{ MP_LINK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_link" },12263{ MP_DPK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk"},12264{ MP_DPK_TRK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk_trk" },12265#ifdef CONFIG_RTW_CUSTOMER_STR12266{ MP_CUSTOMER_STR, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "customer_str" },12267#endif1226812269#endif /* CONFIG_MP_INCLUDED */12270};1227112272static iw_handler rtw_private_handler[] = {12273rtw_wx_write32, /* 0x00 */12274rtw_wx_read32, /* 0x01 */12275NULL, /* 0x02 */12276#ifdef MP_IOCTL_HDL12277rtw_mp_ioctl_hdl, /* 0x03 */12278#else12279rtw_wx_priv_null,12280#endif12281/* for MM DTV platform */12282rtw_get_ap_info, /* 0x04 */1228312284rtw_set_pid, /* 0x05 */12285rtw_wps_start, /* 0x06 */1228612287/* for PLATFORM_MT53XX */12288rtw_wx_get_sensitivity, /* 0x07 */12289rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */12290rtw_wx_set_mtk_wps_ie, /* 0x09 */1229112292/* for RTK_DMP_PLATFORM12293* Set Channel depend on the country code */12294rtw_wx_set_channel_plan, /* 0x0A */1229512296rtw_dbg_port, /* 0x0B */12297rtw_wx_write_rf, /* 0x0C */12298rtw_wx_read_rf, /* 0x0D */1229912300rtw_priv_set, /*0x0E*/12301rtw_priv_get, /*0x0F*/1230212303rtw_p2p_set, /* 0x10 */12304rtw_p2p_get, /* 0x11 */12305NULL, /* 0x12 */12306rtw_p2p_get2, /* 0x13 */1230712308rtw_tdls, /* 0x14 */12309rtw_tdls_get, /* 0x15 */1231012311rtw_pm_set, /* 0x16 */12312#ifdef CONFIG_RTW_80211K12313rtw_wx_priv_rrm, /* 0x17 */12314#else12315rtw_wx_priv_null, /* 0x17 */12316#endif12317rtw_rereg_nd_name, /* 0x18 */12318rtw_wx_priv_null, /* 0x19 */12319#ifdef CONFIG_MP_INCLUDED12320rtw_wx_priv_null, /* 0x1A */12321rtw_wx_priv_null, /* 0x1B */12322#else12323rtw_wx_priv_null, /* 0x1A */12324rtw_mp_efuse_get, /* 0x1B */12325#endif12326NULL, /* 0x1C is reserved for hostapd */12327rtw_test, /* 0x1D */12328};1232912330#if WIRELESS_EXT >= 1712331static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)12332{12333_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);12334struct iw_statistics *piwstats = &padapter->iwstats;12335int tmp_level = 0;12336int tmp_qual = 0;12337int tmp_noise = 0;1233812339if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE) {12340piwstats->qual.qual = 0;12341piwstats->qual.level = 0;12342piwstats->qual.noise = 0;12343/* RTW_INFO("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */12344} else {12345#ifdef CONFIG_SIGNAL_DISPLAY_DBM12346tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);12347#else12348tmp_level = padapter->recvpriv.signal_strength;12349#endif1235012351tmp_qual = padapter->recvpriv.signal_qual;12352#ifdef CONFIG_BACKGROUND_NOISE_MONITOR12353if (IS_NM_ENABLE(padapter)) {12354tmp_noise = rtw_noise_measure_curchan(padapter);12355#ifndef CONFIG_SIGNAL_DISPLAY_DBM12356tmp_noise = translate_dbm_to_percentage(tmp_noise);/*percentage*/12357#endif12358}12359#endif12360/* RTW_INFO("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); */1236112362piwstats->qual.level = tmp_level;12363piwstats->qual.qual = tmp_qual;12364piwstats->qual.noise = tmp_noise;12365}12366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14))12367piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* |IW_QUAL_DBM; */12368#else12369#ifdef RTK_DMP_PLATFORM12370/* IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. */12371/* remove this flag for show percentage 0~100 */12372piwstats->qual.updated = 0x07;12373#else12374piwstats->qual.updated = 0x0f;12375#endif12376#endif1237712378#ifdef CONFIG_SIGNAL_DISPLAY_DBM12379piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;12380#endif1238112382return &padapter->iwstats;12383}12384#endif1238512386#ifdef CONFIG_WIRELESS_EXT12387struct iw_handler_def rtw_handlers_def =12388{12389.standard = rtw_handlers,12390.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),12391#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) || defined(CONFIG_WEXT_PRIV)12392.private = rtw_private_handler,12393.private_args = (struct iw_priv_args *)rtw_private_args,12394.num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),12395.num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),12396#endif12397#if WIRELESS_EXT >= 1712398.get_wireless_stats = rtw_get_wireless_stats,12399#endif12400};12401#endif1240212403/* copy from net/wireless/wext.c start12404* ----------------------------------------------------------------12405*12406* Calculate size of private arguments12407*/12408static const char iw_priv_type_size[] = {124090, /* IW_PRIV_TYPE_NONE */124101, /* IW_PRIV_TYPE_BYTE */124111, /* IW_PRIV_TYPE_CHAR */124120, /* Not defined */12413sizeof(__u32), /* IW_PRIV_TYPE_INT */12414sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */12415sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */124160, /* Not defined */12417};1241812419static int get_priv_size(__u16 args)12420{12421int num = args & IW_PRIV_SIZE_MASK;12422int type = (args & IW_PRIV_TYPE_MASK) >> 12;1242312424return num * iw_priv_type_size[type];12425}12426/* copy from net/wireless/wext.c end */124271242812429static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)12430{12431int err = 0;12432u8 *input = NULL;12433u32 input_len = 0;12434const char delim[] = " ";12435u8 *output = NULL;12436u32 output_len = 0;12437u32 count = 0;12438u8 *buffer = NULL;12439u32 buffer_len = 0;12440char *ptr = NULL;12441u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */12442u32 cmdlen;12443s32 len;12444u8 *extra = NULL;12445u32 extra_size = 0;1244612447s32 k;12448const iw_handler *priv; /* Private ioctl */12449const struct iw_priv_args *priv_args; /* Private ioctl description */12450const struct iw_priv_args *mp_priv_args; /*MP Private ioctl description */12451const struct iw_priv_args *sel_priv_args; /*Selected Private ioctl description */12452u32 num_priv; /* Number of ioctl */12453u32 num_priv_args; /* Number of descriptions */12454u32 num_mp_priv_args; /*Number of MP descriptions */12455u32 num_sel_priv_args; /*Number of Selected descriptions */12456iw_handler handler;12457int temp;12458int subcmd = 0; /* sub-ioctl index */12459int offset = 0; /* Space for sub-ioctl index */1246012461union iwreq_data wdata;1246212463_rtw_memcpy(&wdata, wrq_data, sizeof(wdata));1246412465input_len = wdata.data.length;12466if (!input_len)12467return -EINVAL;12468input = rtw_zmalloc(input_len);1246912470if (input == NULL) {12471err = -EOPNOTSUPP;12472goto exit;12473}1247412475if (copy_from_user(input, wdata.data.pointer, input_len)) {12476err = -EFAULT;12477goto exit;12478}12479input[input_len - 1] = '\0';12480ptr = input;12481len = input_len;1248212483sscanf(ptr, "%16s", cmdname);12484cmdlen = strlen(cmdname);12485RTW_DBG("%s: cmd=%s\n", __func__, cmdname);1248612487/* skip command string */12488if (cmdlen > 0)12489cmdlen += 1; /* skip one space */12490ptr += cmdlen;12491len -= cmdlen;12492RTW_DBG("%s: parameters=%s\n", __func__, ptr);1249312494priv = rtw_private_handler;12495priv_args = rtw_private_args;12496mp_priv_args = rtw_mp_private_args;12497num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);12498num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);12499num_mp_priv_args = sizeof(rtw_mp_private_args) / sizeof(struct iw_priv_args);1250012501if (num_priv_args == 0) {12502err = -EOPNOTSUPP;12503goto exit;12504}1250512506/* Search the correct ioctl */12507k = -1;12508sel_priv_args = priv_args;12509num_sel_priv_args = num_priv_args;12510while12511((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))12512;1251312514/* If not found... */12515if (k == num_sel_priv_args) {12516k = -1;12517sel_priv_args = mp_priv_args;12518num_sel_priv_args = num_mp_priv_args;12519while12520((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))12521;1252212523if (k == num_sel_priv_args) {12524err = -EOPNOTSUPP;12525goto exit;12526}12527}1252812529/* Watch out for sub-ioctls ! */12530if (sel_priv_args[k].cmd < SIOCDEVPRIVATE) {12531int j = -1;1253212533/* Find the matching *real* ioctl */12534while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||12535(priv_args[j].set_args != sel_priv_args[k].set_args) ||12536(priv_args[j].get_args != sel_priv_args[k].get_args)))12537;1253812539/* If not found... */12540if (j == num_priv_args) {12541err = -EINVAL;12542goto exit;12543}1254412545/* Save sub-ioctl number */12546subcmd = sel_priv_args[k].cmd;12547/* Reserve one int (simplify alignment issues) */12548offset = sizeof(__u32);12549/* Use real ioctl definition from now on */12550k = j;12551}1255212553buffer = rtw_zmalloc(4096);12554if (NULL == buffer) {12555err = -ENOMEM;12556goto exit;12557}1255812559if (k >= num_priv_args) {12560err = -EINVAL;12561goto exit;12562}1256312564/* If we have to set some data */12565if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&12566(priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {12567u8 *str;1256812569switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {12570case IW_PRIV_TYPE_BYTE:12571/* Fetch args */12572count = 0;12573do {12574str = strsep(&ptr, delim);12575if (NULL == str)12576break;12577sscanf(str, "%i", &temp);12578buffer[count++] = (u8)temp;12579} while (1);12580buffer_len = count;1258112582/* Number of args to fetch */12583wdata.data.length = count;12584if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))12585wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;1258612587break;1258812589case IW_PRIV_TYPE_INT:12590/* Fetch args */12591count = 0;12592do {12593str = strsep(&ptr, delim);12594if (NULL == str)12595break;12596sscanf(str, "%i", &temp);12597((s32 *)buffer)[count++] = (s32)temp;12598} while (1);12599buffer_len = count * sizeof(s32);1260012601/* Number of args to fetch */12602wdata.data.length = count;12603if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))12604wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;1260512606break;1260712608case IW_PRIV_TYPE_CHAR:12609if (len > 0) {12610/* Size of the string to fetch */12611wdata.data.length = len;12612if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))12613wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;1261412615/* Fetch string */12616_rtw_memcpy(buffer, ptr, wdata.data.length);12617} else {12618wdata.data.length = 1;12619buffer[0] = '\0';12620}12621buffer_len = wdata.data.length;12622break;1262312624default:12625RTW_INFO("%s: Not yet implemented...\n", __func__);12626err = -1;12627goto exit;12628}1262912630if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&12631(wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {12632RTW_INFO("%s: The command %s needs exactly %d argument(s)...\n",12633__func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);12634err = -EINVAL;12635goto exit;12636}12637} /* if args to set */12638else12639wdata.data.length = 0L;1264012641/* Those two tests are important. They define how the driver12642* will have to handle the data */12643if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&12644((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {12645/* First case : all SET args fit within wrq */12646if (offset)12647wdata.mode = subcmd;12648_rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);12649} else {12650if ((priv_args[k].set_args == 0) &&12651(priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&12652(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {12653/* Second case : no SET args, GET args fit within wrq */12654if (offset)12655wdata.mode = subcmd;12656} else {12657/* Third case : args won't fit in wrq, or variable number of args */12658if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {12659err = -EFAULT;12660goto exit;12661}12662wdata.data.flags = subcmd;12663}12664}1266512666rtw_mfree(input, input_len);12667input = NULL;1266812669extra_size = 0;12670if (IW_IS_SET(priv_args[k].cmd)) {12671/* Size of set arguments */12672extra_size = get_priv_size(priv_args[k].set_args);1267312674/* Does it fits in iwr ? */12675if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&12676((extra_size + offset) <= IFNAMSIZ))12677extra_size = 0;12678} else {12679/* Size of get arguments */12680extra_size = get_priv_size(priv_args[k].get_args);1268112682/* Does it fits in iwr ? */12683if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&12684(extra_size <= IFNAMSIZ))12685extra_size = 0;12686}1268712688if (extra_size == 0) {12689extra = (u8 *)&wdata;12690rtw_mfree(buffer, 4096);12691buffer = NULL;12692} else12693extra = buffer;1269412695handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];12696err = handler(dev, NULL, &wdata, extra);1269712698/* If we have to get some data */12699if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&12700(priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {12701int j;12702int n = 0; /* number of args */12703u8 str[20] = {0};1270412705/* Check where is the returned data */12706if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&12707(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))12708n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;12709else12710n = wdata.data.length;1271112712output = rtw_zmalloc(4096);12713if (NULL == output) {12714err = -ENOMEM;12715goto exit;12716}1271712718switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {12719case IW_PRIV_TYPE_BYTE:12720/* Display args */12721for (j = 0; j < n; j++) {12722sprintf(str, "%d ", extra[j]);12723len = strlen(str);12724output_len = strlen(output);12725if ((output_len + len + 1) > 4096) {12726err = -E2BIG;12727goto exit;12728}12729_rtw_memcpy(output + output_len, str, len);12730}12731break;1273212733case IW_PRIV_TYPE_INT:12734/* Display args */12735for (j = 0; j < n; j++) {12736sprintf(str, "%d ", ((__s32 *)extra)[j]);12737len = strlen(str);12738output_len = strlen(output);12739if ((output_len + len + 1) > 4096) {12740err = -E2BIG;12741goto exit;12742}12743_rtw_memcpy(output + output_len, str, len);12744}12745break;1274612747case IW_PRIV_TYPE_CHAR:12748/* Display args */12749_rtw_memcpy(output, extra, n);12750break;1275112752default:12753RTW_INFO("%s: Not yet implemented...\n", __func__);12754err = -1;12755goto exit;12756}1275712758output_len = strlen(output) + 1;12759wrq_data->data.length = output_len;12760if (copy_to_user(wrq_data->data.pointer, output, output_len)) {12761err = -EFAULT;12762goto exit;12763}12764} /* if args to set */12765else12766wrq_data->data.length = 0;1276712768exit:12769if (input)12770rtw_mfree(input, input_len);12771if (buffer)12772rtw_mfree(buffer, 4096);12773if (output)12774rtw_mfree(output, 4096);1277512776return err;12777}1277812779#ifdef CONFIG_COMPAT12780static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)12781{12782struct compat_iw_point iwp_compat;12783union iwreq_data wrq_data;12784int err = 0;12785RTW_DBG("%s:...\n", __func__);12786if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))12787return -EFAULT;1278812789wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);12790wrq_data.data.length = iwp_compat.length;12791wrq_data.data.flags = iwp_compat.flags;1279212793err = _rtw_ioctl_wext_private(dev, &wrq_data);1279412795iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);12796iwp_compat.length = wrq_data.data.length;12797iwp_compat.flags = wrq_data.data.flags;12798if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))12799return -EFAULT;1280012801return err;12802}12803#endif /* CONFIG_COMPAT */1280412805static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)12806{12807struct iw_point *iwp;12808union iwreq_data wrq_data;12809int err = 0;12810iwp = &wrq_data.data;12811RTW_DBG("%s:...\n", __func__);12812if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))12813return -EFAULT;1281412815err = _rtw_ioctl_wext_private(dev, &wrq_data);1281612817if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))12818return -EFAULT;1281912820return err;12821}1282212823static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq)12824{12825#ifdef CONFIG_COMPAT12826#if (KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE)12827if (is_compat_task())12828#else12829if (in_compat_syscall())12830#endif12831return rtw_ioctl_compat_wext_private(dev, rq);12832else12833#endif /* CONFIG_COMPAT */12834return rtw_ioctl_standard_wext_private(dev, rq);12835}1283612837int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)12838{12839struct iwreq *wrq = (struct iwreq *)rq;12840int ret = 0;1284112842switch (cmd) {12843case RTL_IOCTL_WPA_SUPPLICANT:12844ret = wpa_supplicant_ioctl(dev, &wrq->u.data);12845break;12846#ifdef CONFIG_AP_MODE12847case RTL_IOCTL_HOSTAPD:12848ret = rtw_hostapd_ioctl(dev, &wrq->u.data);12849break;12850#ifdef CONFIG_WIRELESS_EXT12851case SIOCSIWMODE:12852ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);12853break;12854#endif12855#endif /* CONFIG_AP_MODE */12856case SIOCDEVPRIVATE:12857ret = rtw_ioctl_wext_private(dev, rq);12858break;12859case (SIOCDEVPRIVATE+1):12860ret = rtw_android_priv_cmd(dev, rq, cmd);12861break;12862default:12863ret = -EOPNOTSUPP;12864break;12865}1286612867return ret;12868}128691287012871