Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/rtw_android.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*****************************************************************************/1415#ifdef CONFIG_GPIO_WAKEUP16#include <linux/gpio.h>17#endif1819#include <drv_types.h>2021#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)22#include <linux/platform_device.h>23#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))24#include <linux/wlan_plat.h>25#else26#include <linux/wifi_tiwlan.h>27#endif28#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */2930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))31#define strnicmp strncasecmp32#endif /* Linux kernel >= 4.0.0 */3334#ifdef CONFIG_GPIO_WAKEUP35#include <linux/interrupt.h>36#include <linux/irq.h>37#endif3839#include "rtw_version.h"4041extern void macstr2num(u8 *dst, u8 *src);4243const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = {44"START",45"STOP",46"SCAN-ACTIVE",47"SCAN-PASSIVE",48"RSSI",49"LINKSPEED",50"RXFILTER-START",51"RXFILTER-STOP",52"RXFILTER-ADD",53"RXFILTER-REMOVE",54"BTCOEXSCAN-START",55"BTCOEXSCAN-STOP",56"BTCOEXMODE",57"SETSUSPENDMODE",58"SETSUSPENDOPT",59"P2P_DEV_ADDR",60"SETFWPATH",61"SETBAND",62"GETBAND",63"COUNTRY",64"P2P_SET_NOA",65"P2P_GET_NOA",66"P2P_SET_PS",67"SET_AP_WPS_P2P_IE",6869"MIRACAST",7071#ifdef CONFIG_PNO_SUPPORT72"PNOSSIDCLR",73"PNOSETUP",74"PNOFORCE",75"PNODEBUG",76#endif7778"MACADDR",7980"BLOCK_SCAN",81"BLOCK",82"WFD-ENABLE",83"WFD-DISABLE",84"WFD-SET-TCPPORT",85"WFD-SET-MAXTPUT",86"WFD-SET-DEVTYPE",87"SET_DTIM",88"HOSTAPD_SET_MACADDR_ACL",89"HOSTAPD_ACL_ADD_STA",90"HOSTAPD_ACL_REMOVE_STA",91#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0))92"GTK_REKEY_OFFLOAD",93#endif /* CONFIG_GTK_OL */94/* Private command for P2P disable*/95"P2P_DISABLE",96"SET_AEK",97"EXT_AUTH_STATUS",98"DRIVER_VERSION"99};100101#ifdef CONFIG_PNO_SUPPORT102#define PNO_TLV_PREFIX 'S'103#define PNO_TLV_VERSION '1'104#define PNO_TLV_SUBVERSION '2'105#define PNO_TLV_RESERVED '0'106#define PNO_TLV_TYPE_SSID_IE 'S'107#define PNO_TLV_TYPE_TIME 'T'108#define PNO_TLV_FREQ_REPEAT 'R'109#define PNO_TLV_FREQ_EXPO_MAX 'M'110111typedef struct cmd_tlv {112char prefix;113char version;114char subver;115char reserved;116} cmd_tlv_t;117118#ifdef CONFIG_PNO_SET_DEBUG119char pno_in_example[] = {120'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',121'S', '1', '2', '0',122'S', /* 1 */1230x05,124'd', 'l', 'i', 'n', 'k',125'S', /* 2 */1260x06,127'B', 'U', 'F', 'B', 'U', 'F',128'S', /* 3 */1290x20,130'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '@', '#', '$', '%', '^',131'S', /* 4 */1320x0a,133'!', '@', '#', '$', '%', '^', '&', '*', '(', ')',134'T',135'0', '5',136'R',137'2',138'M',139'2',1400x00141};142#endif /* CONFIG_PNO_SET_DEBUG */143#endif /* PNO_SUPPORT */144145typedef struct android_wifi_priv_cmd {146char *buf;147int used_len;148int total_len;149} android_wifi_priv_cmd;150151#ifdef CONFIG_COMPAT152typedef struct compat_android_wifi_priv_cmd {153compat_uptr_t buf;154int used_len;155int total_len;156} compat_android_wifi_priv_cmd;157#endif /* CONFIG_COMPAT */158159/**160* Local (static) functions and variables161*/162163/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first164* time (only) in dhd_open, subsequential wifi on will be handled by165* wl_android_wifi_on166*/167static int g_wifi_on = _TRUE;168169unsigned int oob_irq = 0;170unsigned int oob_gpio = 0;171172#ifdef CONFIG_PNO_SUPPORT173/*174* rtw_android_pno_setup175* Description:176* This is used for private command.177*178* Parameter:179* net: net_device180* command: parameters from private command181* total_len: the length of the command.182*183* */184static int rtw_android_pno_setup(struct net_device *net, char *command, int total_len)185{186pno_ssid_t pno_ssids_local[MAX_PNO_LIST_COUNT];187int res = -1;188int nssid = 0;189cmd_tlv_t *cmd_tlv_temp;190char *str_ptr;191int tlv_size_left;192int pno_time = 0;193int pno_repeat = 0;194int pno_freq_expo_max = 0;195int cmdlen = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_PNOSETUP_SET]) + 1;196197#ifdef CONFIG_PNO_SET_DEBUG198int i;199char *p;200p = pno_in_example;201202total_len = sizeof(pno_in_example);203str_ptr = p + cmdlen;204#else205str_ptr = command + cmdlen;206#endif207208if (total_len < (cmdlen + sizeof(cmd_tlv_t))) {209RTW_INFO("%s argument=%d less min size\n", __func__, total_len);210goto exit_proc;211}212213tlv_size_left = total_len - cmdlen;214215cmd_tlv_temp = (cmd_tlv_t *)str_ptr;216memset(pno_ssids_local, 0, sizeof(pno_ssids_local));217218if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&219(cmd_tlv_temp->version == PNO_TLV_VERSION) &&220(cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) {221222str_ptr += sizeof(cmd_tlv_t);223tlv_size_left -= sizeof(cmd_tlv_t);224225nssid = rtw_parse_ssid_list_tlv(&str_ptr, pno_ssids_local,226MAX_PNO_LIST_COUNT, &tlv_size_left);227if (nssid <= 0) {228RTW_INFO("SSID is not presented or corrupted ret=%d\n", nssid);229goto exit_proc;230} else {231if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {232RTW_INFO("%s scan duration corrupted field size %d\n",233__func__, tlv_size_left);234goto exit_proc;235}236str_ptr++;237pno_time = simple_strtoul(str_ptr, &str_ptr, 16);238RTW_INFO("%s: pno_time=%d\n", __func__, pno_time);239240if (str_ptr[0] != 0) {241if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {242RTW_INFO("%s pno repeat : corrupted field\n",243__func__);244goto exit_proc;245}246str_ptr++;247pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);248RTW_INFO("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat);249if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {250RTW_INFO("%s FREQ_EXPO_MAX corrupted field size\n",251__func__);252goto exit_proc;253}254str_ptr++;255pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);256RTW_INFO("%s: pno_freq_expo_max=%d\n",257__func__, pno_freq_expo_max);258}259}260} else {261RTW_INFO("%s get wrong TLV command\n", __FUNCTION__);262goto exit_proc;263}264265res = rtw_dev_pno_set(net, pno_ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max);266267#ifdef CONFIG_PNO_SET_DEBUG268rtw_dev_pno_debug(net);269#endif270271exit_proc:272return res;273}274275/*276* rtw_android_cfg80211_pno_setup277* Description:278* This is used for cfg80211 sched_scan.279*280* Parameter:281* net: net_device282* request: cfg80211_request283* */284285int rtw_android_cfg80211_pno_setup(struct net_device *net,286struct cfg80211_ssid *ssids, int n_ssids, int interval)287{288int res = -1;289int nssid = 0;290int pno_time = 0;291int pno_repeat = 0;292int pno_freq_expo_max = 0;293int index = 0;294pno_ssid_t pno_ssids_local[MAX_PNO_LIST_COUNT];295296if (n_ssids > MAX_PNO_LIST_COUNT || n_ssids < 0) {297RTW_INFO("%s: nssids(%d) is invalid.\n", __func__, n_ssids);298return -EINVAL;299}300301memset(pno_ssids_local, 0, sizeof(pno_ssids_local));302303nssid = n_ssids;304305for (index = 0 ; index < nssid ; index++) {306pno_ssids_local[index].SSID_len = ssids[index].ssid_len;307memcpy(pno_ssids_local[index].SSID, ssids[index].ssid,308ssids[index].ssid_len);309}310#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)311if(ssids)312rtw_mfree((u8 *)ssids, (n_ssids * sizeof(struct cfg80211_ssid)));313#endif314pno_time = (interval / 1000);315316RTW_INFO("%s: nssids: %d, pno_time=%d\n", __func__, nssid, pno_time);317318res = rtw_dev_pno_set(net, pno_ssids_local, nssid, pno_time,319pno_repeat, pno_freq_expo_max);320321#ifdef CONFIG_PNO_SET_DEBUG322rtw_dev_pno_debug(net);323#endif324exit_proc:325return res;326}327328int rtw_android_pno_enable(struct net_device *net, int pno_enable)329{330_adapter *padapter = (_adapter *)rtw_netdev_priv(net);331struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);332333if (pwrctl) {334pwrctl->wowlan_pno_enable = pno_enable;335RTW_INFO("%s: wowlan_pno_enable: %d\n", __func__, pwrctl->wowlan_pno_enable);336if (pwrctl->wowlan_pno_enable == 0) {337if (pwrctl->pnlo_info != NULL) {338rtw_mfree((u8 *)pwrctl->pnlo_info, sizeof(pno_nlo_info_t));339pwrctl->pnlo_info = NULL;340}341if (pwrctl->pno_ssid_list != NULL) {342rtw_mfree((u8 *)pwrctl->pno_ssid_list, sizeof(pno_ssid_list_t));343pwrctl->pno_ssid_list = NULL;344}345if (pwrctl->pscan_info != NULL) {346rtw_mfree((u8 *)pwrctl->pscan_info, sizeof(pno_scan_info_t));347pwrctl->pscan_info = NULL;348}349}350return 0;351} else352return -1;353}354#endif /* CONFIG_PNO_SUPPORT */355356int rtw_android_cmdstr_to_num(char *cmdstr)357{358int cmd_num;359for (cmd_num = 0 ; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++)360if (0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num])))361break;362363return cmd_num;364}365366int rtw_android_get_rssi(struct net_device *net, char *command, int total_len)367{368_adapter *padapter = (_adapter *)rtw_netdev_priv(net);369struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);370struct wlan_network *pcur_network = &pmlmepriv->cur_network;371int bytes_written = 0;372373if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {374bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d",375pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);376}377378return bytes_written;379}380381int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len)382{383_adapter *padapter = (_adapter *)rtw_netdev_priv(net);384int bytes_written = 0;385u16 link_speed = 0;386387link_speed = rtw_get_cur_max_rate(padapter) / 10;388bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);389390return bytes_written;391}392393int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len)394{395int bytes_written = 0;396397bytes_written = snprintf(command, total_len, "Macaddr = "MAC_FMT, MAC_ARG(net->dev_addr));398return bytes_written;399}400401int rtw_android_set_country(struct net_device *net, char *command, int total_len)402{403_adapter *adapter = (_adapter *)rtw_netdev_priv(net);404char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1;405int ret = _FAIL;406407ret = rtw_set_country(adapter, country_code);408409return (ret == _SUCCESS) ? 0 : -1;410}411412int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len)413{414int bytes_written = 0;415416/* We use the same address as our HW MAC address */417_rtw_memcpy(command, net->dev_addr, ETH_ALEN);418419bytes_written = ETH_ALEN;420return bytes_written;421}422423int rtw_android_set_block_scan(struct net_device *net, char *command, int total_len)424{425_adapter *adapter = (_adapter *)rtw_netdev_priv(net);426char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK_SCAN]) + 1;427428#ifdef CONFIG_IOCTL_CFG80211429adapter_wdev_data(adapter)->block_scan = (*block_value == '0') ? _FALSE : _TRUE;430#endif431432return 0;433}434435int rtw_android_set_block(struct net_device *net, char *command, int total_len)436{437_adapter *adapter = (_adapter *)rtw_netdev_priv(net);438char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK]) + 1;439440#ifdef CONFIG_IOCTL_CFG80211441adapter_wdev_data(adapter)->block = (*block_value == '0') ? _FALSE : _TRUE;442#endif443444return 0;445}446447int rtw_android_setband(struct net_device *net, char *command, int total_len)448{449_adapter *adapter = (_adapter *)rtw_netdev_priv(net);450char *arg = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SETBAND]) + 1;451u32 band = WIFI_FREQUENCY_BAND_AUTO;452int ret = _FAIL;453454if (sscanf(arg, "%u", &band) >= 1)455ret = rtw_set_band(adapter, band);456457return (ret == _SUCCESS) ? 0 : -1;458}459460int rtw_android_getband(struct net_device *net, char *command, int total_len)461{462_adapter *adapter = (_adapter *)rtw_netdev_priv(net);463int bytes_written = 0;464465bytes_written = snprintf(command, total_len, "%u", adapter->setband);466467return bytes_written;468}469470#ifdef CONFIG_WFD471int rtw_android_set_miracast_mode(struct net_device *net, char *command, int total_len)472{473_adapter *adapter = (_adapter *)rtw_netdev_priv(net);474struct wifi_display_info *wfd_info = &adapter->wfd_info;475char *arg = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_MIRACAST]) + 1;476u8 mode;477int num;478int ret = _FAIL;479480num = sscanf(arg, "%hhu", &mode);481482if (num < 1)483goto exit;484485switch (mode) {486case 1: /* soruce */487mode = MIRACAST_SOURCE;488break;489case 2: /* sink */490mode = MIRACAST_SINK;491break;492case 0: /* disabled */493default:494mode = MIRACAST_DISABLED;495break;496}497wfd_info->stack_wfd_mode = mode;498RTW_INFO("stack miracast mode: %s\n", get_miracast_mode_str(wfd_info->stack_wfd_mode));499500ret = _SUCCESS;501502exit:503return (ret == _SUCCESS) ? 0 : -1;504}505#endif /* CONFIG_WFD */506507int get_int_from_command(char *pcmd)508{509int i = 0;510511for (i = 0; i < strlen(pcmd); i++) {512if (pcmd[i] == '=') {513/* Skip the '=' and space characters. */514i += 2;515break;516}517}518return rtw_atoi(pcmd + i) ;519}520521#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0))522int rtw_gtk_offload(struct net_device *net, u8 *cmd_ptr)523{524int i;525/* u8 *cmd_ptr = priv_cmd.buf; */526struct sta_info *psta;527_adapter *padapter = (_adapter *)rtw_netdev_priv(net);528struct mlme_priv *pmlmepriv = &padapter->mlmepriv;529struct sta_priv *pstapriv = &padapter->stapriv;530struct security_priv *psecuritypriv = &(padapter->securitypriv);531psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));532533534if (psta == NULL)535RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);536else {537/* string command length of "GTK_REKEY_OFFLOAD" */538cmd_ptr += 18;539540_rtw_memcpy(psta->kek, cmd_ptr, RTW_KEK_LEN);541cmd_ptr += RTW_KEK_LEN;542/*543printk("supplicant KEK: ");544for(i=0;i<RTW_KEK_LEN; i++)545printk(" %02x ", psta->kek[i]);546printk("\n supplicant KCK: ");547*/548_rtw_memcpy(psta->kck, cmd_ptr, RTW_KCK_LEN);549cmd_ptr += RTW_KCK_LEN;550/*551for(i=0;i<RTW_KEK_LEN; i++)552printk(" %02x ", psta->kck[i]);553*/554_rtw_memcpy(psta->replay_ctr, cmd_ptr, RTW_REPLAY_CTR_LEN);555psecuritypriv->binstallKCK_KEK = _TRUE;556557/* printk("\nREPLAY_CTR: "); */558/* for(i=0;i<RTW_REPLAY_CTR_LEN; i++) */559/* printk(" %02x ", psta->replay_ctr[i]); */560}561562return _SUCCESS;563}564#endif /* CONFIG_GTK_OL */565566#ifdef CONFIG_RTW_MESH_AEK567static int rtw_android_set_aek(struct net_device *ndev, char *command, int total_len)568{569#define SET_AEK_DATA_LEN (ETH_ALEN + 32)570571_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);572u8 *addr;573u8 *aek;574int err = 0;575576if (total_len - strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AEK]) - 1 != SET_AEK_DATA_LEN) {577err = -EINVAL;578goto exit;579}580581addr = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AEK]) + 1;582aek = addr + ETH_ALEN;583584RTW_PRINT(FUNC_NDEV_FMT" addr="MAC_FMT"\n"585, FUNC_NDEV_ARG(ndev), MAC_ARG(addr));586if (0)587RTW_PRINT(FUNC_NDEV_FMT" aek="KEY_FMT KEY_FMT"\n"588, FUNC_NDEV_ARG(ndev), KEY_ARG(aek), KEY_ARG(aek + 16));589590if (rtw_mesh_plink_set_aek(adapter, addr, aek) != _SUCCESS)591err = -ENOENT;592593exit:594return err;595}596#endif /* CONFIG_RTW_MESH_AEK */597598int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)599{600#define PRIVATE_COMMAND_MAX_LEN 8192601int ret = 0;602char *command = NULL;603int cmd_num;604int bytes_written = 0;605#ifdef CONFIG_PNO_SUPPORT606uint cmdlen = 0;607uint pno_enable = 0;608#endif609android_wifi_priv_cmd priv_cmd;610_adapter *padapter = (_adapter *) rtw_netdev_priv(net);611#ifdef CONFIG_WFD612struct wifi_display_info *pwfd_info;613#endif614615rtw_lock_suspend();616617if (!ifr->ifr_data) {618ret = -EINVAL;619goto exit;620}621if (padapter->registrypriv.mp_mode == 1) {622ret = -EINVAL;623goto exit;624}625#ifdef CONFIG_COMPAT626#if (KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE)627if (is_compat_task()) {628#else629if (in_compat_syscall()) {630#endif631/* User space is 32-bit, use compat ioctl */632compat_android_wifi_priv_cmd compat_priv_cmd;633634if (copy_from_user(&compat_priv_cmd, ifr->ifr_data, sizeof(compat_android_wifi_priv_cmd))) {635ret = -EFAULT;636goto exit;637}638priv_cmd.buf = compat_ptr(compat_priv_cmd.buf);639priv_cmd.used_len = compat_priv_cmd.used_len;640priv_cmd.total_len = compat_priv_cmd.total_len;641} else642#endif /* CONFIG_COMPAT */643if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {644ret = -EFAULT;645goto exit;646}647if (padapter->registrypriv.mp_mode == 1) {648ret = -EFAULT;649goto exit;650}651/*RTW_INFO("%s priv_cmd.buf=%p priv_cmd.total_len=%d priv_cmd.used_len=%d\n",__func__,priv_cmd.buf,priv_cmd.total_len,priv_cmd.used_len);*/652if (priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN || priv_cmd.total_len < 0) {653RTW_WARN("%s: invalid private command (%d)\n", __FUNCTION__,654priv_cmd.total_len);655ret = -EFAULT;656goto exit;657}658659command = rtw_zmalloc(priv_cmd.total_len+1);660if (!command) {661RTW_INFO("%s: failed to allocate memory\n", __FUNCTION__);662ret = -ENOMEM;663goto exit;664}665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))666if (!access_ok(priv_cmd.buf, priv_cmd.total_len)) {667#else668if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) {669#endif670RTW_INFO("%s: failed to access memory\n", __FUNCTION__);671ret = -EFAULT;672goto exit;673}674if (copy_from_user(command, (void *)priv_cmd.buf, priv_cmd.total_len)) {675ret = -EFAULT;676goto exit;677}678command[priv_cmd.total_len] = '\0';679RTW_INFO("%s: Android private cmd \"%s\" on %s\n"680, __FUNCTION__, command, ifr->ifr_name);681682cmd_num = rtw_android_cmdstr_to_num(command);683684switch (cmd_num) {685case ANDROID_WIFI_CMD_START:686/* bytes_written = wl_android_wifi_on(net); */687goto response;688case ANDROID_WIFI_CMD_SETFWPATH:689goto response;690}691692if (!g_wifi_on) {693RTW_INFO("%s: Ignore private cmd \"%s\" - iface %s is down\n"694, __FUNCTION__, command, ifr->ifr_name);695ret = 0;696goto exit;697}698699if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {700switch (cmd_num) {701case ANDROID_WIFI_CMD_WFD_ENABLE:702case ANDROID_WIFI_CMD_WFD_DISABLE:703case ANDROID_WIFI_CMD_WFD_SET_TCPPORT:704case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT:705case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE:706goto response;707}708}709710switch (cmd_num) {711712case ANDROID_WIFI_CMD_STOP:713/* bytes_written = wl_android_wifi_off(net); */714break;715716case ANDROID_WIFI_CMD_SCAN_ACTIVE:717/* rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_ACTIVE); */718#ifdef CONFIG_PLATFORM_MSTAR719#ifdef CONFIG_IOCTL_CFG80211720adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->bandroid_scan = _TRUE;721#endif /* CONFIG_IOCTL_CFG80211 */722#endif /* CONFIG_PLATFORM_MSTAR */723break;724case ANDROID_WIFI_CMD_SCAN_PASSIVE:725/* rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_PASSIVE); */726break;727728case ANDROID_WIFI_CMD_RSSI:729bytes_written = rtw_android_get_rssi(net, command, priv_cmd.total_len);730break;731case ANDROID_WIFI_CMD_LINKSPEED:732bytes_written = rtw_android_get_link_speed(net, command, priv_cmd.total_len);733break;734735case ANDROID_WIFI_CMD_MACADDR:736bytes_written = rtw_android_get_macaddr(net, command, priv_cmd.total_len);737break;738739case ANDROID_WIFI_CMD_BLOCK_SCAN:740bytes_written = rtw_android_set_block_scan(net, command, priv_cmd.total_len);741break;742743case ANDROID_WIFI_CMD_BLOCK:744bytes_written = rtw_android_set_block(net, command, priv_cmd.total_len);745break;746747case ANDROID_WIFI_CMD_RXFILTER_START:748/* bytes_written = net_os_set_packet_filter(net, 1); */749break;750case ANDROID_WIFI_CMD_RXFILTER_STOP:751/* bytes_written = net_os_set_packet_filter(net, 0); */752break;753case ANDROID_WIFI_CMD_RXFILTER_ADD:754/* int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; */755/* bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); */756break;757case ANDROID_WIFI_CMD_RXFILTER_REMOVE:758/* int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; */759/* bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); */760break;761762case ANDROID_WIFI_CMD_BTCOEXSCAN_START:763/* TBD: BTCOEXSCAN-START */764break;765case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP:766/* TBD: BTCOEXSCAN-STOP */767break;768case ANDROID_WIFI_CMD_BTCOEXMODE:769#if 0770uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';771if (mode == 1)772net_os_set_packet_filter(net, 0); /* DHCP starts */773else774net_os_set_packet_filter(net, 1); /* DHCP ends */775#ifdef WL_CFG80211776bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command);777#endif778#endif779break;780781case ANDROID_WIFI_CMD_SETSUSPENDMODE:782break;783784case ANDROID_WIFI_CMD_SETSUSPENDOPT:785/* bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); */786break;787788case ANDROID_WIFI_CMD_SETBAND:789bytes_written = rtw_android_setband(net, command, priv_cmd.total_len);790break;791792case ANDROID_WIFI_CMD_GETBAND:793bytes_written = rtw_android_getband(net, command, priv_cmd.total_len);794break;795796case ANDROID_WIFI_CMD_COUNTRY:797bytes_written = rtw_android_set_country(net, command, priv_cmd.total_len);798break;799800#ifdef CONFIG_PNO_SUPPORT801case ANDROID_WIFI_CMD_PNOSSIDCLR_SET:802/* bytes_written = dhd_dev_pno_reset(net); */803break;804case ANDROID_WIFI_CMD_PNOSETUP_SET:805bytes_written = rtw_android_pno_setup(net, command, priv_cmd.total_len);806break;807case ANDROID_WIFI_CMD_PNOENABLE_SET:808cmdlen = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_PNOENABLE_SET]);809pno_enable = *(command + cmdlen + 1) - '0';810bytes_written = rtw_android_pno_enable(net, pno_enable);811break;812#endif813814case ANDROID_WIFI_CMD_P2P_DEV_ADDR:815bytes_written = rtw_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);816break;817case ANDROID_WIFI_CMD_P2P_SET_NOA:818/* int skip = strlen(CMD_P2P_SET_NOA) + 1; */819/* bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip); */820break;821case ANDROID_WIFI_CMD_P2P_GET_NOA:822/* bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); */823break;824case ANDROID_WIFI_CMD_P2P_SET_PS:825/* int skip = strlen(CMD_P2P_SET_PS) + 1; */826/* bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip); */827break;828829#ifdef CONFIG_IOCTL_CFG80211830case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE: {831int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3;832bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0');833break;834}835#endif /* CONFIG_IOCTL_CFG80211 */836837#ifdef CONFIG_WFD838839case ANDROID_WIFI_CMD_MIRACAST:840bytes_written = rtw_android_set_miracast_mode(net, command, priv_cmd.total_len);841break;842843case ANDROID_WIFI_CMD_WFD_ENABLE: {844/* Commented by Albert 2012/07/24 */845/* We can enable the WFD function by using the following command: */846/* wpa_cli driver wfd-enable */847848if (padapter->wdinfo.driver_interface == DRIVER_CFG80211)849rtw_wfd_enable(padapter, 1);850break;851}852853case ANDROID_WIFI_CMD_WFD_DISABLE: {854/* Commented by Albert 2012/07/24 */855/* We can disable the WFD function by using the following command: */856/* wpa_cli driver wfd-disable */857858if (padapter->wdinfo.driver_interface == DRIVER_CFG80211)859rtw_wfd_enable(padapter, 0);860break;861}862case ANDROID_WIFI_CMD_WFD_SET_TCPPORT: {863/* Commented by Albert 2012/07/24 */864/* We can set the tcp port number by using the following command: */865/* wpa_cli driver wfd-set-tcpport = 554 */866867if (padapter->wdinfo.driver_interface == DRIVER_CFG80211)868rtw_wfd_set_ctrl_port(padapter, (u16)get_int_from_command(command));869break;870}871case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT: {872break;873}874case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE: {875/* Commented by Albert 2012/08/28 */876/* Specify the WFD device type ( WFD source/primary sink ) */877878pwfd_info = &padapter->wfd_info;879if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {880pwfd_info->wfd_device_type = (u8) get_int_from_command(command);881pwfd_info->wfd_device_type &= WFD_DEVINFO_DUAL;882}883break;884}885#endif886case ANDROID_WIFI_CMD_CHANGE_DTIM: {887#ifdef CONFIG_LPS888u8 dtim;889u8 *ptr = (u8 *) command;890891ptr += 9;/* string command length of "SET_DTIM"; */892893dtim = rtw_atoi(ptr);894895RTW_INFO("DTIM=%d\n", dtim);896897rtw_lps_change_dtim_cmd(padapter, dtim);898#endif899}900break;901902#if CONFIG_RTW_MACADDR_ACL903case ANDROID_WIFI_CMD_HOSTAPD_SET_MACADDR_ACL: {904rtw_set_macaddr_acl(padapter, RTW_ACL_PERIOD_BSS, get_int_from_command(command));905break;906}907case ANDROID_WIFI_CMD_HOSTAPD_ACL_ADD_STA: {908u8 addr[ETH_ALEN] = {0x00};909macstr2num(addr, command + strlen("HOSTAPD_ACL_ADD_STA") + 3); /* 3 is space bar + "=" + space bar these 3 chars */910rtw_acl_add_sta(padapter, RTW_ACL_PERIOD_BSS, addr);911break;912}913case ANDROID_WIFI_CMD_HOSTAPD_ACL_REMOVE_STA: {914u8 addr[ETH_ALEN] = {0x00};915macstr2num(addr, command + strlen("HOSTAPD_ACL_REMOVE_STA") + 3); /* 3 is space bar + "=" + space bar these 3 chars */916rtw_acl_remove_sta(padapter, RTW_ACL_PERIOD_BSS, addr);917break;918}919#endif /* CONFIG_RTW_MACADDR_ACL */920#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0))921case ANDROID_WIFI_CMD_GTK_REKEY_OFFLOAD:922rtw_gtk_offload(net, (u8 *)command);923break;924#endif /* CONFIG_GTK_OL */925case ANDROID_WIFI_CMD_P2P_DISABLE: {926#ifdef CONFIG_P2P927rtw_p2p_enable(padapter, P2P_ROLE_DISABLE);928#endif /* CONFIG_P2P */929break;930}931932#ifdef CONFIG_RTW_MESH_AEK933case ANDROID_WIFI_CMD_SET_AEK:934bytes_written = rtw_android_set_aek(net, command, priv_cmd.total_len);935break;936#endif937938case ANDROID_WIFI_CMD_EXT_AUTH_STATUS: {939rtw_set_external_auth_status(padapter,940command + strlen("EXT_AUTH_STATUS "),941priv_cmd.total_len - strlen("EXT_AUTH_STATUS "));942break;943}944case ANDROID_WIFI_CMD_DRIVERVERSION: {945bytes_written = strlen(DRIVERVERSION);946snprintf(command, bytes_written + 1, DRIVERVERSION);947break;948}949default:950RTW_INFO("Unknown PRIVATE command %s - ignored\n", command);951snprintf(command, 3, "OK");952bytes_written = strlen("OK");953}954955response:956if (bytes_written >= 0) {957if ((bytes_written == 0) && (priv_cmd.total_len > 0))958command[0] = '\0';959if (bytes_written >= priv_cmd.total_len) {960RTW_INFO("%s: bytes_written = %d\n", __FUNCTION__, bytes_written);961bytes_written = priv_cmd.total_len;962} else963bytes_written++;964priv_cmd.used_len = bytes_written;965if (copy_to_user((void *)priv_cmd.buf, command, bytes_written)) {966RTW_INFO("%s: failed to copy data to user buffer\n", __FUNCTION__);967ret = -EFAULT;968}969} else970ret = bytes_written;971972exit:973rtw_unlock_suspend();974if (command)975rtw_mfree(command, priv_cmd.total_len + 1);976977return ret;978}979980981/**982* Functions for Android WiFi card detection983*/984#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)985986static int g_wifidev_registered = 0;987static struct semaphore wifi_control_sem;988static struct wifi_platform_data *wifi_control_data = NULL;989static struct resource *wifi_irqres = NULL;990991static int wifi_add_dev(void);992static void wifi_del_dev(void);993994int rtw_android_wifictrl_func_add(void)995{996int ret = 0;997sema_init(&wifi_control_sem, 0);998999ret = wifi_add_dev();1000if (ret) {1001RTW_INFO("%s: platform_driver_register failed\n", __FUNCTION__);1002return ret;1003}1004g_wifidev_registered = 1;10051006/* Waiting callback after platform_driver_register is done or exit with error */1007if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {1008ret = -EINVAL;1009RTW_INFO("%s: platform_driver_register timeout\n", __FUNCTION__);1010}10111012return ret;1013}10141015void rtw_android_wifictrl_func_del(void)1016{1017if (g_wifidev_registered) {1018wifi_del_dev();1019g_wifidev_registered = 0;1020}1021}10221023void *wl_android_prealloc(int section, unsigned long size)1024{1025void *alloc_ptr = NULL;1026if (wifi_control_data && wifi_control_data->mem_prealloc) {1027alloc_ptr = wifi_control_data->mem_prealloc(section, size);1028if (alloc_ptr) {1029RTW_INFO("success alloc section %d\n", section);1030if (size != 0L)1031memset(alloc_ptr, 0, size);1032return alloc_ptr;1033}1034}10351036RTW_INFO("can't alloc section %d\n", section);1037return NULL;1038}10391040int wifi_get_irq_number(unsigned long *irq_flags_ptr)1041{1042if (wifi_irqres) {1043*irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK;1044return (int)wifi_irqres->start;1045}1046#ifdef CUSTOM_OOB_GPIO_NUM1047return CUSTOM_OOB_GPIO_NUM;1048#else1049return -1;1050#endif1051}10521053int wifi_set_power(int on, unsigned long msec)1054{1055RTW_INFO("%s = %d\n", __FUNCTION__, on);1056if (wifi_control_data && wifi_control_data->set_power)1057wifi_control_data->set_power(on);1058if (msec)1059msleep(msec);1060return 0;1061}10621063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))1064int wifi_get_mac_addr(unsigned char *buf)1065{1066RTW_INFO("%s\n", __FUNCTION__);1067if (!buf)1068return -EINVAL;1069if (wifi_control_data && wifi_control_data->get_mac_addr)1070return wifi_control_data->get_mac_addr(buf);1071return -EOPNOTSUPP;1072}1073#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */10741075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) || defined(COMPAT_KERNEL_RELEASE)1076#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))1077void *wifi_get_country_code(char *ccode, u32 flags)1078#else /* Linux kernel < 3.18 */1079void *wifi_get_country_code(char *ccode)1080#endif /* Linux kernel < 3.18 */1081{1082RTW_INFO("%s\n", __FUNCTION__);1083if (!ccode)1084return NULL;1085if (wifi_control_data && wifi_control_data->get_country_code)1086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))1087return wifi_control_data->get_country_code(ccode, flags);1088#else /* Linux kernel < 3.18 */1089return wifi_control_data->get_country_code(ccode);1090#endif /* Linux kernel < 3.18 */1091return NULL;1092}1093#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */10941095static int wifi_set_carddetect(int on)1096{1097RTW_INFO("%s = %d\n", __FUNCTION__, on);1098if (wifi_control_data && wifi_control_data->set_carddetect)1099wifi_control_data->set_carddetect(on);1100return 0;1101}11021103static int wifi_probe(struct platform_device *pdev)1104{1105struct wifi_platform_data *wifi_ctrl =1106(struct wifi_platform_data *)(pdev->dev.platform_data);1107int wifi_wake_gpio = 0;11081109RTW_INFO("## %s\n", __FUNCTION__);1110wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");11111112if (wifi_irqres == NULL)1113wifi_irqres = platform_get_resource_byname(pdev,1114IORESOURCE_IRQ, "bcm4329_wlan_irq");1115else1116wifi_wake_gpio = wifi_irqres->start;11171118#ifdef CONFIG_GPIO_WAKEUP1119RTW_INFO("%s: gpio:%d wifi_wake_gpio:%d\n", __func__,1120(int)wifi_irqres->start, wifi_wake_gpio);11211122if (wifi_wake_gpio > 0) {1123#ifdef CONFIG_PLATFORM_INTEL_BYT1124wifi_configure_gpio();1125#else /* CONFIG_PLATFORM_INTEL_BYT */1126gpio_request(wifi_wake_gpio, "oob_irq");1127gpio_direction_input(wifi_wake_gpio);1128oob_irq = gpio_to_irq(wifi_wake_gpio);1129#endif /* CONFIG_PLATFORM_INTEL_BYT */1130RTW_INFO("%s oob_irq:%d\n", __func__, oob_irq);1131} else if (wifi_irqres) {1132oob_irq = wifi_irqres->start;1133RTW_INFO("%s oob_irq:%d\n", __func__, oob_irq);1134}1135#endif1136wifi_control_data = wifi_ctrl;11371138wifi_set_power(1, 0); /* Power On */1139wifi_set_carddetect(1); /* CardDetect (0->1) */11401141up(&wifi_control_sem);1142return 0;1143}11441145#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN1146extern PADAPTER g_test_adapter;11471148static void shutdown_card(void)1149{1150u32 addr;1151u8 tmp8, cnt = 0;11521153if (NULL == g_test_adapter) {1154RTW_INFO("%s: padapter==NULL\n", __FUNCTION__);1155return;1156}11571158#ifdef CONFIG_FWLPS_IN_IPS1159LeaveAllPowerSaveMode(g_test_adapter);1160#endif /* CONFIG_FWLPS_IN_IPS */11611162#ifdef CONFIG_WOWLAN1163#ifdef CONFIG_GPIO_WAKEUP1164/*default wake up pin change to BT*/1165RTW_INFO("%s:default wake up pin change to BT\n", __FUNCTION__);1166rtw_hal_switch_gpio_wl_ctrl(g_test_adapter, WAKEUP_GPIO_IDX, _FALSE);1167#endif /* CONFIG_GPIO_WAKEUP */1168#endif /* CONFIG_WOWLAN */11691170/* Leave SDIO HCI Suspend */1171addr = 0x10250086;1172rtw_write8(g_test_adapter, addr, 0);1173do {1174tmp8 = rtw_read8(g_test_adapter, addr);1175cnt++;1176RTW_INFO(FUNC_ADPT_FMT ": polling SDIO_HSUS_CTRL(0x%x)=0x%x, cnt=%d\n",1177FUNC_ADPT_ARG(g_test_adapter), addr, tmp8, cnt);11781179if (tmp8 & BIT(1))1180break;11811182if (cnt >= 100) {1183RTW_INFO(FUNC_ADPT_FMT ": polling 0x%x[1]==1 FAIL!!\n",1184FUNC_ADPT_ARG(g_test_adapter), addr);1185break;1186}11871188rtw_mdelay_os(10);1189} while (1);11901191/* unlock register I/O */1192rtw_write8(g_test_adapter, 0x1C, 0);11931194/* enable power down function */1195/* 0x04[4] = 1 */1196/* 0x05[7] = 1 */1197addr = 0x04;1198tmp8 = rtw_read8(g_test_adapter, addr);1199tmp8 |= BIT(4);1200rtw_write8(g_test_adapter, addr, tmp8);1201RTW_INFO(FUNC_ADPT_FMT ": read after write 0x%x=0x%x\n",1202FUNC_ADPT_ARG(g_test_adapter), addr, rtw_read8(g_test_adapter, addr));12031204addr = 0x05;1205tmp8 = rtw_read8(g_test_adapter, addr);1206tmp8 |= BIT(7);1207rtw_write8(g_test_adapter, addr, tmp8);1208RTW_INFO(FUNC_ADPT_FMT ": read after write 0x%x=0x%x\n",1209FUNC_ADPT_ARG(g_test_adapter), addr, rtw_read8(g_test_adapter, addr));12101211/* lock register page0 0x0~0xB read/write */1212rtw_write8(g_test_adapter, 0x1C, 0x0E);12131214rtw_set_surprise_removed(g_test_adapter);1215RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=%s\n",1216FUNC_ADPT_ARG(g_test_adapter), rtw_is_surprise_removed(g_test_adapter) ? "True" : "False");1217}1218#endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */12191220static int wifi_remove(struct platform_device *pdev)1221{1222struct wifi_platform_data *wifi_ctrl =1223(struct wifi_platform_data *)(pdev->dev.platform_data);12241225RTW_INFO("## %s\n", __FUNCTION__);1226wifi_control_data = wifi_ctrl;12271228wifi_set_power(0, 0); /* Power Off */1229wifi_set_carddetect(0); /* CardDetect (1->0) */12301231up(&wifi_control_sem);1232return 0;1233}12341235#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN1236static void wifi_shutdown(struct platform_device *pdev)1237{1238struct wifi_platform_data *wifi_ctrl =1239(struct wifi_platform_data *)(pdev->dev.platform_data);124012411242RTW_INFO("## %s\n", __FUNCTION__);12431244wifi_control_data = wifi_ctrl;12451246shutdown_card();1247wifi_set_power(0, 0); /* Power Off */1248wifi_set_carddetect(0); /* CardDetect (1->0) */1249}1250#endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */12511252static int wifi_suspend(struct platform_device *pdev, pm_message_t state)1253{1254RTW_INFO("##> %s\n", __FUNCTION__);1255#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)1256bcmsdh_oob_intr_set(0);1257#endif1258return 0;1259}12601261static int wifi_resume(struct platform_device *pdev)1262{1263RTW_INFO("##> %s\n", __FUNCTION__);1264#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)1265if (dhd_os_check_if_up(bcmsdh_get_drvdata()))1266bcmsdh_oob_intr_set(1);1267#endif1268return 0;1269}12701271/* temporarily use these two */1272static struct platform_driver wifi_device = {1273.probe = wifi_probe,1274.remove = wifi_remove,1275.suspend = wifi_suspend,1276.resume = wifi_resume,1277#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN1278.shutdown = wifi_shutdown,1279#endif /* RTW_SUPPORT_PLATFORM_SHUTDOWN */1280.driver = {1281.name = "bcmdhd_wlan",1282}1283};12841285static struct platform_driver wifi_device_legacy = {1286.probe = wifi_probe,1287.remove = wifi_remove,1288.suspend = wifi_suspend,1289.resume = wifi_resume,1290.driver = {1291.name = "bcm4329_wlan",1292}1293};12941295static int wifi_add_dev(void)1296{1297RTW_INFO("## Calling platform_driver_register\n");1298platform_driver_register(&wifi_device);1299platform_driver_register(&wifi_device_legacy);1300return 0;1301}13021303static void wifi_del_dev(void)1304{1305RTW_INFO("## Unregister platform_driver_register\n");1306platform_driver_unregister(&wifi_device);1307platform_driver_unregister(&wifi_device_legacy);1308}1309#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */13101311#ifdef CONFIG_GPIO_WAKEUP1312#ifdef CONFIG_PLATFORM_INTEL_BYT1313int wifi_configure_gpio(void)1314{1315if (gpio_request(oob_gpio, "oob_irq")) {1316RTW_INFO("## %s Cannot request GPIO\n", __FUNCTION__);1317return -1;1318}1319gpio_export(oob_gpio, 0);1320if (gpio_direction_input(oob_gpio)) {1321RTW_INFO("## %s Cannot set GPIO direction input\n", __FUNCTION__);1322return -1;1323}1324oob_irq = gpio_to_irq(oob_gpio);1325if (oob_irq < 0) {1326RTW_INFO("## %s Cannot convert GPIO to IRQ\n", __FUNCTION__);1327return -1;1328}13291330RTW_INFO("## %s OOB_IRQ=%d\n", __FUNCTION__, oob_irq);13311332return 0;1333}1334#endif /* CONFIG_PLATFORM_INTEL_BYT */1335void wifi_free_gpio(unsigned int gpio)1336{1337#ifdef CONFIG_PLATFORM_INTEL_BYT1338if (gpio)1339gpio_free(gpio);1340#endif /* CONFIG_PLATFORM_INTEL_BYT */1341}1342#endif /* CONFIG_GPIO_WAKEUP */134313441345