diff options
Diffstat (limited to 'drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c')
-rw-r--r-- | drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c | 1469 |
1 files changed, 0 insertions, 1469 deletions
diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c deleted file mode 100644 index 7f1b86c..0000000 --- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c +++ /dev/null @@ -1,1469 +0,0 @@ -/* - * Linux cfg80211 driver - Android related functions - * - * Copyright (C) 1999-2012, Broadcom Corporation - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2 (the "GPL"), - * available at http://www.broadcom.com/licenses/GPLv2.php, with the - * following added to such license: - * - * As a special exception, the copyright holders of this software give you - * permission to link this software with independent modules, and to copy and - * distribute the resulting executable under terms of your choice, provided that - * you also meet, for each linked independent module, the terms and conditions of - * the license of that module. An independent module is a module which is not - * derived from this software. The special exception does not apply to any - * modifications of the software. - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a license - * other than the GPL, without Broadcom's express prior written consent. - * - * $Id: wl_android.c 309571 2012-01-20 01:45:10Z $ - */ - -#include <linux/module.h> -#include <linux/netdevice.h> - -#include <wl_android.h> -#include <wldev_common.h> -#include <wlioctl.h> -#include <bcmutils.h> -#include <linux_osl.h> -#include <dhd_dbg.h> -#include <dngl_stats.h> -#include <dhd.h> -#include <bcmsdbus.h> -#ifdef WL_CFG80211 -#include <wl_cfg80211.h> -#endif -#if defined(CONFIG_WIFI_CONTROL_FUNC) -#include <linux/platform_device.h> -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -#include <linux/wlan_plat.h> -#else -#include <linux/wifi_tiwlan.h> -#endif -#endif /* CONFIG_WIFI_CONTROL_FUNC */ - -/* - * Android private command strings, PLEASE define new private commands here - * so they can be updated easily in the future (if needed) - */ - -#define CMD_START "START" -#define CMD_STOP "STOP" -#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -#define CMD_RSSI "RSSI" -#define CMD_LINKSPEED "LINKSPEED" -#define CMD_RXFILTER_START "RXFILTER-START" -#define CMD_RXFILTER_STOP "RXFILTER-STOP" -#define CMD_RXFILTER_ADD "RXFILTER-ADD" -#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" -#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -#define CMD_BTCOEXMODE "BTCOEXMODE" -#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -#define CMD_SETFWPATH "SETFWPATH" -#define CMD_SETBAND "SETBAND" -#define CMD_GETBAND "GETBAND" -#define CMD_COUNTRY "COUNTRY" -#define CMD_P2P_SET_NOA "P2P_SET_NOA" -#define CMD_P2P_GET_NOA "P2P_GET_NOA" -#define CMD_P2P_SET_PS "P2P_SET_PS" -#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" - - -/* Hostapd private command */ -#define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL" -#define CMD_SET_HAPD_MAX_NUM_STA "HAPD_MAX_NUM_STA" -#define CMD_SET_HAPD_SSID "HAPD_SSID" -#define CMD_SET_HAPD_HIDE_SSID "HAPD_HIDE_SSID" -#define CMD_HAPD_STA_DISASSOC "HAPD_STA_DISASSOC" -#ifdef BCMCCX -#define CMD_GETCCKM_RN "get cckm_rn" -#define CMD_SETCCKM_KRK "set cckm_krk" -#define CMD_GET_ASSOC_RES_IES "get assoc_res_ies" -#endif - -#ifdef PNO_SUPPORT -#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" -#define CMD_PNOSETUP_SET "PNOSETUP " -#define CMD_PNOENABLE_SET "PNOFORCE" -#define CMD_PNODEBUG_SET "PNODEBUG" - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION '1' -#define PNO_TLV_SUBVERSION '2' -#define PNO_TLV_RESERVED '0' -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_TLV_FREQ_REPEAT 'R' -#define PNO_TLV_FREQ_EXPO_MAX 'M' - -typedef struct cmd_tlv { - char prefix; - char version; - char subver; - char reserved; -} cmd_tlv_t; -#endif /* PNO_SUPPORT */ - -#ifdef ROAM_API -#define CMD_ROAMTRIGGER_SET "SETROAMTRIGGER" -#define CMD_ROAMTRIGGER_GET "GETROAMTRIGGER" -#define CMD_ROAMDELTA_SET "SETROAMDELTA" -#define CMD_ROAMDELTA_GET "GETROAMDELTA" -#define CMD_ROAMSCANPERIOD_SET "SETROAMSCANPERIOD" -#define CMD_ROAMSCANPERIOD_GET "GETROAMSCANPERIOD" -#define CMD_COUNTRYREV_SET "SETCOUNTRYREV" -#define CMD_COUNTRYREV_GET "GETCOUNTRYREV" -#endif /* ROAM_API */ - -#ifdef OKC_SUPPORT -#define CMD_OKC_SET_PMK "SET_PMK" -#define CMD_OKC_ENABLE "OKC_ENABLE" -#endif - -#ifdef SUPPORT_AMPDU_MPDU_CMD -#define CMD_AMPDU_MPDU "AMPDU_MPDU" -#endif - -#ifdef VSDB -#define CMD_CHANGE_RL "CHANGE_RL" -#define CMD_RESTORE_RL "RESTORE_RL" -#endif -typedef struct android_wifi_priv_cmd { - char *buf; - int used_len; - int total_len; -} android_wifi_priv_cmd; - -/** - * Extern function declarations (TODO: move them to dhd_linux.h) - */ -void dhd_customer_gpio_wlan_ctrl(int onoff); -uint dhd_dev_reset(struct net_device *dev, uint8 flag); -void dhd_dev_init_ioctl(struct net_device *dev); -#ifdef WL_CFG80211 -int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); -int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command); -#else -int wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr) -{ return 0; } -int wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len) -{ return 0; } -int wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len) -{ return 0; } -int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len) -{ return 0; } -#endif -extern int dhd_os_check_if_up(void *dhdp); -extern void *bcmsdh_get_drvdata(void); - -extern bool ap_fw_loaded; -#if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW_SAMSUNG) -extern char iface_name[IFNAMSIZ]; -#endif - -/** - * Local (static) functions and variables - */ - -/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first - * time (only) in dhd_open, subsequential wifi on will be handled by - * wl_android_wifi_on - */ -static int g_wifi_on = TRUE; - -/** - * Local (static) function definitions - */ -static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len) -{ - int link_speed; - int bytes_written; - int error; - - error = wldev_get_link_speed(net, &link_speed); - if (error) - return -1; - - /* Convert Kbps to Android Mbps */ - link_speed = link_speed / 1000; - bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed); - DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); - return bytes_written; -} - -static int wl_android_get_rssi(struct net_device *net, char *command, int total_len) -{ - wlc_ssid_t ssid = {0}; - int rssi; - int bytes_written = 0; - int error; - - error = wldev_get_rssi(net, &rssi); - if (error) - return -1; - - error = wldev_get_ssid(net, &ssid); - if (error) - return -1; - if ((ssid.SSID_len == 0) || (ssid.SSID_len > DOT11_MAX_SSID_LEN)) { - DHD_ERROR(("%s: wldev_get_ssid failed\n", __FUNCTION__)); - } else { - memcpy(command, ssid.SSID, ssid.SSID_len); - bytes_written = ssid.SSID_len; - } - bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi); - DHD_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written)); - return bytes_written; -} - -static int wl_android_set_suspendopt(struct net_device *dev, char *command, int total_len) -{ - int suspend_flag; - int ret_now; - int ret = 0; - -#ifdef CUSTOMER_HW_SAMSUNG - if (!dhd_download_fw_on_driverload) { -#endif /* CUSTOMER_HW_SAMSUNG */ - suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0'; - - if (suspend_flag != 0) - suspend_flag = 1; - ret_now = net_os_set_suspend_disable(dev, suspend_flag); - - if (ret_now != suspend_flag) { - if (!(ret = net_os_set_suspend(dev, ret_now))) - DHD_INFO(("%s: Suspend Flag %d -> %d\n", - __FUNCTION__, ret_now, suspend_flag)); - else - DHD_ERROR(("%s: failed %d\n", __FUNCTION__, ret)); - } -#ifdef CUSTOMER_HW_SAMSUNG - } -#endif /* CUSTOMER_HW_SAMSUNG */ - return ret; -} - -static int wl_android_get_band(struct net_device *dev, char *command, int total_len) -{ - uint band; - int bytes_written; - int error; - - error = wldev_get_band(dev, &band); - if (error) - return -1; - bytes_written = snprintf(command, total_len, "Band %d", band); - return bytes_written; -} - -#ifdef ROAM_API -int wl_android_set_roam_trigger( - struct net_device *dev, char* command, int total_len) -{ - int roam_trigger[2]; - - sscanf(command, "%*s %d", &roam_trigger[0]); - roam_trigger[1] = WLC_BAND_ALL; - - return wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, - sizeof(roam_trigger), 1); -} - -static int wl_android_get_roam_trigger( - struct net_device *dev, char *command, int total_len) -{ - int bytes_written; - int roam_trigger[2] = {0, 0}; - - roam_trigger[1] = WLC_BAND_2G; - if (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, - sizeof(roam_trigger), 0)) { - roam_trigger[1] = WLC_BAND_5G; - if (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, - sizeof(roam_trigger), 0)) - return -1; - } - - bytes_written = snprintf(command, total_len, "%s %d", - CMD_ROAMTRIGGER_GET, roam_trigger[0]); - - return bytes_written; -} - -int wl_android_set_roam_delta( - struct net_device *dev, char* command, int total_len) -{ - int roam_delta[2]; - - sscanf(command, "%*s %d", &roam_delta[0]); - roam_delta[1] = WLC_BAND_ALL; - - return wldev_ioctl(dev, WLC_SET_ROAM_DELTA, roam_delta, - sizeof(roam_delta), 1); -} - -static int wl_android_get_roam_delta( - struct net_device *dev, char *command, int total_len) -{ - int bytes_written; - int roam_delta[2] = {0, 0}; - - roam_delta[1] = WLC_BAND_2G; - if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta, - sizeof(roam_delta), 0)) { - roam_delta[1] = WLC_BAND_5G; - if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta, - sizeof(roam_delta), 0)) - return -1; - } - - bytes_written = snprintf(command, total_len, "%s %d", - CMD_ROAMDELTA_GET, roam_delta[0]); - - return bytes_written; -} - -int wl_android_set_roam_scan_period( - struct net_device *dev, char* command, int total_len) -{ - int roam_scan_period = 0; - - sscanf(command, "%*s %d", &roam_scan_period); - return wldev_ioctl(dev, WLC_SET_ROAM_SCAN_PERIOD, &roam_scan_period, - sizeof(roam_scan_period), 1); -} - -static int wl_android_get_roam_scan_period( - struct net_device *dev, char *command, int total_len) -{ - int bytes_written; - int roam_scan_period = 0; - - if (wldev_ioctl(dev, WLC_GET_ROAM_SCAN_PERIOD, &roam_scan_period, - sizeof(roam_scan_period), 0)) - return -1; - - bytes_written = snprintf(command, total_len, "%s %d", - CMD_ROAMSCANPERIOD_GET, roam_scan_period); - - return bytes_written; -} - -int wl_android_set_country_rev( - struct net_device *dev, char* command, int total_len) -{ - int error = 0; - wl_country_t cspec = {{0}, 0, {0} }; - char country_code[WLC_CNTRY_BUF_SZ]; - char smbuf[WLC_IOCTL_SMLEN]; - int rev = 0; - - memset(country_code, 0, sizeof(country_code)); - sscanf(command+sizeof("SETCOUNTRYREV"), "%s %d", country_code, &rev); - WL_TRACE(("%s: country_code = %s, rev = %d\n", __func__, - country_code, rev)); - - memcpy(cspec.country_abbrev, country_code, sizeof(country_code)); - memcpy(cspec.ccode, country_code, sizeof(country_code)); - cspec.rev = rev; - - error = wldev_iovar_setbuf(dev, "country", (char *)&cspec, - sizeof(cspec), smbuf, sizeof(smbuf), NULL); - - if (error) { - DHD_ERROR(("%s: set country '%s/%d' failed code %d\n", - __func__, cspec.ccode, cspec.rev, error)); - } else { - dhd_bus_country_set(dev, &cspec); - DHD_INFO(("%s: set country '%s/%d'\n", - __func__, cspec.ccode, cspec.rev)); - } - - return error; -} - -static int wl_android_get_country_rev( - struct net_device *dev, char *command, int total_len) -{ - int error; - int bytes_written; - char smbuf[WLC_IOCTL_SMLEN]; - wl_country_t cspec; - - error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec), smbuf, - sizeof(smbuf), NULL); - - if (error) { - DHD_ERROR(("%s: get country failed code %d\n", - __func__, error)); - return -1; - } else { - DHD_INFO(("%s: get country '%s %d'\n", __func__, smbuf, smbuf[WLC_CNTRY_BUF_SZ])); - } - bytes_written = snprintf(command, total_len, "%s %s %d", CMD_COUNTRYREV_GET, smbuf, smbuf[WLC_CNTRY_BUF_SZ]); - return bytes_written; -} -#endif /* ROAM_API */ - -#ifdef PNO_SUPPORT -static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len) -{ - wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT]; - int res = -1; - int nssid = 0; - cmd_tlv_t *cmd_tlv_temp; - char *str_ptr; - int tlv_size_left; - int pno_time = 0; - int pno_repeat = 0; - int pno_freq_expo_max = 0; - -#ifdef PNO_SET_DEBUG - int i; - char pno_in_example[] = { - 'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ', - 'S', '1', '2', '0', - 'S', - 0x05, - 'd', 'l', 'i', 'n', 'k', - 'S', - 0x04, - 'G', 'O', 'O', 'G', - 'T', - '0', 'B', - 'R', - '2', - 'M', - '2', - 0x00 - }; -#endif /* PNO_SET_DEBUG */ - - DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - - if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) { - DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len)); - goto exit_proc; - } - - -#ifdef PNO_SET_DEBUG - memcpy(command, pno_in_example, sizeof(pno_in_example)); - for (i = 0; i < sizeof(pno_in_example); i++) - printf("%02X ", command[i]); - printf("\n"); - total_len = sizeof(pno_in_example); -#endif - - str_ptr = command + strlen(CMD_PNOSETUP_SET); - tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET); - - cmd_tlv_temp = (cmd_tlv_t *)str_ptr; - memset(ssids_local, 0, sizeof(ssids_local)); - - if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) && - (cmd_tlv_temp->version == PNO_TLV_VERSION) && - (cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) { - - str_ptr += sizeof(cmd_tlv_t); - tlv_size_left -= sizeof(cmd_tlv_t); - - if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local, - MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) { - DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid)); - goto exit_proc; - } else { - if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) { - DHD_ERROR(("%s scan duration corrupted field size %d\n", - __FUNCTION__, tlv_size_left)); - goto exit_proc; - } - str_ptr++; - pno_time = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time)); - - if (str_ptr[0] != 0) { - if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) { - DHD_ERROR(("%s pno repeat : corrupted field\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat)); - if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) { - DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n", - __FUNCTION__)); - goto exit_proc; - } - str_ptr++; - pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16); - DHD_INFO(("%s: pno_freq_expo_max=%d\n", - __FUNCTION__, pno_freq_expo_max)); - } - } - } else { - DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__)); - goto exit_proc; - } - - res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max); - -exit_proc: - return res; -} -#endif /* PNO_SUPPORT */ - -static int wl_android_get_p2p_dev_addr(struct net_device *ndev, char *command, int total_len) -{ - int ret; - int bytes_written = 0; - - ret = wl_cfg80211_get_p2p_dev_addr(ndev, (struct ether_addr*)command); - if (ret) - return 0; - bytes_written = sizeof(struct ether_addr); - return bytes_written; -} -#ifdef BCMCCX -static int wl_android_get_cckm_rn(struct net_device *dev, char *command) -{ - int error, rn; - - WL_TRACE(("%s:wl_android_get_cckm_rn\n", dev->name)); - - error = wldev_iovar_getint(dev, "cckm_rn", &rn); - if (unlikely(error)) { - WL_ERR(("wl_android_get_cckm_rn error (%d)\n", error)); - return -1; - } - //WL_ERR(("wl_android_get_cckm_rn = %d\n", rn)); - memcpy(command, &rn, sizeof(int)); - - return sizeof(int); -} - -static int wl_android_set_cckm_krk(struct net_device *dev, char *command) -{ - int error; - unsigned char key[16]; - - static char iovar_buf[WLC_IOCTL_MEDLEN]; - - WL_TRACE(("%s: wl_iw_set_cckm_krk\n", dev->name)); - - memset(iovar_buf, 0, sizeof(iovar_buf)); - memcpy(key, command+strlen("set cckm_krk")+1, 16); - - error = wldev_iovar_setbuf(dev,"cckm_krk", key, sizeof(key), iovar_buf, WLC_IOCTL_MEDLEN, NULL); - if (unlikely(error)) - { - WL_ERR((" cckm_krk set error (%d)\n", error)); - return -1; - } - return 0; -} -static int wl_android_get_assoc_res_ies(struct net_device *dev, char *command) -{ - int error; - u8 buf[WL_ASSOC_INFO_MAX]; - wl_assoc_info_t assoc_info; - u32 resp_ies_len = 0; - int bytes_written = 0; - - WL_TRACE(("%s: wl_iw_get_assoc_res_ies\n", dev->name)); - - error = wldev_iovar_getbuf(dev, "assoc_info", NULL, 0, buf, WL_ASSOC_INFO_MAX, NULL); - if (unlikely(error)) { - WL_ERR(("could not get assoc info (%d)\n", error)); - return -1; - } - - memcpy(&assoc_info, buf, sizeof(wl_assoc_info_t)); - assoc_info.req_len = htod32(assoc_info.req_len); - assoc_info.resp_len = htod32(assoc_info.resp_len); - assoc_info.flags = htod32(assoc_info.flags); - - if (assoc_info.resp_len) { - resp_ies_len = assoc_info.resp_len - sizeof(struct dot11_assoc_resp); - } - - /* first 4 bytes are ie len */ - memcpy(command, &resp_ies_len, sizeof(u32)); - bytes_written= sizeof(u32); - - /* get the association resp IE's if there are any */ - if (resp_ies_len) { - error = wldev_iovar_getbuf(dev, "assoc_resp_ies", NULL, 0, buf, WL_ASSOC_INFO_MAX, NULL); - if (unlikely(error)) { - WL_ERR(("could not get assoc resp_ies (%d)\n", error)); - return -1; - } - - memcpy(command+sizeof(u32), buf, resp_ies_len); - bytes_written += resp_ies_len; - } - return bytes_written; -} - -#endif /* BCMCCX */ - -/** - * Global function definitions (declared in wl_android.h) - */ - -int wl_android_wifi_on(struct net_device *dev) -{ - int ret = 0; - int retry = POWERUP_MAX_RETRY; - - DHD_ERROR(("%s in\n", __FUNCTION__)); - if (!dev) { - DHD_ERROR(("%s: dev is null\n", __FUNCTION__)); - return -EINVAL; - } - - dhd_net_if_lock(dev); - if (!g_wifi_on) { - do { - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); - if (dhd_download_fw_on_driverload) - msleep(300); - - ret = sdioh_start(NULL, 0); - if (ret == 0) - break; - DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n", - retry+1)); - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - } while (retry-- >= 0); - if (ret != 0) { - DHD_ERROR(("\nfailed to power up wifi chip, max retry reached **\n\n")); - goto exit; - } - ret = dhd_dev_reset(dev, FALSE); - sdioh_start(NULL, 1); - dhd_dev_init_ioctl(dev); - g_wifi_on = TRUE; - } - -exit: - dhd_net_if_unlock(dev); - - return ret; -} - -int wl_android_wifi_off(struct net_device *dev) -{ - int ret = 0; - - DHD_ERROR(("%s in\n", __FUNCTION__)); - if (!dev) { - DHD_TRACE(("%s: dev is null\n", __FUNCTION__)); - return -EINVAL; - } - - dhd_net_if_lock(dev); - if (g_wifi_on) { - dhd_dev_reset(dev, 1); - if (dhd_download_fw_on_driverload) - msleep(100); - sdioh_stop(NULL); - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - g_wifi_on = FALSE; - } - dhd_net_if_unlock(dev); - - return ret; -} - -static int wl_android_set_fwpath(struct net_device *net, char *command, int total_len) -{ - if ((strlen(command) - strlen(CMD_SETFWPATH)) > MOD_PARAM_PATHLEN) - return -1; - bcm_strncpy_s(fw_path, sizeof(fw_path), - command + strlen(CMD_SETFWPATH) + 1, MOD_PARAM_PATHLEN - 1); - if (strstr(fw_path, "apsta") != NULL) { - DHD_INFO(("GOT APSTA FIRMWARE\n")); - ap_fw_loaded = TRUE; - } else { - DHD_INFO(("GOT STA FIRMWARE\n")); - ap_fw_loaded = FALSE; - } - return 0; -} - - -static int -wl_android_set_auto_channel(struct net_device *dev, const char* string_num, - char* command, int total_len) -{ - int channel; - int chosen = 0; - int retry = 0; - int ret = 0; - - /* Restrict channel to 1 - 7: 2GHz, 20MHz BW, No SB */ - u32 req_buf[8] = {7, 0x2B01, 0x2B02, 0x2B03, 0x2B04, 0x2B05, 0x2B06, - 0x2B07}; - - /* Auto channel select */ - wl_uint32_list_t request; - - channel = bcm_atoi(string_num); - DHD_INFO(("%s : HAPD_AUTO_CHANNEL = %d\n", __FUNCTION__, channel)); - - if (channel == 20) - ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&req_buf, - sizeof(req_buf), true); - else { /* channel == 0 */ - request.count = htod32(0); - ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)&request, - sizeof(request), true); - } - - if (ret < 0) { - DHD_ERROR(("%s: can't start auto channel scan, err = %d\n", - __FUNCTION__, ret)); - channel = 0; - goto done; - } - - /* Wait for auto channel selection, max 2500 ms */ - bcm_mdelay(500); - - retry = 10; - while(retry--) { - ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen), - false); - if (ret < 0 || dtoh32(chosen) == 0) { - DHD_INFO(("%s: %d tried, ret = %d, chosen = %d\n", - __FUNCTION__, (10 - retry), ret, chosen)); - bcm_mdelay(200); - } - else { - channel = (u16)chosen & 0x00FF; - DHD_ERROR(("%s: selected channel = %d\n", __FUNCTION__, channel)); - break; - } - } - - if (retry == 0) { - DHD_ERROR(("%s: auto channel timed out, failed\n", __FUNCTION__)); - channel = 0; - } - -done: -// snprintf(command, total_len, "%d", channel); - snprintf(command, 4, "%d", channel); - DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); - -// return 1; - return 4; -} - -static int -wl_android_set_max_num_sta(struct net_device *dev, const char* string_num) -{ - int max_assoc; - - max_assoc = bcm_atoi(string_num); - DHD_INFO(("%s : HAPD_MAX_NUM_STA = %d\n", __FUNCTION__, max_assoc)); - wldev_iovar_setint(dev, "maxassoc", max_assoc); - return 1; -} - -static int -wl_android_set_ssid (struct net_device *dev, const char* hapd_ssid) -{ - wlc_ssid_t ssid; - s32 ret; - - ssid.SSID_len = strlen(hapd_ssid); - bcm_strncpy_s(ssid.SSID, sizeof(ssid.SSID), hapd_ssid, ssid.SSID_len); - DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__, ssid.SSID)); - ret = wldev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t), true); - if (ret < 0) { - DHD_ERROR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__, ret)); - } - return 1; - -} - -static int -wl_android_set_hide_ssid(struct net_device *dev, const char* string_num) -{ - int hide_ssid; - int enable = 0; - - hide_ssid = bcm_atoi(string_num); - DHD_INFO(("%s: HAPD_HIDE_SSID = %d\n", __FUNCTION__, hide_ssid)); - if (hide_ssid) - enable = 1; - wldev_iovar_setint(dev, "closednet", enable); - return 1; -} - -static int -wl_android_sta_diassoc(struct net_device *dev, const char* straddr) -{ - scb_val_t scbval; - s32 ret; - - DHD_INFO(("%s: deauth STA %s\n", __FUNCTION__, straddr)); - - /* Unspecified reason */ - scbval.val = htod32(1); - bcm_ether_atoe(straddr, &scbval.ea); - - DHD_INFO(("%s: deauth STA: %02X:%02X:%02X:%02X:%02X:%02X\n", __FUNCTION__, - scbval.ea.octet[0], scbval.ea.octet[1], scbval.ea.octet[2], - scbval.ea.octet[3], scbval.ea.octet[4], scbval.ea.octet[5])); - - if ((ret = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, - sizeof(scb_val_t), true)) < 0) { - DHD_ERROR(("%s : WLC_SCB_DEAUTHENTICATE_FOR_REASON error:%d\n", __FUNCTION__ , ret)); - } - - return 1; -} - -#ifdef OKC_SUPPORT - -static int -wl_android_set_pmk(struct net_device *dev, char *command, int total_len) -{ - uchar pmk[33]; - int error = 0; - char smbuf[WLC_IOCTL_SMLEN]; -#ifdef OKC_DEBUG - int i = 0; -#endif - - bzero(pmk, sizeof(pmk)); - memcpy((char *)pmk, command + strlen("SET_PMK "), 32); - error = wldev_iovar_setbuf(dev, "okc_info_pmk", pmk, 32, smbuf, sizeof(smbuf), NULL); - if (error) { - DHD_ERROR(("Failed to set PMK for OKC, error = %d\n", error)); - } -#ifdef OKC_DEBUG - DHD_ERROR(("PMK is ")); - for (i = 0; i < 32; i++) - DHD_ERROR(("%02X ", pmk[i])); - - DHD_ERROR(("\n")); -#endif - return error; -} - -static int -wl_android_okc_enable(struct net_device *dev, char *command, int total_len) -{ - int error = 0; - char okc_enable = 0; - - okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0'; - error = wldev_iovar_setint(dev, "okc_enable", okc_enable); - if (error) { - DHD_ERROR(("Failed to %s OKC, error = %d\n", - okc_enable ? "enable" : "disable", error)); - } - - return error; -} - -#endif /* OKC_ SUPPORT */ -#ifdef VSDB -static int -wl_android_ch_res_rl(struct net_device *dev, bool change) -{ - int error = 0; - s32 srl = 7; - s32 lrl = 4; - printk("%s enter\n", __FUNCTION__); - if (change) { - srl = 4; - lrl = 2; - } - error = wldev_ioctl(dev, WLC_SET_SRL, &srl, - sizeof(s32), true); - if (error) { - DHD_ERROR(("Failed to set SRL, error = %d\n", error)); - } - error = wldev_ioctl(dev, WLC_SET_LRL, &lrl, - sizeof(s32), true); - if (error) { - DHD_ERROR(("Failed to set LRL, error = %d\n", error)); - } - return error; -} -#endif - -#ifdef SUPPORT_AMPDU_MPDU_CMD -/* CMD_AMPDU_MPDU */ -static int -wl_android_set_ampdu_mpdu(struct net_device *dev, const char* string_num) -{ - int err = 0; - int ampdu_mpdu; - - //ampdu_mpdu = my_atoi(string_num); - ampdu_mpdu = bcm_atoi(string_num); - - if (ampdu_mpdu > 32) { - DHD_ERROR(("%s : ampdu_mpdu MAX value is 32.\n", __FUNCTION__)); - return -1; - } - DHD_ERROR(("%s : ampdu_mpdu = %d\n", __FUNCTION__, ampdu_mpdu)); - err = wldev_iovar_setint(dev, "ampdu_mpdu", ampdu_mpdu); - if (err < 0) { - DHD_ERROR(("%s : ampdu_mpdu set error. %d\n", __FUNCTION__, err)); - return -1; - } - - return 0; -} -#endif - -int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) -{ - int ret = 0; - char *command = NULL; - int bytes_written = 0; - android_wifi_priv_cmd priv_cmd; - - net_os_wake_lock(net); - - if (!ifr->ifr_data) { - ret = -EINVAL; - goto exit; - } - if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) { - ret = -EFAULT; - goto exit; - } - command = kmalloc(priv_cmd.total_len, GFP_KERNEL); - if (!command) - { - DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__)); - ret = -ENOMEM; - goto exit; - } - if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) { - ret = -EFAULT; - goto exit; - } - - DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name)); - - if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) { - DHD_ERROR(("%s, Received regular START command\n", __FUNCTION__)); -#ifdef CUSTOMER_HW_SAMSUNG - sleep_never = 1; -#else - bytes_written = wl_android_wifi_on(net); -#endif /* CUSTOMER_HW_SAMSUNG */ - } - else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) { - bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len); - } - - if (!g_wifi_on) { - DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n", - __FUNCTION__, command, ifr->ifr_name)); - ret = 0; - goto exit; - } - - if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) { - DHD_ERROR(("%s, Received regular STOP command\n", __FUNCTION__)); -#ifdef CUSTOMER_HW_SAMSUNG - sleep_never = 1; -#else - bytes_written = wl_android_wifi_off(net); -#endif /* CUSTOMER_HW_SAMSUNG */ - } - else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) { - /* TBD: SCAN-ACTIVE */ - } - else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) { - /* TBD: SCAN-PASSIVE */ - } - else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) { - bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { - bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) { - bytes_written = net_os_set_packet_filter(net, 1); - } - else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) { - bytes_written = net_os_set_packet_filter(net, 0); - } - else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) { - int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0'; - bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num); - } - else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) { - int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0'; - bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num); - } - else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) { - /* TBD: BTCOEXSCAN-START */ - } - else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) { - /* TBD: BTCOEXSCAN-STOP */ - } - else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) { -#if !defined(CUSTOMER_HW_SAMSUNG) - uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; - - if (mode == 1) - net_os_set_packet_filter(net, 0); /* DHCP starts */ - else - net_os_set_packet_filter(net, 1); /* DHCP ends */ -#endif -#ifdef WL_CFG80211 - bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command); -#endif - } - else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { - bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { - uint band = *(command + strlen(CMD_SETBAND) + 1) - '0'; - bytes_written = wldev_set_band(net, band); - wl_update_wiphybands(NULL); - } - else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { - bytes_written = wl_android_get_band(net, command, priv_cmd.total_len); - } -#ifndef GLOBALCONFIG_WLAN_COUNTRY_CODE - - else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { - char *country_code = command + strlen(CMD_COUNTRY) + 1; - bytes_written = wldev_set_country(net, country_code); - wl_update_wiphybands(NULL); - } -#endif -#ifdef ROAM_API - else if (strnicmp(command, CMD_ROAMTRIGGER_SET, - strlen(CMD_ROAMTRIGGER_SET)) == 0) { - bytes_written = wl_android_set_roam_trigger(net, command, - priv_cmd.total_len); - } else if (strnicmp(command, CMD_ROAMTRIGGER_GET, - strlen(CMD_ROAMTRIGGER_GET)) == 0) { - bytes_written = wl_android_get_roam_trigger(net, command, - priv_cmd.total_len); - } else if (strnicmp(command, CMD_ROAMDELTA_SET, - strlen(CMD_ROAMDELTA_SET)) == 0) { - bytes_written = wl_android_set_roam_delta(net, command, - priv_cmd.total_len); - } else if (strnicmp(command, CMD_ROAMDELTA_GET, - strlen(CMD_ROAMDELTA_GET)) == 0) { - bytes_written = wl_android_get_roam_delta(net, command, - priv_cmd.total_len); - } else if (strnicmp(command, CMD_ROAMSCANPERIOD_SET, - strlen(CMD_ROAMSCANPERIOD_SET)) == 0) { - bytes_written = wl_android_set_roam_scan_period(net, command, - priv_cmd.total_len); - } else if (strnicmp(command, CMD_ROAMSCANPERIOD_GET, - strlen(CMD_ROAMSCANPERIOD_GET)) == 0) { - bytes_written = wl_android_get_roam_scan_period(net, command, - priv_cmd.total_len); - } else if (strnicmp(command, CMD_COUNTRYREV_SET, - strlen(CMD_COUNTRYREV_SET)) == 0) { - bytes_written = wl_android_set_country_rev(net, command, - priv_cmd.total_len); - wl_update_wiphybands(NULL); - } else if (strnicmp(command, CMD_COUNTRYREV_GET, - strlen(CMD_COUNTRYREV_GET)) == 0) { - bytes_written = wl_android_get_country_rev(net, command, - priv_cmd.total_len); - } -#endif /* ROAM_API */ -#ifdef PNO_SUPPORT - else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { - bytes_written = dhd_dev_pno_reset(net); - } - else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { - bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { - uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0'; - bytes_written = dhd_dev_pno_enable(net, pfn_enabled); - } -#endif - else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) { - bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) { - int skip = strlen(CMD_P2P_SET_NOA) + 1; - bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, - priv_cmd.total_len - skip); - } - else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) { - bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len); - } - else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) { - int skip = strlen(CMD_P2P_SET_PS) + 1; - bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, - priv_cmd.total_len - skip); - } -#ifdef WL_CFG80211 - else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE, - strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) { - int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3; - bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip, - priv_cmd.total_len - skip, *(command + skip - 2) - '0'); - } -#endif /* WL_CFG80211 */ - else if (strnicmp(command, CMD_SET_HAPD_AUTO_CHANNEL, - strlen(CMD_SET_HAPD_AUTO_CHANNEL)) == 0) { - int skip = strlen(CMD_SET_HAPD_AUTO_CHANNEL) + 3; -// wl_android_set_auto_channel(net, (const char*)command+skip, command, -// priv_cmd.total_len); - bytes_written = wl_android_set_auto_channel(net, (const char*)command+skip, command, - priv_cmd.total_len); - } - else if (strnicmp(command, CMD_SET_HAPD_MAX_NUM_STA, - strlen(CMD_SET_HAPD_MAX_NUM_STA)) == 0) { - int skip = strlen(CMD_SET_HAPD_MAX_NUM_STA) + 3; - wl_android_set_max_num_sta(net, (const char*)command+skip); - } - else if (strnicmp(command, CMD_SET_HAPD_SSID, - strlen(CMD_SET_HAPD_SSID)) == 0) { - int skip = strlen(CMD_SET_HAPD_SSID) + 3; - wl_android_set_ssid(net, (const char*)command+skip); - } - else if (strnicmp(command, CMD_SET_HAPD_HIDE_SSID, - strlen(CMD_SET_HAPD_HIDE_SSID)) == 0) { - int skip = strlen(CMD_SET_HAPD_HIDE_SSID) + 3; - wl_android_set_hide_ssid(net, (const char*)command+skip); - } - else if (strnicmp(command, CMD_HAPD_STA_DISASSOC, - strlen(CMD_HAPD_STA_DISASSOC)) == 0) { - int skip = strlen(CMD_HAPD_STA_DISASSOC) + 1; - wl_android_sta_diassoc(net, (const char*)command+skip); - } -#ifdef OKC_SUPPORT - else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0) - bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len); - else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0) - bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len); -#endif /* OKC_SUPPORT */ -#ifdef BCMCCX - else if (strnicmp(command, CMD_GETCCKM_RN, strlen(CMD_GETCCKM_RN)) == 0) { - bytes_written = wl_android_get_cckm_rn(net, command); - } - else if (strnicmp(command, CMD_SETCCKM_KRK, strlen(CMD_SETCCKM_KRK)) == 0) { - bytes_written = wl_android_set_cckm_krk(net, command); - } - else if (strnicmp(command, CMD_GET_ASSOC_RES_IES, strlen(CMD_GET_ASSOC_RES_IES)) == 0) { - bytes_written = wl_android_get_assoc_res_ies(net, command); - } -#endif /* BCMCCX */ -#ifdef SUPPORT_AMPDU_MPDU_CMD - /* CMD_AMPDU_MPDU */ - else if (strnicmp(command, CMD_AMPDU_MPDU,strlen(CMD_AMPDU_MPDU)) == 0) { - int skip = strlen(CMD_AMPDU_MPDU) + 1; - bytes_written = wl_android_set_ampdu_mpdu(net, (const char*)command+skip); - } -#endif -#ifdef VSDB - else if (strnicmp(command, CMD_CHANGE_RL, strlen(CMD_CHANGE_RL)) == 0) - bytes_written = wl_android_ch_res_rl(net, true); - else if (strnicmp(command, CMD_RESTORE_RL, strlen(CMD_RESTORE_RL)) == 0) - bytes_written = wl_android_ch_res_rl(net, false); -#endif - else { - if ((strnicmp(command, CMD_START, strlen(CMD_START)) != 0) && - (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) != 0)) - DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command)); - snprintf(command, 3, "OK"); - bytes_written = strlen("OK"); - } - - if (bytes_written >= 0) { - if ((bytes_written == 0) && (priv_cmd.total_len > 0)) - command[0] = '\0'; - if (bytes_written >= priv_cmd.total_len) { - DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written)); - bytes_written = priv_cmd.total_len; - } else { - bytes_written++; - } - priv_cmd.used_len = bytes_written; - if (copy_to_user(priv_cmd.buf, command, bytes_written)) { - DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__)); - ret = -EFAULT; - } - } - else { - ret = bytes_written; - } - -exit: - net_os_wake_unlock(net); - if (command) { - kfree(command); - } - - return ret; -} - -int wl_android_init(void) -{ - int ret = 0; - - dhd_msg_level = DHD_ERROR_VAL; -#ifdef ENABLE_INSMOD_NO_FW_LOAD - dhd_download_fw_on_driverload = FALSE; -#endif /* ENABLE_INSMOD_NO_FW_LOAD */ -#if defined(CUSTOMER_HW2) || defined(CUSTOMER_HW_SAMSUNG) - if (!iface_name[0]) { - memset(iface_name, 0, IFNAMSIZ); - bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ); - } -#endif /* CUSTOMER_HW2 || CUSTOMER_HW_SAMSUNG */ - return ret; -} - -int wl_android_exit(void) -{ - int ret = 0; - - return ret; -} - -void wl_android_post_init(void) -{ - if (!dhd_download_fw_on_driverload) { - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF); - g_wifi_on = 0; - } -} -/** - * Functions for Android WiFi card detection - */ -#if defined(CONFIG_WIFI_CONTROL_FUNC) - -static int g_wifidev_registered = 0; -static struct semaphore wifi_control_sem; -static struct wifi_platform_data *wifi_control_data = NULL; -static struct resource *wifi_irqres = NULL; - -static int wifi_add_dev(void); -static void wifi_del_dev(void); - -int wl_android_wifictrl_func_add(void) -{ - int ret = 0; - sema_init(&wifi_control_sem, 0); - - ret = wifi_add_dev(); - if (ret) { - DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__)); - return ret; - } - g_wifidev_registered = 1; - - /* Waiting callback after platform_driver_register is done or exit with error */ - if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { - ret = -EINVAL; - DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__)); - } - - return ret; -} - -void wl_android_wifictrl_func_del(void) -{ - if (g_wifidev_registered) - { - wifi_del_dev(); - g_wifidev_registered = 0; - } -} - -void* wl_android_prealloc(int section, unsigned long size) -{ - void *alloc_ptr = NULL; - if (wifi_control_data && wifi_control_data->mem_prealloc) { - alloc_ptr = wifi_control_data->mem_prealloc(section, size); - if (alloc_ptr) { - DHD_INFO(("success alloc section %d\n", section)); - if (size != 0L) - bzero(alloc_ptr, size); - return alloc_ptr; - } - } - - DHD_ERROR(("can't alloc section %d\n", section)); - return NULL; -} - -int wifi_get_irq_number(unsigned long *irq_flags_ptr) -{ - if (wifi_irqres) { - *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; - return (int)wifi_irqres->start; - } -#ifdef CUSTOM_OOB_GPIO_NUM - return CUSTOM_OOB_GPIO_NUM; -#else - return -1; -#endif -} - -int wifi_set_power(int on, unsigned long msec) -{ - DHD_ERROR(("%s = %d\n", __FUNCTION__, on)); - if (wifi_control_data && wifi_control_data->set_power) { - wifi_control_data->set_power(on); - } - if (msec) - msleep(msec); - return 0; -} - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) -int wifi_get_mac_addr(unsigned char *buf) -{ - DHD_ERROR(("%s\n", __FUNCTION__)); - if (!buf) - return -EINVAL; - if (wifi_control_data && wifi_control_data->get_mac_addr) { - return wifi_control_data->get_mac_addr(buf); - } - return -EOPNOTSUPP; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */ - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -void *wifi_get_country_code(char *ccode) -{ - DHD_TRACE(("%s\n", __FUNCTION__)); - if (!ccode) - return NULL; - if (wifi_control_data && wifi_control_data->get_country_code) { - return wifi_control_data->get_country_code(ccode); - } - return NULL; -} -#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */ - -static int wifi_set_carddetect(int on) -{ - DHD_ERROR(("%s = %d\n", __FUNCTION__, on)); - if (wifi_control_data && wifi_control_data->set_carddetect) { - wifi_control_data->set_carddetect(on); - } - return 0; -} - -static int wifi_probe(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - DHD_ERROR(("## %s\n", __FUNCTION__)); - wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq"); - if (wifi_irqres == NULL) - wifi_irqres = platform_get_resource_byname(pdev, - IORESOURCE_IRQ, "bcm4329_wlan_irq"); - wifi_control_data = wifi_ctrl; - - wifi_set_power(1, 200); /* Power On */ - wifi_set_carddetect(1); /* CardDetect (0->1) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_remove(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - DHD_ERROR(("## %s\n", __FUNCTION__)); - wifi_control_data = wifi_ctrl; - - wifi_set_power(0, 100); /* Power Off */ - wifi_set_carddetect(0); /* CardDetect (1->0) */ - - up(&wifi_control_sem); - return 0; -} -int dhd_os_check_wakelock(void *dhdp); - -static int wifi_suspend(struct platform_device *pdev, pm_message_t state) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if defined(BCMHOST) - if (dhd_os_check_wakelock(bcmsdh_get_drvdata())) - return -EBUSY; -#endif -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 - bcmsdh_oob_intr_set(0); -#endif /* (OOB_INTR_ONLY) */ - return 0; -} - -static int wifi_resume(struct platform_device *pdev) -{ - DHD_TRACE(("##> %s\n", __FUNCTION__)); -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && 1 - if (dhd_os_check_if_up(bcmsdh_get_drvdata())) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ - return 0; -} - -static struct platform_driver wifi_device = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = "bcmdhd_wlan", - } -}; - -static struct platform_driver wifi_device_legacy = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = "bcm4329_wlan", - } -}; - -static int wifi_add_dev(void) -{ - DHD_TRACE(("## Calling platform_driver_register\n")); - platform_driver_register(&wifi_device); - platform_driver_register(&wifi_device_legacy); - return 0; -} - -static void wifi_del_dev(void) -{ - DHD_TRACE(("## Unregister platform_driver_register\n")); - platform_driver_unregister(&wifi_device); - platform_driver_unregister(&wifi_device_legacy); -} -#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */ |