/*
* Linux cfg80211 driver - Android related functions
*
- * $Copyright Open Broadcom Corporation$
+ * Copyright (C) 1999-2016, 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 505064 2014-09-26 09:40:28Z $
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: wl_android.c 608788 2015-12-29 10:59:33Z $
*/
#include <linux/module.h>
#ifdef WL_NAN
#include <wl_cfgnan.h>
#endif /* WL_NAN */
+#ifdef DHDTCPACK_SUPPRESS
+#include <dhd_ip.h>
+#endif /* DHDTCPACK_SUPPRESS */
#ifndef WL_CFG80211
#define htod32(i) i
#define CMD_SCAN_PASSIVE "SCAN-PASSIVE"
#define CMD_RSSI "RSSI"
#define CMD_LINKSPEED "LINKSPEED"
-#ifdef PKT_FILTER_SUPPORT
#define CMD_RXFILTER_START "RXFILTER-START"
#define CMD_RXFILTER_STOP "RXFILTER-STOP"
#define CMD_RXFILTER_ADD "RXFILTER-ADD"
#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE"
-#if defined(CUSTOM_PLATFORM_NV_TEGRA)
-#define CMD_PKT_FILTER_MODE "PKT_FILTER_MODE"
-#define CMD_PKT_FILTER_PORTS "PKT_FILTER_PORTS"
-#endif /* defined(CUSTOM_PLATFORM_NV_TEGRA) */
-#endif /* PKT_FILTER_SUPPORT */
#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
#define CMD_BTCOEXMODE "BTCOEXMODE"
#define CMD_P2P_GET_NOA "P2P_GET_NOA"
#endif /* WL_ENABLE_P2P_IF */
#define CMD_P2P_SD_OFFLOAD "P2P_SD_"
+#define CMD_P2P_LISTEN_OFFLOAD "P2P_LO_"
#define CMD_P2P_SET_PS "P2P_SET_PS"
+#define CMD_P2P_ECSA "P2P_ECSA"
#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE"
#define CMD_SETROAMMODE "SETROAMMODE"
#define CMD_SETIBSSBEACONOUIDATA "SETIBSSBEACONOUIDATA"
#define CMD_MIRACAST "MIRACAST"
+#ifdef WL_NAN
#define CMD_NAN "NAN_"
+#endif /* WL_NAN */
+#define CMD_COUNTRY_DELIMITER "/"
+#ifdef WL11ULB
+#define CMD_ULB_MODE "ULB_MODE"
+#define CMD_ULB_BW "ULB_BW"
+#endif /* WL11ULB */
#define CMD_GET_CHANNEL "GET_CHANNEL"
#define CMD_SET_ROAM "SET_ROAM_TRIGGER"
#define CMD_GET_ROAM "GET_ROAM_TRIGGER"
#define CMD_GET_BEST_CHANNELS "GET_BEST_CHANNELS"
#endif /* WL_SUPPORT_AUTO_CHANNEL */
-#if defined(CUSTOM_PLATFORM_NV_TEGRA)
-#define CMD_SETMIRACAST "SETMIRACAST"
-#define CMD_ASSOCRESPIE "ASSOCRESPIE"
-#define CMD_RXRATESTATS "RXRATESTATS"
-#endif /* defined(CUSTOM_PLATFORM_NV_TEGRA) */
-
+#define CMD_80211_MODE "MODE" /* 802.11 mode a/b/g/n/ac */
+#define CMD_CHANSPEC "CHANSPEC"
+#define CMD_DATARATE "DATARATE"
+#define CMD_ASSOC_CLIENTS "ASSOCLIST"
+#define CMD_SET_CSA "SETCSA"
+#ifdef WL_SUPPORT_AUTO_CHANNEL
+#define CMD_SET_HAPD_AUTO_CHANNEL "HAPD_AUTO_CHANNEL"
+#endif /* WL_SUPPORT_AUTO_CHANNEL */
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+#ifdef SUPPORT_SET_LPC
+#define CMD_HAPD_LPC_ENABLED "HAPD_LPC_ENABLED"
+#endif /* SUPPORT_SET_LPC */
+#ifdef SUPPORT_TRIGGER_HANG_EVENT
+#define CMD_TEST_FORCE_HANG "TEST_FORCE_HANG"
+#endif /* SUPPORT_TRIGGER_HANG_EVENT */
+#ifdef TEST_TX_POWER_CONTROL
+#define CMD_TEST_SET_TX_POWER "TEST_SET_TX_POWER"
+#define CMD_TEST_GET_TX_POWER "TEST_GET_TX_POWER"
+#endif /* TEST_TX_POWER_CONTROL */
+#define CMD_SARLIMIT_TX_CONTROL "SET_TX_POWER_CALLING"
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
#define CMD_KEEP_ALIVE "KEEPALIVE"
-/* CCX Private Commands */
-#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_WLS_BATCHING "WLS_BATCHING"
#endif /* PNO_SUPPORT */
-#define CMD_OKC_SET_PMK "SET_PMK"
-#define CMD_OKC_ENABLE "OKC_ENABLE"
-
#define CMD_HAPD_MAC_FILTER "HAPD_MAC_FILTER"
-#ifdef WLFBT
-#define CMD_GET_FTKEY "GET_FTKEY"
-#endif
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+
+
+#if defined(SUPPORT_RANDOM_MAC_SCAN)
+#define ENABLE_RANDOM_MAC "ENABLE_RANDOM_MAC"
+#define DISABLE_RANDOM_MAC "DISABLE_RANDOM_MAC"
+#endif /* SUPPORT_RANDOM_MAC_SCAN */
+
+
+#define CMD_CHANGE_RL "CHANGE_RL"
+#define CMD_RESTORE_RL "RESTORE_RL"
+
+#define CMD_SET_RMC_ENABLE "SETRMCENABLE"
+#define CMD_SET_RMC_TXRATE "SETRMCTXRATE"
+#define CMD_SET_RMC_ACTPERIOD "SETRMCACTIONPERIOD"
+#define CMD_SET_RMC_IDLEPERIOD "SETRMCIDLEPERIOD"
+#define CMD_SET_RMC_LEADER "SETRMCLEADER"
+#define CMD_SET_RMC_EVENT "SETRMCEVENT"
+
+#define CMD_SET_SCSCAN "SETSINGLEANT"
+#define CMD_GET_SCSCAN "GETSINGLEANT"
+
+/* FCC_PWR_LIMIT_2G */
+#define CUSTOMER_HW4_ENABLE 0
+#define CUSTOMER_HW4_DISABLE -1
+#define CUSTOMER_HW4_EN_CONVERT(i) (i += 1)
+
+#ifdef WLTDLS
+#define CMD_TDLS_RESET "TDLS_RESET"
+#endif /* WLTDLS */
+
+#ifdef IPV6_NDO_SUPPORT
+#define CMD_NDRA_LIMIT "NDRA_LIMIT"
+#endif /* IPV6_NDO_SUPPORT */
+
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
-#ifdef WLAIBSS
-#define CMD_SETIBSSTXFAILEVENT "SETIBSSTXFAILEVENT"
-#define CMD_GET_IBSS_PEER_INFO "GETIBSSPEERINFO"
-#define CMD_GET_IBSS_PEER_INFO_ALL "GETIBSSPEERINFOALL"
-#define CMD_SETIBSSROUTETABLE "SETIBSSROUTETABLE"
-#define CMD_SETIBSSAMPDU "SETIBSSAMPDU"
-#define CMD_SETIBSSANTENNAMODE "SETIBSSANTENNAMODE"
-#endif /* WLAIBSS */
#define CMD_ROAM_OFFLOAD "SETROAMOFFLOAD"
-#define CMD_ROAM_OFFLOAD_APLIST "SETROAMOFFLAPLIST"
-#define CMD_GET_LINK_STATUS "GETLINKSTATUS"
+#define CMD_ROAM_OFFLOAD_APLIST "SETROAMOFFLAPLIST"
+#define CMD_INTERFACE_CREATE "INTERFACE_CREATE"
+#define CMD_INTERFACE_DELETE "INTERFACE_DELETE"
+
+#if defined(DHD_ENABLE_BIGDATA_LOGGING)
+#define CMD_GET_BSS_INFO "GETBSSINFO"
+#define CMD_GET_ASSOC_REJECT_INFO "GETASSOCREJECTINFO"
+#endif /* DHD_ENABLE_BIGDATA_LOGGING */
#ifdef P2PRESP_WFDIE_SRC
#define CMD_P2P_SET_WFDIE_RESP "P2P_SET_WFDIE_RESP"
#define CMD_P2P_GET_WFDIE_RESP "P2P_GET_WFDIE_RESP"
#endif /* P2PRESP_WFDIE_SRC */
-/* related with CMD_GET_LINK_STATUS */
-#define WL_ANDROID_LINK_VHT 0x01
-#define WL_ANDROID_LINK_MIMO 0x02
-#define WL_ANDROID_LINK_AP_VHT_SUPPORT 0x04
-#define WL_ANDROID_LINK_AP_MIMO_SUPPORT 0x08
+#define CMD_DFS_AP_MOVE "DFS_AP_MOVE"
+#define CMD_WBTEXT_ENABLE "WBTEXT_ENABLE"
+#define CMD_WBTEXT_PROFILE_CONFIG "WBTEXT_PROFILE_CONFIG"
+#define CMD_WBTEXT_WEIGHT_CONFIG "WBTEXT_WEIGHT_CONFIG"
+#define CMD_WBTEXT_TABLE_CONFIG "WBTEXT_TABLE_CONFIG"
+#define CMD_WBTEXT_DELTA_CONFIG "WBTEXT_DELTA_CONFIG"
+
+#ifdef WLWFDS
+#define CMD_ADD_WFDS_HASH "ADD_WFDS_HASH"
+#define CMD_DEL_WFDS_HASH "DEL_WFDS_HASH"
+#endif /* WLWFDS */
+
+#ifdef SET_RPS_CPUS
+#define CMD_RPSMODE "RPSMODE"
+#endif /* SET_RPS_CPUS */
+
+#ifdef BT_WIFI_HANDOVER
+#define CMD_TBOW_TEARDOWN "TBOW_TEARDOWN"
+#endif /* BT_WIFI_HANDOVER */
+
+#define CMD_MURX_BFE_CAP "MURX_BFE_CAP"
/* miracast related definition */
#define MIRACAST_MODE_OFF 0
static u8 miracast_cur_mode;
#endif
+#ifdef DHD_LOG_DUMP
+#define CMD_NEW_DEBUG_PRINT_DUMP "DEBUG_DUMP"
+extern void dhd_schedule_log_dump(dhd_pub_t *dhdp);
+extern int dhd_bus_mem_dump(dhd_pub_t *dhd);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_TRACE_WAKE_LOCK
+extern void dhd_wk_lock_stats_dump(dhd_pub_t *dhdp);
+#endif /* DHD_TRACE_WAKE_LOCK */
+
struct io_cfg {
s8 *iovar;
s32 param;
(JOIN_PREF_WPA_TUPLE_SIZE * JOIN_PREF_MAX_WPA_TUPLES))
#endif /* BCMFW_ROAM_ENABLE */
-#ifdef WL_GENL
-static s32 wl_genl_handle_msg(struct sk_buff *skb, struct genl_info *info);
-static int wl_genl_init(void);
-static int wl_genl_deinit(void);
-
-extern struct net init_net;
-/* attribute policy: defines which attribute has which type (e.g int, char * etc)
- * possible values defined in net/netlink.h
- */
-static struct nla_policy wl_genl_policy[BCM_GENL_ATTR_MAX + 1] = {
- [BCM_GENL_ATTR_STRING] = { .type = NLA_NUL_STRING },
- [BCM_GENL_ATTR_MSG] = { .type = NLA_BINARY },
-};
-
-#define WL_GENL_VER 1
-/* family definition */
-static struct genl_family wl_genl_family = {
- .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */
- .hdrsize = 0,
- .name = "bcm-genl", /* Netlink I/F for Android */
- .version = WL_GENL_VER, /* Version Number */
- .maxattr = BCM_GENL_ATTR_MAX,
-};
-
-/* commands: mapping between the command enumeration and the actual function */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
-struct genl_ops wl_genl_ops[] = {
- {
- .cmd = BCM_GENL_CMD_MSG,
- .flags = 0,
- .policy = wl_genl_policy,
- .doit = wl_genl_handle_msg,
- .dumpit = NULL,
- },
-};
-#else
-struct genl_ops wl_genl_ops = {
- .cmd = BCM_GENL_CMD_MSG,
- .flags = 0,
- .policy = wl_genl_policy,
- .doit = wl_genl_handle_msg,
- .dumpit = NULL,
-
-};
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
-static struct genl_multicast_group wl_genl_mcast[] = {
- { .name = "bcm-genl-mcast", },
-};
-#else
-static struct genl_multicast_group wl_genl_mcast = {
- .id = GENL_ID_GENERATE, /* Genetlink would generate the ID */
- .name = "bcm-genl-mcast",
-};
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
-#endif /* WL_GENL */
/**
* Extern function declarations (TODO: move them to dhd_linux.h)
{ return 0; }
int wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
{ return 0; }
+int wl_cfg80211_set_p2p_ecsa(struct net_device *net, char* buf, int len)
+{ return 0; }
#endif /* WL_CFG80211 */
/**
* Local (static) function definitions
*/
+
+#ifdef WLWFDS
+static int wl_android_set_wfds_hash(
+ struct net_device *dev, char *command, int total_len, bool enable)
+{
+ int error = 0;
+ wl_p2p_wfds_hash_t *wfds_hash = NULL;
+ char *smbuf = NULL;
+ smbuf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
+
+ if (smbuf == NULL) {
+ ANDROID_ERROR(("%s: failed to allocated memory %d bytes\n",
+ __FUNCTION__, WLC_IOCTL_MAXLEN));
+ return -ENOMEM;
+ }
+
+ if (enable) {
+ wfds_hash = (wl_p2p_wfds_hash_t *)(command + strlen(CMD_ADD_WFDS_HASH) + 1);
+ error = wldev_iovar_setbuf(dev, "p2p_add_wfds_hash", wfds_hash,
+ sizeof(wl_p2p_wfds_hash_t), smbuf, WLC_IOCTL_MAXLEN, NULL);
+ }
+ else {
+ wfds_hash = (wl_p2p_wfds_hash_t *)(command + strlen(CMD_DEL_WFDS_HASH) + 1);
+ error = wldev_iovar_setbuf(dev, "p2p_del_wfds_hash", wfds_hash,
+ sizeof(wl_p2p_wfds_hash_t), smbuf, WLC_IOCTL_MAXLEN, NULL);
+ }
+
+ if (error) {
+ ANDROID_ERROR(("%s: failed to %s, error=%d\n", __FUNCTION__, command, error));
+ }
+
+ if (smbuf)
+ kfree(smbuf);
+ return error;
+}
+#endif /* WLWFDS */
+
static int wl_android_get_link_speed(struct net_device *net, char *command, int total_len)
{
int link_speed;
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;
+ int error = 0;
+ scb_val_t scbval;
+ char *delim = NULL;
+
+ delim = strchr(command, ' ');
+ /* For Ap mode rssi command would be
+ * driver rssi <sta_mac_addr>
+ * for STA/GC mode
+ * driver rssi
+ */
+ if (delim) {
+ /* Ap/GO mode
+ * driver rssi <sta_mac_addr>
+ */
+ ANDROID_TRACE(("%s: cmd:%s\n", __FUNCTION__, delim));
+ /* skip space from delim after finding char */
+ delim++;
+ if (!(bcm_ether_atoe((delim), &scbval.ea)))
+ {
+ ANDROID_ERROR(("%s:address err\n", __FUNCTION__));
+ return -1;
+ }
+ scbval.val = htod32(0);
+ ANDROID_TRACE(("%s: address:"MACDBG, __FUNCTION__, MAC2STRDBG(scbval.ea.octet)));
+ }
+ else {
+ /* STA/GC mode */
+ memset(&scbval, 0, sizeof(scb_val_t));
+ }
- error = wldev_get_rssi(net, &rssi);
+ error = wldev_get_rssi(net, &scbval);
if (error)
return -1;
#if defined(RSSIOFFSET)
- rssi = wl_update_rssi_offset(net, rssi);
+ scbval.val = wl_update_rssi_offset(net, scbval.val);
#endif
error = wldev_get_ssid(net, &ssid);
memcpy(command, ssid.SSID, ssid.SSID_len);
bytes_written = ssid.SSID_len;
}
- bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", rssi);
- ANDROID_INFO(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written));
+ bytes_written += snprintf(&command[bytes_written], total_len, " rssi %d", scbval.val);
+ ANDROID_TRACE(("%s: command result is %s (%d)\n", __FUNCTION__, command, bytes_written));
return bytes_written;
}
suspend_flag = *(command + strlen(CMD_SETSUSPENDOPT) + 1) - '0';
- if (suspend_flag != 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, 1)))
+ if (!(ret = net_os_set_suspend(dev, ret_now, 1))) {
ANDROID_INFO(("%s: Suspend Flag %d -> %d\n",
__FUNCTION__, ret_now, suspend_flag));
- else
+ } else {
ANDROID_ERROR(("%s: failed %d\n", __FUNCTION__, ret));
+ }
}
+
return ret;
}
return ret;
}
+int wl_android_get_80211_mode(struct net_device *dev, char *command, int total_len)
+{
+ uint8 mode[4];
+ int error = 0;
+ int bytes_written = 0;
+
+ error = wldev_get_mode(dev, mode);
+ if (error)
+ return -1;
+
+ ANDROID_INFO(("%s: mode:%s\n", __FUNCTION__, mode));
+ bytes_written = snprintf(command, total_len, "%s %s", CMD_80211_MODE, mode);
+ ANDROID_INFO(("%s: command:%s EXIT\n", __FUNCTION__, command));
+ return bytes_written;
+
+}
+
+extern chanspec_t
+wl_chspec_driver_to_host(chanspec_t chanspec);
+int wl_android_get_chanspec(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int bytes_written = 0;
+ int chsp = {0};
+ uint16 band = 0;
+ uint16 bw = 0;
+ uint16 channel = 0;
+ u32 sb = 0;
+ chanspec_t chanspec;
+
+ /* command is
+ * driver chanspec
+ */
+ error = wldev_iovar_getint(dev, "chanspec", &chsp);
+ if (error)
+ return -1;
+
+ chanspec = wl_chspec_driver_to_host(chsp);
+ ANDROID_INFO(("%s:return value of chanspec:%x\n", __FUNCTION__, chanspec));
+
+ channel = chanspec & WL_CHANSPEC_CHAN_MASK;
+ band = chanspec & WL_CHANSPEC_BAND_MASK;
+ bw = chanspec & WL_CHANSPEC_BW_MASK;
+
+ ANDROID_INFO(("%s:channel:%d band:%d bandwidth:%d\n", __FUNCTION__, channel, band, bw));
+
+ if (bw == WL_CHANSPEC_BW_80)
+ bw = WL_CH_BANDWIDTH_80MHZ;
+ else if (bw == WL_CHANSPEC_BW_40)
+ bw = WL_CH_BANDWIDTH_40MHZ;
+ else if (bw == WL_CHANSPEC_BW_20)
+ bw = WL_CH_BANDWIDTH_20MHZ;
+ else
+ bw = WL_CH_BANDWIDTH_20MHZ;
+
+ if (bw == WL_CH_BANDWIDTH_40MHZ) {
+ if (CHSPEC_SB_UPPER(chanspec)) {
+ channel += CH_10MHZ_APART;
+ } else {
+ channel -= CH_10MHZ_APART;
+ }
+ }
+ else if (bw == WL_CH_BANDWIDTH_80MHZ) {
+ sb = chanspec & WL_CHANSPEC_CTL_SB_MASK;
+ if (sb == WL_CHANSPEC_CTL_SB_LL) {
+ channel -= (CH_10MHZ_APART + CH_20MHZ_APART);
+ } else if (sb == WL_CHANSPEC_CTL_SB_LU) {
+ channel -= CH_10MHZ_APART;
+ } else if (sb == WL_CHANSPEC_CTL_SB_UL) {
+ channel += CH_10MHZ_APART;
+ } else {
+ /* WL_CHANSPEC_CTL_SB_UU */
+ channel += (CH_10MHZ_APART + CH_20MHZ_APART);
+ }
+ }
+ bytes_written = snprintf(command, total_len, "%s channel %d band %s bw %d", CMD_CHANSPEC,
+ channel, band == WL_CHANSPEC_BAND_5G ? "5G":"2G", bw);
+
+ ANDROID_INFO(("%s: command:%s EXIT\n", __FUNCTION__, command));
+ return bytes_written;
+
+}
+
+/* returns current datarate datarate returned from firmware are in 500kbps */
+int wl_android_get_datarate(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int datarate = 0;
+ int bytes_written = 0;
+
+ error = wldev_get_datarate(dev, &datarate);
+ if (error)
+ return -1;
+
+ ANDROID_INFO(("%s:datarate:%d\n", __FUNCTION__, datarate));
+
+ bytes_written = snprintf(command, total_len, "%s %d", CMD_DATARATE, (datarate/2));
+ return bytes_written;
+}
+int wl_android_get_assoclist(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int bytes_written = 0;
+ uint i;
+ char mac_buf[MAX_NUM_OF_ASSOCLIST *
+ sizeof(struct ether_addr) + sizeof(uint)] = {0};
+ struct maclist *assoc_maclist = (struct maclist *)mac_buf;
+
+ ANDROID_TRACE(("%s: ENTER\n", __FUNCTION__));
+
+ assoc_maclist->count = htod32(MAX_NUM_OF_ASSOCLIST);
+
+ error = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf), false);
+ if (error)
+ return -1;
+
+ assoc_maclist->count = dtoh32(assoc_maclist->count);
+ bytes_written = snprintf(command, total_len, "%s listcount: %d Stations:",
+ CMD_ASSOC_CLIENTS, assoc_maclist->count);
+
+ for (i = 0; i < assoc_maclist->count; i++) {
+ bytes_written += snprintf(command + bytes_written, total_len, " " MACDBG,
+ MAC2STRDBG(assoc_maclist->ea[i].octet));
+ }
+ return bytes_written;
+
+}
+extern chanspec_t
+wl_chspec_host_to_driver(chanspec_t chanspec);
+static int wl_android_set_csa(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ char smbuf[WLC_IOCTL_SMLEN];
+ wl_chan_switch_t csa_arg;
+ u32 chnsp = 0;
+ int err = 0;
+
+ ANDROID_INFO(("%s: command:%s\n", __FUNCTION__, command));
+
+ command = (command + strlen(CMD_SET_CSA));
+ /* Order is mode, count channel */
+ if (!*++command) {
+ ANDROID_ERROR(("%s:error missing arguments\n", __FUNCTION__));
+ return -1;
+ }
+ csa_arg.mode = bcm_atoi(command);
+
+ if (csa_arg.mode != 0 && csa_arg.mode != 1) {
+ ANDROID_ERROR(("Invalid mode\n"));
+ return -1;
+ }
+
+ if (!*++command) {
+ ANDROID_ERROR(("%s:error missing count\n", __FUNCTION__));
+ return -1;
+ }
+ command++;
+ csa_arg.count = bcm_atoi(command);
+
+ csa_arg.reg = 0;
+ csa_arg.chspec = 0;
+ command += 2;
+ if (!*command) {
+ ANDROID_ERROR(("%s:error missing channel\n", __FUNCTION__));
+ return -1;
+ }
+
+ chnsp = wf_chspec_aton(command);
+ if (chnsp == 0) {
+ ANDROID_ERROR(("%s:chsp is not correct\n", __FUNCTION__));
+ return -1;
+ }
+ chnsp = wl_chspec_host_to_driver(chnsp);
+ csa_arg.chspec = chnsp;
+
+ if (chnsp & WL_CHANSPEC_BAND_5G) {
+ u32 chanspec = chnsp;
+ err = wldev_iovar_getint(dev, "per_chan_info", &chanspec);
+ if (!err) {
+ if ((chanspec & WL_CHAN_RADAR) || (chanspec & WL_CHAN_PASSIVE)) {
+ ANDROID_ERROR(("Channel is radar sensitive\n"));
+ return -1;
+ }
+ if (chanspec == 0) {
+ ANDROID_ERROR(("Invalid hw channel\n"));
+ return -1;
+ }
+ } else {
+ ANDROID_ERROR(("does not support per_chan_info\n"));
+ return -1;
+ }
+ ANDROID_INFO(("non radar sensitivity\n"));
+ }
+ error = wldev_iovar_setbuf(dev, "csa", &csa_arg, sizeof(csa_arg),
+ smbuf, sizeof(smbuf), NULL);
+ if (error) {
+ ANDROID_ERROR(("%s:set csa failed:%d\n", __FUNCTION__, error));
+ return -1;
+ }
+ return 0;
+}
static int wl_android_get_band(struct net_device *dev, char *command, int total_len)
{
uint band;
return bytes_written;
}
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+
+#ifdef FCC_PWR_LIMIT_2G
+int
+wl_android_set_fcc_pwr_limit_2g(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int enable = 0;
+
+ sscanf(command+sizeof("SET_FCC_CHANNEL"), "%d", &enable);
+
+ if ((enable != CUSTOMER_HW4_ENABLE) && (enable != CUSTOMER_HW4_DISABLE)) {
+ ANDROID_ERROR(("%s: Invalid data\n", __FUNCTION__));
+ return BCME_ERROR;
+ }
+
+ CUSTOMER_HW4_EN_CONVERT(enable);
+
+ ANDROID_ERROR(("%s: fccpwrlimit2g set (%d)\n", __FUNCTION__, enable));
+ error = wldev_iovar_setint(dev, "fccpwrlimit2g", enable);
+ if (error) {
+ ANDROID_ERROR(("%s: fccpwrlimit2g set returned (%d)\n", __FUNCTION__, error));
+ return BCME_ERROR;
+ }
+
+ return error;
+}
+
+int
+wl_android_get_fcc_pwr_limit_2g(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int enable = 0;
+ int bytes_written = 0;
+
+ error = wldev_iovar_getint(dev, "fccpwrlimit2g", &enable);
+ if (error) {
+ ANDROID_ERROR(("%s: fccpwrlimit2g get error (%d)\n", __FUNCTION__, error));
+ return BCME_ERROR;
+ }
+ ANDROID_ERROR(("%s: fccpwrlimit2g get (%d)\n", __FUNCTION__, enable));
+
+ bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_FCC_PWR_LIMIT_2G, enable);
+
+ return bytes_written;
+}
+#endif /* FCC_PWR_LIMIT_2G */
+
+#ifdef IPV6_NDO_SUPPORT
+int
+wl_android_nd_ra_limit(struct net_device *dev, char *command, int total_len)
+{
+ int err = 0;
+ int bytes_written = 0;
+ uint tokens;
+ char *pos, *token, *delim;
+ char smbuf[WLC_IOCTL_SMLEN];
+ char param[ND_PARAM_SIZE+1], value[ND_VALUE_SIZE+1];
+ uint16 type = 0xff, min = 0, per = 0, hold = 0;
+ nd_ra_ol_limits_t ra_ol_limit;
+
+ WL_TRACE(("command=%s, len=%d\n", command, total_len));
+ pos = command + strlen(CMD_NDRA_LIMIT) + 1;
+ memset(&ra_ol_limit, 0, sizeof(nd_ra_ol_limits_t));
+
+ if (!strncmp(pos, ND_RA_OL_SET, strlen(ND_RA_OL_SET))) {
+ WL_TRACE(("SET NDRA_LIMIT\n"));
+ pos += strlen(ND_RA_OL_SET) + 1;
+ while ((token = strsep(&pos, ND_PARAMS_DELIMETER)) != NULL) {
+ memset(param, 0, sizeof(param));
+ memset(value, 0, sizeof(value));
+
+ delim = strchr(token, ND_PARAM_VALUE_DELLIMETER);
+ if (delim != NULL)
+ *delim = ' ';
+
+ tokens = sscanf(token, ND_LIMIT_STR_FMT, param, value);
+ if (!strncmp(param, ND_RA_TYPE, strlen(ND_RA_TYPE))) {
+ type = simple_strtol(value, NULL, 0);
+ } else if (!strncmp(param, ND_RA_MIN_TIME, strlen(ND_RA_MIN_TIME))) {
+ min = simple_strtol(value, NULL, 0);
+ } else if (!strncmp(param, ND_RA_PER, strlen(ND_RA_PER))) {
+ per = simple_strtol(value, NULL, 0);
+ if (per > 100) {
+ ANDROID_ERROR(("Invalid PERCENT %d\n", per));
+ err = BCME_BADARG;
+ goto exit;
+ }
+ } else if (!strncmp(param, ND_RA_HOLD, strlen(ND_RA_HOLD))) {
+ hold = simple_strtol(value, NULL, 0);
+ }
+ }
+
+ ra_ol_limit.version = htod32(ND_RA_OL_LIMITS_VER);
+ ra_ol_limit.type = htod32(type);
+ if (type == ND_RA_OL_LIMITS_REL_TYPE) {
+ if ((min == 0) || (per == 0)) {
+ ANDROID_ERROR(("Invalid min_time %d, percent %d\n", min, per));
+ err = BCME_BADARG;
+ goto exit;
+ }
+ ra_ol_limit.length = htod32(ND_RA_OL_LIMITS_REL_TYPE_LEN);
+ ra_ol_limit.limits.lifetime_relative.min_time = htod32(min);
+ ra_ol_limit.limits.lifetime_relative.lifetime_percent = htod32(per);
+ } else if (type == ND_RA_OL_LIMITS_FIXED_TYPE) {
+ if (hold == 0) {
+ ANDROID_ERROR(("Invalid hold_time %d\n", hold));
+ err = BCME_BADARG;
+ goto exit;
+ }
+ ra_ol_limit.length = htod32(ND_RA_OL_LIMITS_FIXED_TYPE_LEN);
+ ra_ol_limit.limits.fixed.hold_time = htod32(hold);
+ } else {
+ ANDROID_ERROR(("unknown TYPE %d\n", type));
+ err = BCME_BADARG;
+ goto exit;
+ }
+
+ err = wldev_iovar_setbuf(dev, "nd_ra_limit_intv", &ra_ol_limit,
+ sizeof(nd_ra_ol_limits_t), smbuf, sizeof(smbuf), NULL);
+ if (err) {
+ ANDROID_ERROR(("Failed to set nd_ra_limit_intv, error = %d\n", err));
+ goto exit;
+ }
+
+ WL_TRACE(("TYPE %d, MIN %d, PER %d, HOLD %d\n", type, min, per, hold));
+ } else if (!strncmp(pos, ND_RA_OL_GET, strlen(ND_RA_OL_GET))) {
+ WL_TRACE(("GET NDRA_LIMIT\n"));
+ err = wldev_iovar_getbuf(dev, "nd_ra_limit_intv", NULL, 0,
+ smbuf, sizeof(smbuf), NULL);
+ if (err) {
+ ANDROID_ERROR(("Failed to get nd_ra_limit_intv, error = %d\n", err));
+ goto exit;
+ }
+
+ memcpy(&ra_ol_limit, (uint8 *)smbuf, sizeof(nd_ra_ol_limits_t));
+ type = ra_ol_limit.type;
+ if (ra_ol_limit.version != ND_RA_OL_LIMITS_VER) {
+ ANDROID_ERROR(("Invalid Version %d\n", ra_ol_limit.version));
+ err = BCME_VERSION;
+ goto exit;
+ }
+
+ if (ra_ol_limit.type == ND_RA_OL_LIMITS_REL_TYPE) {
+ min = ra_ol_limit.limits.lifetime_relative.min_time;
+ per = ra_ol_limit.limits.lifetime_relative.lifetime_percent;
+ ANDROID_ERROR(("TYPE %d, MIN %d, PER %d\n", type, min, per));
+ bytes_written = snprintf(command, total_len,
+ "%s GET TYPE %d, MIN %d, PER %d", CMD_NDRA_LIMIT, type, min, per);
+ } else if (ra_ol_limit.type == ND_RA_OL_LIMITS_FIXED_TYPE) {
+ hold = ra_ol_limit.limits.fixed.hold_time;
+ ANDROID_ERROR(("TYPE %d, HOLD %d\n", type, hold));
+ bytes_written = snprintf(command, total_len,
+ "%s GET TYPE %d, HOLD %d", CMD_NDRA_LIMIT, type, hold);
+ } else {
+ ANDROID_ERROR(("unknown TYPE %d\n", type));
+ err = BCME_ERROR;
+ goto exit;
+ }
+
+ return bytes_written;
+ } else {
+ ANDROID_ERROR(("unknown command\n"));
+ err = BCME_ERROR;
+ goto exit;
+ }
+
+exit:
+ return err;
+}
+#endif /* IPV6_NDO_SUPPORT */
+#ifdef WLTDLS
+int wl_android_tdls_reset(struct net_device *dev)
+{
+ int ret = 0;
+ ret = dhd_tdls_enable(dev, false, false, NULL);
+ if (ret < 0) {
+ ANDROID_ERROR(("Disable tdls failed. %d\n", ret));
+ return ret;
+ }
+ ret = dhd_tdls_enable(dev, true, true, NULL);
+ if (ret < 0) {
+ ANDROID_ERROR(("enable tdls failed. %d\n", ret));
+ return ret;
+ }
+ return 0;
+}
+#endif /* WLTDLS */
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
+static int wl_android_wbtext(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0, argc = 0;
+ int data, bytes_written;
+
+ argc = sscanf(command+sizeof("WBTEXT_ENABLE"), "%d", &data);
+ if (!argc) {
+ error = wldev_iovar_getint(dev, "wnm_bsstrans_resp", &data);
+ if (error) {
+ ANDROID_ERROR(("%s: Failed to set wbtext error = %d\n",
+ __FUNCTION__, error));
+ }
+ bytes_written = snprintf(command, total_len, "WBTEXT %s\n",
+ (data == WL_BSSTRANS_POLICY_PRODUCT)? "ENABLED" : "DISABLED");
+ return bytes_written;
+ } else {
+ if (data)
+ data = WL_BSSTRANS_POLICY_PRODUCT;
+
+ error = wldev_iovar_setint(dev, "wnm_bsstrans_resp", data);
+ if (error) {
+ ANDROID_ERROR(("%s: Failed to set wbtext error = %d\n",
+ __FUNCTION__, error));
+ }
+ }
+ return error;
+}
#ifdef PNO_SUPPORT
#define PNO_PARAM_SIZE 50
ANDROID_ERROR(("failed to configure batch scan\n"));
} else {
memset(command, 0, total_len);
- err = sprintf(command, "%d", err);
+ err = snprintf(command, total_len, "%d", err);
}
} else if (!strncmp(pos, PNO_BATCHING_GET, strlen(PNO_BATCHING_GET))) {
err = dhd_dev_pno_get_for_batch(dev, command, total_len);
ANDROID_ERROR(("failed to stop batching scan\n"));
} else {
memset(command, 0, total_len);
- err = sprintf(command, "OK");
+ err = snprintf(command, total_len, "OK");
}
} else {
ANDROID_ERROR(("%s : unknown command\n", __FUNCTION__));
#ifndef WL_SCHED_SCAN
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];
+ wlc_ssid_ext_t ssids_local[MAX_PFN_LIST_COUNT];
int res = -1;
int nssid = 0;
cmd_tlv_t *cmd_tlv_temp;
return bytes_written;
}
-#ifdef BCMCCX
-static int wl_android_get_cckm_rn(struct net_device *dev, char *command)
-{
- int error, rn;
-
- ANDROID_TRACE(("%s:wl_android_get_cckm_rn\n", dev->name));
-
- error = wldev_iovar_getint(dev, "cckm_rn", &rn);
- if (unlikely(error)) {
- ANDROID_ERROR(("wl_android_get_cckm_rn error (%d)\n", error));
- return -1;
- }
- 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];
-
- ANDROID_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))
- {
- ANDROID_ERROR((" 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;
-
- ANDROID_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)) {
- ANDROID_ERROR(("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)) {
- ANDROID_ERROR(("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 */
int
wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *maclist)
int macmode = MACLIST_MODE_DISABLED;
struct maclist *list;
char eabuf[ETHER_ADDR_STR_LEN];
+ char *token;
/* string should look like below (macmode/macnum/maclist) */
/* 1 2 00:11:22:33:44:55 00:11:22:33:44:ff */
/* get the MAC filter mode */
- macmode = bcm_atoi(strsep((char**)&str, " "));
+ token = strsep((char**)&str, " ");
+ if (!token) {
+ return -1;
+ }
+ macmode = bcm_atoi(token);
if (macmode < MACLIST_MODE_DISABLED || macmode > MACLIST_MODE_ALLOW) {
ANDROID_ERROR(("%s : invalid macmode %d\n", __FUNCTION__, macmode));
return -1;
}
- macnum = bcm_atoi(strsep((char**)&str, " "));
+ token = strsep((char**)&str, " ");
+ if (!token) {
+ return -1;
+ }
+ macnum = bcm_atoi(token);
if (macnum < 0 || macnum > MAX_NUM_MAC_FILT) {
ANDROID_ERROR(("%s : invalid number of MAC address entries %d\n",
__FUNCTION__, macnum));
int wl_android_wifi_on(struct net_device *dev)
{
int ret = 0;
-#ifdef CONFIG_MACH_UNIVERSAL5433
- int retry;
- /* Do not retry old revision Helsinki Prime */
- if (!check_rev()) {
- retry = 1;
- } else {
- retry = POWERUP_MAX_RETRY;
- }
-#else
int retry = POWERUP_MAX_RETRY;
-#endif /* CONFIG_MACH_UNIVERSAL5433 */
if (!dev) {
ANDROID_ERROR(("%s: dev is null\n", __FUNCTION__));
#ifdef BCMPCIE
ret = dhd_net_bus_devreset(dev, FALSE);
#endif /* BCMPCIE */
- if (ret == 0)
+ if (ret == 0) {
break;
+ }
ANDROID_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n",
retry));
#ifdef BCMPCIE
#endif
}
-int wl_android_wifi_off(struct net_device *dev)
+int wl_android_wifi_off(struct net_device *dev, bool on_failure)
{
int ret = 0;
printf("%s in 1\n", __FUNCTION__);
dhd_net_if_lock(dev);
- printf("%s in 2: g_wifi_on=%d\n", __FUNCTION__, g_wifi_on);
- if (g_wifi_on) {
+ printf("%s in 2: g_wifi_on=%d, on_failure=%d\n", __FUNCTION__, g_wifi_on, on_failure);
+ if (g_wifi_on || on_failure) {
#if defined(BCMSDIO) || defined(BCMPCIE)
ret = dhd_net_bus_devreset(dev, TRUE);
#ifdef BCMSDIO
wl_android_get_connection_stats(struct net_device *dev, char *command, int total_len)
{
wl_cnt_t* cnt = NULL;
+#ifndef DISABLE_IF_COUNTERS
+ wl_if_stats_t* if_stats = NULL;
+#endif /* DISABLE_IF_COUNTERS */
+
int link_speed = 0;
struct connection_stats *output;
unsigned int bufsize = 0;
- int bytes_written = 0;
+ int bytes_written = -1;
int ret = 0;
ANDROID_INFO(("%s: enter Get Connection Stats\n", __FUNCTION__));
bufsize = total_len;
if (bufsize < sizeof(struct connection_stats)) {
- ANDROID_ERROR(("%s: not enough buffer size, provided=%u, requires=%u\n",
+ ANDROID_ERROR(("%s: not enough buffer size, provided=%u, requires=%zu\n",
__FUNCTION__, bufsize,
sizeof(struct connection_stats)));
goto error;
}
- if ((cnt = kmalloc(sizeof(*cnt), GFP_KERNEL)) == NULL) {
- ANDROID_ERROR(("kmalloc failed\n"));
- return -1;
+ output = (struct connection_stats *)command;
+
+#ifndef DISABLE_IF_COUNTERS
+ if ((if_stats = kmalloc(sizeof(*if_stats), GFP_KERNEL)) == NULL) {
+ ANDROID_ERROR(("%s(%d): kmalloc failed\n", __FUNCTION__, __LINE__));
+ goto error;
}
- memset(cnt, 0, sizeof(*cnt));
+ memset(if_stats, 0, sizeof(*if_stats));
- ret = wldev_iovar_getbuf(dev, "counters", NULL, 0, (char *)cnt, sizeof(wl_cnt_t), NULL);
+ ret = wldev_iovar_getbuf(dev, "if_counters", NULL, 0,
+ (char *)if_stats, sizeof(*if_stats), NULL);
if (ret) {
- ANDROID_ERROR(("%s: wldev_iovar_getbuf() failed, ret=%d\n",
+ ANDROID_ERROR(("%s: if_counters not supported ret=%d\n",
__FUNCTION__, ret));
+
+ /* In case if_stats IOVAR is not supported, get information from counters. */
+#endif /* DISABLE_IF_COUNTERS */
+ if ((cnt = kmalloc(sizeof(*cnt), GFP_KERNEL)) == NULL) {
+ ANDROID_ERROR(("%s(%d): kmalloc failed\n", __FUNCTION__, __LINE__));
+ goto error;
+ }
+ memset(cnt, 0, sizeof(*cnt));
+
+ ret = wldev_iovar_getbuf(dev, "counters", NULL, 0,
+ (char *)cnt, sizeof(wl_cnt_t), NULL);
+ if (ret) {
+ ANDROID_ERROR(("%s: wldev_iovar_getbuf() failed, ret=%d\n",
+ __FUNCTION__, ret));
+ goto error;
+ }
+
+ if (dtoh16(cnt->version) > WL_CNT_T_VERSION) {
+ ANDROID_ERROR(("%s: incorrect version of wl_cnt_t, expected=%u got=%u\n",
+ __FUNCTION__, WL_CNT_T_VERSION, cnt->version));
+ goto error;
+ }
+
+ output->txframe = dtoh32(cnt->txframe);
+ output->txbyte = dtoh32(cnt->txbyte);
+ output->txerror = dtoh32(cnt->txerror);
+ output->rxframe = dtoh32(cnt->rxframe);
+ output->rxbyte = dtoh32(cnt->rxbyte);
+ output->txfail = dtoh32(cnt->txfail);
+ output->txretry = dtoh32(cnt->txretry);
+ output->txretrie = dtoh32(cnt->txretrie);
+ output->txrts = dtoh32(cnt->txrts);
+ output->txnocts = dtoh32(cnt->txnocts);
+ output->txexptime = dtoh32(cnt->txexptime);
+#ifndef DISABLE_IF_COUNTERS
+ } else {
+ /* Populate from if_stats. */
+ if (dtoh16(if_stats->version) > WL_IF_STATS_T_VERSION) {
+ ANDROID_ERROR(("%s: incorrect version of wl_if_stats_t, expected=%u got=%u\n",
+ __FUNCTION__, WL_IF_STATS_T_VERSION, if_stats->version));
+ goto error;
+ }
+
+ output->txframe = (uint32)dtoh64(if_stats->txframe);
+ output->txbyte = (uint32)dtoh64(if_stats->txbyte);
+ output->txerror = (uint32)dtoh64(if_stats->txerror);
+ output->rxframe = (uint32)dtoh64(if_stats->rxframe);
+ output->rxbyte = (uint32)dtoh64(if_stats->rxbyte);
+ output->txfail = (uint32)dtoh64(if_stats->txfail);
+ output->txretry = (uint32)dtoh64(if_stats->txretry);
+ output->txretrie = (uint32)dtoh64(if_stats->txretrie);
+ /* Unavailable */
+ output->txrts = 0;
+ output->txnocts = 0;
+ output->txexptime = 0;
+ }
+#endif /* DISABLE_IF_COUNTERS */
+
+ /* link_speed is in kbps */
+ ret = wldev_get_link_speed(dev, &link_speed);
+ if (ret || link_speed < 0) {
+ ANDROID_ERROR(("%s: wldev_get_link_speed() failed, ret=%d, speed=%d\n",
+ __FUNCTION__, ret, link_speed));
goto error;
}
- if (dtoh16(cnt->version) > WL_CNT_T_VERSION) {
- ANDROID_ERROR(("%s: incorrect version of wl_cnt_t, expected=%u got=%u\n",
- __FUNCTION__, WL_CNT_T_VERSION, cnt->version));
- goto error;
+ output->txrate = link_speed;
+
+ /* Channel idle ratio. */
+ if (wl_chanim_stats(dev, &(output->chan_idle)) < 0) {
+ output->chan_idle = 0;
+ };
+
+ bytes_written = sizeof(struct connection_stats);
+
+error:
+#ifndef DISABLE_IF_COUNTERS
+ if (if_stats) {
+ kfree(if_stats);
+ }
+#endif /* DISABLE_IF_COUNTERS */
+ if (cnt) {
+ kfree(cnt);
+ }
+
+ return bytes_written;
+}
+#endif /* CONNECTION_STATISTICS */
+
+
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
+
+/* SoftAP feature */
+#define APCS_BAND_2G_LEGACY1 20
+#define APCS_BAND_2G_LEGACY2 0
+#define APCS_BAND_AUTO "band=auto"
+#define APCS_BAND_2G "band=2g"
+#define APCS_BAND_5G "band=5g"
+#define APCS_MAX_2G_CHANNELS 11
+#define APCS_MAX_RETRY 10
+#define APCS_DEFAULT_2G_CH 1
+#define APCS_DEFAULT_5G_CH 149
+#if defined(WL_SUPPORT_AUTO_CHANNEL)
+static int
+wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
+ char* command, int total_len)
+{
+ int channel = 0;
+ int chosen = 0;
+ int retry = 0;
+ int ret = 0;
+ int spect = 0;
+ u8 *reqbuf = NULL;
+ uint32 band = WLC_BAND_2G;
+ uint32 buf_size;
+
+ if (cmd_str) {
+ ANDROID_INFO(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str)));
+ if (strncmp(cmd_str, APCS_BAND_AUTO, strlen(APCS_BAND_AUTO)) == 0) {
+ band = WLC_BAND_AUTO;
+ } else if (strncmp(cmd_str, APCS_BAND_5G, strlen(APCS_BAND_5G)) == 0) {
+ band = WLC_BAND_5G;
+ } else if (strncmp(cmd_str, APCS_BAND_2G, strlen(APCS_BAND_2G)) == 0) {
+ band = WLC_BAND_2G;
+ } else {
+ /*
+ * For backward compatibility: Some platforms used to issue argument 20 or 0
+ * to enforce the 2G channel selection
+ */
+ channel = bcm_atoi(cmd_str);
+ if ((channel == APCS_BAND_2G_LEGACY1) ||
+ (channel == APCS_BAND_2G_LEGACY2)) {
+ band = WLC_BAND_2G;
+ } else {
+ ANDROID_ERROR(("Invalid argument\n"));
+ return -EINVAL;
+ }
+ }
+ } else {
+ /* If no argument is provided, default to 2G */
+ ANDROID_ERROR(("No argument given default to 2.4G scan\n"));
+ band = WLC_BAND_2G;
+ }
+ ANDROID_INFO(("HAPD_AUTO_CHANNEL = %d, band=%d \n", channel, band));
+
+ if ((ret = wldev_ioctl(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect), false)) < 0) {
+ ANDROID_ERROR(("ACS: error getting the spect\n"));
+ goto done;
+ }
+
+ if (spect > 0) {
+ /* If STA is connected, return is STA channel, else ACS can be issued,
+ * set spect to 0 and proceed with ACS
+ */
+ channel = wl_cfg80211_get_sta_channel();
+ if (channel) {
+ channel = (channel <= CH_MAX_2G_CHANNEL) ? channel : APCS_DEFAULT_2G_CH;
+ goto done2;
+ }
+
+ if ((ret = wl_cfg80211_set_spect(dev, 0) < 0)) {
+ ANDROID_ERROR(("ACS: error while setting spect\n"));
+ goto done;
+ }
+ }
+
+ reqbuf = kzalloc(CHANSPEC_BUF_SIZE, GFP_KERNEL);
+ if (reqbuf == NULL) {
+ ANDROID_ERROR(("failed to allocate chanspec buffer\n"));
+ return -ENOMEM;
+ }
+
+ if (band == WLC_BAND_AUTO) {
+ ANDROID_INFO(("ACS full channel scan \n"));
+ reqbuf[0] = htod32(0);
+ } else if (band == WLC_BAND_5G) {
+ ANDROID_INFO(("ACS 5G band scan \n"));
+ if ((ret = wl_cfg80211_get_chanspecs_5g(dev, reqbuf, CHANSPEC_BUF_SIZE)) < 0) {
+ ANDROID_ERROR(("ACS 5g chanspec retreival failed! \n"));
+ goto done;
+ }
+ } else if (band == WLC_BAND_2G) {
+ /*
+ * If channel argument is not provided/ argument 20 is provided,
+ * Restrict channel to 2GHz, 20MHz BW, No SB
+ */
+ ANDROID_INFO(("ACS 2G band scan \n"));
+ if ((ret = wl_cfg80211_get_chanspecs_2g(dev, reqbuf, CHANSPEC_BUF_SIZE)) < 0) {
+ ANDROID_ERROR(("ACS 2g chanspec retreival failed! \n"));
+ goto done;
+ }
+ } else {
+ ANDROID_ERROR(("ACS: No band chosen\n"));
+ goto done2;
+ }
+
+ buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE;
+ ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf,
+ buf_size, true);
+ if (ret < 0) {
+ ANDROID_ERROR(("can't start auto channel scan, err = %d\n", ret));
+ channel = 0;
+ goto done;
+ }
+
+ /* Wait for auto channel selection, max 3000 ms */
+ if ((band == WLC_BAND_2G) || (band == WLC_BAND_5G)) {
+ OSL_SLEEP(500);
+ } else {
+ /*
+ * Full channel scan at the minimum takes 1.2secs
+ * even with parallel scan. max wait time: 3500ms
+ */
+ OSL_SLEEP(1000);
+ }
+
+ retry = APCS_MAX_RETRY;
+ while (retry--) {
+ ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen,
+ sizeof(chosen), false);
+ if (ret < 0) {
+ chosen = 0;
+ } else {
+ chosen = dtoh32(chosen);
+ }
+
+ if (chosen) {
+ int chosen_band;
+ int apcs_band;
+#ifdef D11AC_IOTYPES
+ if (wl_cfg80211_get_ioctl_version() == 1) {
+ channel = LCHSPEC_CHANNEL((chanspec_t)chosen);
+ } else {
+ channel = CHSPEC_CHANNEL((chanspec_t)chosen);
+ }
+#else
+ channel = CHSPEC_CHANNEL((chanspec_t)chosen);
+#endif /* D11AC_IOTYPES */
+ apcs_band = (band == WLC_BAND_AUTO) ? WLC_BAND_2G : band;
+ chosen_band = (channel <= CH_MAX_2G_CHANNEL) ? WLC_BAND_2G : WLC_BAND_5G;
+ if (apcs_band == chosen_band) {
+ ANDROID_ERROR(("selected channel = %d\n", channel));
+ break;
+ }
+ }
+ ANDROID_INFO(("%d tried, ret = %d, chosen = 0x%x\n",
+ (APCS_MAX_RETRY - retry), ret, chosen));
+ OSL_SLEEP(250);
+ }
+
+done:
+ if ((retry == 0) || (ret < 0)) {
+ /* On failure, fallback to a default channel */
+ if ((band == WLC_BAND_5G)) {
+ channel = APCS_DEFAULT_5G_CH;
+ } else {
+ channel = APCS_DEFAULT_2G_CH;
+ }
+ ANDROID_ERROR(("ACS failed. Fall back to default channel (%d) \n", channel));
+ }
+done2:
+ if (spect > 0) {
+ if ((ret = wl_cfg80211_set_spect(dev, spect) < 0)) {
+ ANDROID_ERROR(("ACS: error while setting spect\n"));
+ }
+ }
+
+ if (reqbuf) {
+ kfree(reqbuf);
+ }
+
+ if (channel) {
+ snprintf(command, 4, "%d", channel);
+ ANDROID_INFO(("command result is %s \n", command));
+ return strlen(command);
+ } else {
+ return ret;
+ }
+}
+#endif /* WL_SUPPORT_AUTO_CHANNEL */
+
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+
+
+#ifdef SUPPORT_SET_LPC
+static int
+wl_android_set_lpc(struct net_device *dev, const char* string_num)
+{
+ int lpc_enabled, ret;
+ s32 val = 1;
+
+ lpc_enabled = bcm_atoi(string_num);
+ ANDROID_INFO(("%s : HAPD_LPC_ENABLED = %d\n", __FUNCTION__, lpc_enabled));
+
+ ret = wldev_ioctl(dev, WLC_DOWN, &val, sizeof(s32), true);
+ if (ret < 0)
+ ANDROID_ERROR(("WLC_DOWN error %d\n", ret));
+
+ wldev_iovar_setint(dev, "lpc", lpc_enabled);
+
+ ret = wldev_ioctl(dev, WLC_UP, &val, sizeof(s32), true);
+ if (ret < 0)
+ ANDROID_ERROR(("WLC_UP error %d\n", ret));
+
+ return 1;
+}
+#endif /* SUPPORT_SET_LPC */
+
+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) {
+ ANDROID_ERROR(("Failed to set SRL, error = %d\n", error));
+ }
+ error = wldev_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(s32), true);
+ if (error) {
+ ANDROID_ERROR(("Failed to set LRL, error = %d\n", error));
+ }
+ return error;
+}
+
+
+static int
+wl_android_rmc_enable(struct net_device *net, int rmc_enable)
+{
+ int err;
+
+ err = wldev_iovar_setint(net, "rmc_ackreq", rmc_enable);
+ return err;
+}
+
+static int
+wl_android_rmc_set_leader(struct net_device *dev, const char* straddr)
+{
+ int error = BCME_OK;
+ char smbuf[WLC_IOCTL_SMLEN];
+ wl_rmc_entry_t rmc_entry;
+ ANDROID_INFO(("%s: Set new RMC leader %s\n", __FUNCTION__, straddr));
+
+ memset(&rmc_entry, 0, sizeof(wl_rmc_entry_t));
+ if (!bcm_ether_atoe(straddr, &rmc_entry.addr)) {
+ if (strlen(straddr) == 1 && bcm_atoi(straddr) == 0) {
+ ANDROID_INFO(("%s: Set auto leader selection mode\n", __FUNCTION__));
+ memset(&rmc_entry, 0, sizeof(wl_rmc_entry_t));
+ } else {
+ ANDROID_ERROR(("%s: No valid mac address provided\n",
+ __FUNCTION__));
+ return BCME_ERROR;
+ }
+ }
+
+ error = wldev_iovar_setbuf(dev, "rmc_ar", &rmc_entry, sizeof(wl_rmc_entry_t),
+ smbuf, sizeof(smbuf), NULL);
+
+ if (error != BCME_OK) {
+ ANDROID_ERROR(("%s: Unable to set RMC leader, error = %d\n",
+ __FUNCTION__, error));
+ }
+
+ return error;
+}
+
+static int wl_android_set_rmc_event(struct net_device *dev, char *command, int total_len)
+{
+ int err = 0;
+ int pid = 0;
+
+ if (sscanf(command, CMD_SET_RMC_EVENT " %d", &pid) <= 0) {
+ ANDROID_ERROR(("Failed to get Parameter from : %s\n", command));
+ return -1;
+ }
+
+ /* set pid, and if the event was happened, let's send a notification through netlink */
+ wl_cfg80211_set_rmc_pid(pid);
+
+ ANDROID_TRACE(("RMC pid=%d\n", pid));
+
+ return err;
+}
+
+int wl_android_get_singlecore_scan(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int bytes_written = 0;
+ int mode = 0;
+
+ error = wldev_iovar_getint(dev, "scan_ps", &mode);
+ if (error) {
+ ANDROID_ERROR(("%s: Failed to get single core scan Mode, error = %d\n",
+ __FUNCTION__, error));
+ return -1;
+ }
+
+ bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_SCSCAN, mode);
+
+ return bytes_written;
+}
+
+int wl_android_set_singlecore_scan(struct net_device *dev, char *command, int total_len)
+{
+ int error = 0;
+ int mode = 0;
+
+ if (sscanf(command, "%*s %d", &mode) != 1) {
+ ANDROID_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
+ return -1;
}
- /* link_speed is in kbps */
- ret = wldev_get_link_speed(dev, &link_speed);
- if (ret || link_speed < 0) {
- ANDROID_ERROR(("%s: wldev_get_link_speed() failed, ret=%d, speed=%d\n",
- __FUNCTION__, ret, link_speed));
- goto error;
+ error = wldev_iovar_setint(dev, "scan_ps", mode);
+ if (error) {
+ ANDROID_ERROR(("%s[1]: Failed to set Mode %d, error = %d\n",
+ __FUNCTION__, mode, error));
+ return -1;
}
- output = (struct connection_stats *)command;
- output->txframe = dtoh32(cnt->txframe);
- output->txbyte = dtoh32(cnt->txbyte);
- output->txerror = dtoh32(cnt->txerror);
- output->rxframe = dtoh32(cnt->rxframe);
- output->rxbyte = dtoh32(cnt->rxbyte);
- output->txfail = dtoh32(cnt->txfail);
- output->txretry = dtoh32(cnt->txretry);
- output->txretrie = dtoh32(cnt->txretrie);
- output->txrts = dtoh32(cnt->txrts);
- output->txnocts = dtoh32(cnt->txnocts);
- output->txexptime = dtoh32(cnt->txexptime);
- output->txrate = link_speed;
+ return error;
+}
+#ifdef TEST_TX_POWER_CONTROL
+static int
+wl_android_set_tx_power(struct net_device *dev, const char* string_num)
+{
+ int err = 0;
+ s32 dbm;
+ enum nl80211_tx_power_setting type;
- /* Channel idle ratio. */
- if (wl_chanim_stats(dev, &(output->chan_idle)) < 0) {
- output->chan_idle = 0;
- };
+ dbm = bcm_atoi(string_num);
- kfree(cnt);
+ if (dbm < -1) {
+ ANDROID_ERROR(("%s: dbm is negative...\n", __FUNCTION__));
+ return -EINVAL;
+ }
- bytes_written = sizeof(struct connection_stats);
- return bytes_written;
+ if (dbm == -1)
+ type = NL80211_TX_POWER_AUTOMATIC;
+ else
+ type = NL80211_TX_POWER_FIXED;
-error:
- if (cnt) {
- kfree(cnt);
+ err = wl_set_tx_power(dev, type, dbm);
+ if (unlikely(err)) {
+ ANDROID_ERROR(("%s: error (%d)\n", __FUNCTION__, err));
+ return err;
}
- return -1;
+
+ return 1;
}
-#endif /* CONNECTION_STATISTICS */
static int
-wl_android_set_pmk(struct net_device *dev, char *command, int total_len)
+wl_android_get_tx_power(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
+ int err;
+ int bytes_written;
+ s32 dbm = 0;
- 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) {
- ANDROID_ERROR(("Failed to set PMK for OKC, error = %d\n", error));
+ err = wl_get_tx_power(dev, &dbm);
+ if (unlikely(err)) {
+ ANDROID_ERROR(("%s: error (%d)\n", __FUNCTION__, err));
+ return err;
}
-#ifdef OKC_DEBUG
- ANDROID_ERROR(("PMK is "));
- for (i = 0; i < 32; i++)
- ANDROID_ERROR(("%02X ", pmk[i]));
- ANDROID_ERROR(("\n"));
-#endif
- return error;
+ bytes_written = snprintf(command, total_len, "%s %d",
+ CMD_TEST_GET_TX_POWER, dbm);
+
+ ANDROID_ERROR(("%s: GET_TX_POWER: dBm=%d\n", __FUNCTION__, dbm));
+
+ return bytes_written;
}
+#endif /* TEST_TX_POWER_CONTROL */
static int
-wl_android_okc_enable(struct net_device *dev, char *command, int total_len)
+wl_android_set_sarlimit_txctrl(struct net_device *dev, const char* string_num)
{
- int error = 0;
- char okc_enable = 0;
+ int err = 0;
+ int setval = 0;
+ s32 mode = bcm_atoi(string_num);
- okc_enable = command[strlen(CMD_OKC_ENABLE) + 1] - '0';
- error = wldev_iovar_setint(dev, "okc_enable", okc_enable);
- if (error) {
- ANDROID_ERROR(("Failed to %s OKC, error = %d\n",
- okc_enable ? "enable" : "disable", error));
+ /* As Samsung specific and their requirement, '0' means activate sarlimit
+ * and '-1' means back to normal state (deactivate sarlimit)
+ */
+ if (mode == 0) {
+ ANDROID_INFO(("%s: SAR limit control activated\n", __FUNCTION__));
+ setval = 1;
+ } else if (mode == -1) {
+ ANDROID_INFO(("%s: SAR limit control deactivated\n", __FUNCTION__));
+ setval = 0;
+ } else {
+ return -EINVAL;
}
- wldev_iovar_setint(dev, "ccx_enable", 0);
-
- return error;
+ err = wldev_iovar_setint(dev, "sar_enable", setval);
+ if (unlikely(err)) {
+ ANDROID_ERROR(("%s: error (%d)\n", __FUNCTION__, err));
+ return err;
+ }
+ return 1;
}
-
-
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
int wl_android_set_roam_mode(struct net_device *dev, char *command, int total_len)
{
kfree(config);
}
}
+#ifdef WL11ULB
+static int
+wl_android_set_ulb_mode(struct net_device *dev, char *command, int total_len)
+{
+ int mode = 0;
+
+ ANDROID_INFO(("set ulb mode (%s) \n", command));
+ if (sscanf(command, "%*s %d", &mode) != 1) {
+ ANDROID_ERROR(("%s: Failed to get Parameter\n", __FUNCTION__));
+ return -1;
+ }
+ return wl_cfg80211_set_ulb_mode(dev, mode);
+}
+static int
+wl_android_set_ulb_bw(struct net_device *dev, char *command, int total_len)
+{
+ int bw = 0;
+ u8 *pos;
+ char *ifname = NULL;
+ ANDROID_INFO(("set ulb bw (%s) \n", command));
+
+ /*
+ * For sta/ap: IFNAME=<ifname> DRIVER ULB_BW <bw> ifname
+ * For p2p: IFNAME=wlan0 DRIVER ULB_BW <bw> p2p-dev-wlan0
+ */
+ if (total_len < strlen(CMD_ULB_BW) + 2)
+ return -EINVAL;
+
+ pos = command + strlen(CMD_ULB_BW) + 1;
+ bw = bcm_atoi(pos);
+
+ if ((strlen(pos) >= 5)) {
+ ifname = pos + 2;
+ }
+ ANDROID_INFO(("[ULB] ifname:%s ulb_bw:%d \n", ifname, bw));
+ return wl_cfg80211_set_ulb_bw(dev, bw, ifname);
+}
+#endif /* WL11ULB */
static int
wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
{
ANDROID_INFO(("%s: enter miracast mode %d\n", __FUNCTION__, mode));
- if (miracast_cur_mode == mode)
+ if (miracast_cur_mode == mode) {
return 0;
+ }
wl_android_iolist_resume(dev, &miracast_resume_list);
miracast_cur_mode = MIRACAST_MODE_OFF;
ANDROID_ERROR(("%s: Connected station's beacon interval: "
"%d and set mchan_algo to %d \n",
__FUNCTION__, val, config.param));
- }
- else {
+ } else {
config.param = MIRACAST_MCHAN_ALGO;
}
ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret)
+ if (ret) {
goto resume;
+ }
/* setting mchan_bw to platform specific value */
config.iovar = "mchan_bw";
config.param = MIRACAST_MCHAN_BW;
ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret)
+ if (ret) {
goto resume;
+ }
/* setting apmdu to platform specific value */
config.iovar = "ampdu_mpdu";
config.param = MIRACAST_AMPDU_SIZE;
ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret)
+ if (ret) {
goto resume;
+ }
/* FALLTROUGH */
/* Source mode shares most configurations with sink mode.
* Fall through here to avoid code duplication
config.iovar = "roam_off";
config.param = 1;
ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret)
+ if (ret) {
goto resume;
+ }
+
/* tunr off pm */
- val = 0;
- config.iovar = NULL;
- config.ioctl = WLC_GET_PM;
- config.arg = &val;
- config.len = sizeof(int);
- ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
- if (ret)
+ ret = wldev_ioctl(dev, WLC_GET_PM, &val, sizeof(val), false);
+ if (ret) {
goto resume;
+ }
+ if (val != PM_OFF) {
+ val = PM_OFF;
+ config.iovar = NULL;
+ config.ioctl = WLC_GET_PM;
+ config.arg = &val;
+ config.len = sizeof(int);
+ ret = wl_android_iolist_add(dev, &miracast_resume_list, &config);
+ if (ret) {
+ goto resume;
+ }
+ }
break;
case MIRACAST_MODE_OFF:
default:
return ret;
}
-#ifdef WLAIBSS
-static int wl_android_set_ibss_txfail_event(struct net_device *dev, char *command, int total_len)
-{
- int err = 0;
- int retry = 0;
- int pid = 0;
- aibss_txfail_config_t txfail_config = {0, 0, 0, 0};
- char smbuf[WLC_IOCTL_SMLEN];
-
- if (sscanf(command, CMD_SETIBSSTXFAILEVENT " %d %d", &retry, &pid) <= 0) {
- ANDROID_ERROR(("Failed to get Parameter from : %s\n", command));
- return -1;
- }
-
- /* set pid, and if the event was happened, let's send a notification through netlink */
- wl_cfg80211_set_txfail_pid(pid);
-
- /* If retry value is 0, it disables the functionality for TX Fail. */
- if (retry > 0) {
- txfail_config.max_tx_retry = retry;
- txfail_config.bcn_timeout = 0; /* 0 : disable tx fail from beacon */
- }
- txfail_config.version = AIBSS_TXFAIL_CONFIG_VER_0;
- txfail_config.len = sizeof(txfail_config);
-
- err = wldev_iovar_setbuf(dev, "aibss_txfail_config", (void *) &txfail_config,
- sizeof(aibss_txfail_config_t), smbuf, WLC_IOCTL_SMLEN, NULL);
- ANDROID_TRACE(("retry=%d, pid=%d, err=%d\n", retry, pid, err));
-
- return ((err == 0)?total_len:err);
-}
-
-static int wl_android_get_ibss_peer_info(struct net_device *dev, char *command,
- int total_len, bool bAll)
-{
- int error;
- int bytes_written = 0;
- void *buf = NULL;
- bss_peer_list_info_t peer_list_info;
- bss_peer_info_t *peer_info;
- int i;
- bool found = false;
- struct ether_addr mac_ea;
-
- ANDROID_TRACE(("get ibss peer info(%s)\n", bAll?"true":"false"));
-
- if (!bAll) {
- if (sscanf (command, "GETIBSSPEERINFO %02x:%02x:%02x:%02x:%02x:%02x",
- (unsigned int *)&mac_ea.octet[0], (unsigned int *)&mac_ea.octet[1],
- (unsigned int *)&mac_ea.octet[2], (unsigned int *)&mac_ea.octet[3],
- (unsigned int *)&mac_ea.octet[4], (unsigned int *)&mac_ea.octet[5]) != 6) {
- ANDROID_TRACE(("invalid MAC address\n"));
- return -1;
- }
- }
-
- if ((buf = kmalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL)) == NULL) {
- ANDROID_ERROR(("kmalloc failed\n"));
- return -1;
- }
-
- error = wldev_iovar_getbuf(dev, "bss_peer_info", NULL, 0, buf, WLC_IOCTL_MAXLEN, NULL);
- if (unlikely(error)) {
- ANDROID_ERROR(("could not get ibss peer info (%d)\n", error));
- kfree(buf);
- return -1;
- }
-
- memcpy(&peer_list_info, buf, sizeof(peer_list_info));
- peer_list_info.version = htod16(peer_list_info.version);
- peer_list_info.bss_peer_info_len = htod16(peer_list_info.bss_peer_info_len);
- peer_list_info.count = htod32(peer_list_info.count);
-
- ANDROID_TRACE(("ver:%d, len:%d, count:%d\n", peer_list_info.version,
- peer_list_info.bss_peer_info_len, peer_list_info.count));
-
- if (peer_list_info.count > 0) {
- if (bAll)
- bytes_written += sprintf(&command[bytes_written], "%u ",
- peer_list_info.count);
-
- peer_info = (bss_peer_info_t *) ((void *)buf + BSS_PEER_LIST_INFO_FIXED_LEN);
-
-
- for (i = 0; i < peer_list_info.count; i++) {
-
- ANDROID_TRACE(("index:%d rssi:%d, tx:%u, rx:%u\n", i, peer_info->rssi,
- peer_info->tx_rate, peer_info->rx_rate));
-
- if (!bAll &&
- memcmp(&mac_ea, &peer_info->ea, sizeof(struct ether_addr)) == 0) {
- found = true;
- }
-
- if (bAll || found) {
- bytes_written += sprintf(&command[bytes_written], MACF,
- ETHER_TO_MACF(peer_info->ea));
- bytes_written += sprintf(&command[bytes_written], " %u %d ",
- peer_info->tx_rate/1000, peer_info->rssi);
- }
-
- if (found)
- break;
-
- peer_info = (bss_peer_info_t *)((void *)peer_info+sizeof(bss_peer_info_t));
- }
- }
- else {
- ANDROID_ERROR(("could not get ibss peer info : no item\n"));
- }
- bytes_written += sprintf(&command[bytes_written], "%s", "\0");
-
- ANDROID_TRACE(("command(%u):%s\n", total_len, command));
- ANDROID_TRACE(("bytes_written:%d\n", bytes_written));
-
- kfree(buf);
- return bytes_written;
-}
-
-int wl_android_set_ibss_routetable(struct net_device *dev, char *command, int total_len)
-{
-
- char *pcmd = command;
- char *str = NULL;
-
- ibss_route_tbl_t *route_tbl = NULL;
- char *ioctl_buf = NULL;
- u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
- s32 err = BCME_OK;
- uint32 route_tbl_len;
- uint32 entries;
- char *endptr;
- uint32 i = 0;
- struct ipv4_addr dipaddr;
- struct ether_addr ea;
-
- route_tbl_len = sizeof(ibss_route_tbl_t) +
- (MAX_IBSS_ROUTE_TBL_ENTRY - 1) * sizeof(ibss_route_entry_t);
- route_tbl = (ibss_route_tbl_t *)kzalloc(route_tbl_len, kflags);
- if (!route_tbl) {
- ANDROID_ERROR(("Route TBL alloc failed\n"));
- return -ENOMEM;
- }
- ioctl_buf = kzalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
- if (!ioctl_buf) {
- ANDROID_ERROR(("ioctl memory alloc failed\n"));
- if (route_tbl) {
- kfree(route_tbl);
- }
- return -ENOMEM;
- }
- memset(ioctl_buf, 0, WLC_IOCTL_MEDLEN);
-
- /* drop command */
- str = bcmstrtok(&pcmd, " ", NULL);
-
- /* get count */
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- ANDROID_ERROR(("Invalid number parameter %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- entries = bcm_strtoul(str, &endptr, 0);
- if (*endptr != '\0') {
- ANDROID_ERROR(("Invalid number parameter %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- ANDROID_INFO(("Routing table count:%d\n", entries));
- route_tbl->num_entry = entries;
-
- for (i = 0; i < entries; i++) {
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str || !bcm_atoipv4(str, &dipaddr)) {
- ANDROID_ERROR(("Invalid ip string %s\n", str));
- err = -EINVAL;
- goto exit;
- }
-
-
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str || !bcm_ether_atoe(str, &ea)) {
- ANDROID_ERROR(("Invalid ethernet string %s\n", str));
- err = -EINVAL;
- goto exit;
- }
- bcopy(&dipaddr, &route_tbl->route_entry[i].ipv4_addr, IPV4_ADDR_LEN);
- bcopy(&ea, &route_tbl->route_entry[i].nexthop, ETHER_ADDR_LEN);
- }
-
- route_tbl_len = sizeof(ibss_route_tbl_t) +
- ((!entries?0:(entries - 1)) * sizeof(ibss_route_entry_t));
- err = wldev_iovar_setbuf(dev, "ibss_route_tbl",
- route_tbl, route_tbl_len, ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
- if (err != BCME_OK) {
- ANDROID_ERROR(("Fail to set iovar %d\n", err));
- err = -EINVAL;
- }
-
-exit:
- if (route_tbl)
- kfree(route_tbl);
- if (ioctl_buf)
- kfree(ioctl_buf);
- return err;
-
-}
-
-int
-wl_android_set_ibss_ampdu(struct net_device *dev, char *command, int total_len)
-{
- char *pcmd = command;
- char *str = NULL, *endptr = NULL;
- struct ampdu_aggr aggr;
- char smbuf[WLC_IOCTL_SMLEN];
- int idx;
- int err = 0;
- int wme_AC2PRIO[AC_COUNT][2] = {
- {PRIO_8021D_VO, PRIO_8021D_NC}, /* AC_VO - 3 */
- {PRIO_8021D_CL, PRIO_8021D_VI}, /* AC_VI - 2 */
- {PRIO_8021D_BK, PRIO_8021D_NONE}, /* AC_BK - 1 */
- {PRIO_8021D_BE, PRIO_8021D_EE}}; /* AC_BE - 0 */
-
- ANDROID_TRACE(("set ibss ampdu:%s\n", command));
-
- memset(&aggr, 0, sizeof(aggr));
- /* Cofigure all priorities */
- aggr.conf_TID_bmap = NBITMASK(NUMPRIO);
-
- /* acquire parameters */
- /* drop command */
- str = bcmstrtok(&pcmd, " ", NULL);
-
- for (idx = 0; idx < AC_COUNT; idx++) {
- bool on;
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- ANDROID_ERROR(("Invalid parameter : %s\n", pcmd));
- return -EINVAL;
- }
- on = bcm_strtoul(str, &endptr, 0) ? TRUE : FALSE;
- if (*endptr != '\0') {
- ANDROID_ERROR(("Invalid number format %s\n", str));
- return -EINVAL;
- }
- if (on) {
- setbit(&aggr.enab_TID_bmap, wme_AC2PRIO[idx][0]);
- setbit(&aggr.enab_TID_bmap, wme_AC2PRIO[idx][1]);
- }
- }
-
- err = wldev_iovar_setbuf(dev, "ampdu_txaggr", (void *)&aggr,
- sizeof(aggr), smbuf, WLC_IOCTL_SMLEN, NULL);
-
- return ((err == 0) ? total_len : err);
-}
-
-int wl_android_set_ibss_antenna(struct net_device *dev, char *command, int total_len)
-{
- char *pcmd = command;
- char *str = NULL;
- int txchain, rxchain;
- int err = 0;
-
- ANDROID_TRACE(("set ibss antenna:%s\n", command));
-
- /* acquire parameters */
- /* drop command */
- str = bcmstrtok(&pcmd, " ", NULL);
-
- /* TX chain */
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- ANDROID_ERROR(("Invalid parameter : %s\n", pcmd));
- return -EINVAL;
- }
- txchain = bcm_atoi(str);
-
- /* RX chain */
- str = bcmstrtok(&pcmd, " ", NULL);
- if (!str) {
- ANDROID_ERROR(("Invalid parameter : %s\n", pcmd));
- return -EINVAL;
- }
- rxchain = bcm_atoi(str);
-
- err = wldev_iovar_setint(dev, "txchain", txchain);
- if (err != 0)
- return err;
- err = wldev_iovar_setint(dev, "rxchain", rxchain);
- return ((err == 0)?total_len:err);
-}
-#endif /* WLAIBSS */
int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len)
{
return res;
}
-
static const char *
get_string_by_separator(char *result, int result_len, const char *src, char separator)
{
*result++ = *src++;
}
*result = 0;
- if (*src == separator)
+ if (*src == separator) {
++src;
+ }
return src;
}
+#ifdef WL_CFG80211
int
wl_android_set_roam_offload_bssid_list(struct net_device *dev, const char *cmd)
{
roamoffl_bssid_list_t *bssid_list;
const char *str = cmd;
char *ioctl_buf;
+ dhd_pub_t *dhdp = wl_cfg80211_get_dhdp();
str = get_string_by_separator(sbuf, 32, str, ',');
cnt = bcm_atoi(sbuf);
cnt = MIN(cnt, MAX_ROAMOFFL_BSSID_NUM);
- size = sizeof(int) + sizeof(struct ether_addr) * cnt;
+
+ if ((cnt > 0) &&
+ (((dhdp->op_mode & DHD_FLAG_STA_MODE) && (dhdp->op_mode & DHD_FLAG_HOSTAP_MODE)) ||
+ FALSE)) {
+ ANDROID_ERROR(("Can't set ROAMOFFL_BSSID when enabled STA-SoftAP or WES\n"));
+ return -EINVAL;
+ }
+
+ size = sizeof(int32) + sizeof(struct ether_addr) * cnt;
ANDROID_ERROR(("ROAM OFFLOAD BSSID LIST %d BSSIDs, size %d\n", cnt, size));
bssid_list = kmalloc(size, GFP_KERNEL);
if (bssid_list == NULL) {
for (i = 0; i < cnt; i++) {
str = get_string_by_separator(sbuf, 32, str, ',');
- if (bcm_ether_atoe(sbuf, &bssid_list->bssid[i]) == 0) {
- ANDROID_ERROR(("%s: Invalid station MAC Address!!!\n", __FUNCTION__));
- kfree(bssid_list);
- kfree(ioctl_buf);
- return -1;
- }
+ bcm_ether_atoe(sbuf, &bssid_list->bssid[i]);
}
- bssid_list->cnt = cnt;
+ bssid_list->cnt = (int32)cnt;
err = wldev_iovar_setbuf(dev, "roamoffl_bssid_list",
- bssid_list, size, ioctl_buf, ioctl_buf_len, NULL);
+ bssid_list, size, ioctl_buf, ioctl_buf_len, NULL);
kfree(bssid_list);
kfree(ioctl_buf);
return err;
}
+#endif
#ifdef P2PRESP_WFDIE_SRC
static int wl_android_get_wfdie_resp(struct net_device *dev, char *command, int total_len)
}
#endif /* P2PRESP_WFDIE_SRC */
-static int wl_android_get_link_status(struct net_device *dev, char *command,
- int total_len)
-{
- int bytes_written, error, result = 0, single_stream, stf = -1, i, nss = 0, mcs_map;
- uint32 rspec;
- uint encode, rate, txexp;
- struct wl_bss_info *bi;
- int datalen = sizeof(uint32) + sizeof(wl_bss_info_t);
- char buf[datalen];
-
- /* get BSS information */
- *(u32 *) buf = htod32(datalen);
- error = wldev_ioctl(dev, WLC_GET_BSS_INFO, (void *)buf, datalen, false);
- if (unlikely(error)) {
- ANDROID_ERROR(("Could not get bss info %d\n", error));
- return -1;
- }
-
- bi = (struct wl_bss_info *) (buf + sizeof(uint32));
-
- for (i = 0; i < ETHER_ADDR_LEN; i++) {
- if (bi->BSSID.octet[i] > 0) {
- break;
- }
- }
-
- if (i == ETHER_ADDR_LEN) {
- ANDROID_TRACE(("No BSSID\n"));
- return -1;
- }
-
- /* check VHT capability at beacon */
- if (bi->vht_cap) {
- if (CHSPEC_IS5G(bi->chanspec)) {
- result |= WL_ANDROID_LINK_AP_VHT_SUPPORT;
- }
- }
-
- /* get a rspec (radio spectrum) rate */
- error = wldev_iovar_getint(dev, "nrate", &rspec);
- if (unlikely(error) || rspec == 0) {
- ANDROID_ERROR(("get link status error (%d)\n", error));
- return -1;
- }
-
- encode = (rspec & WL_RSPEC_ENCODING_MASK);
- rate = (rspec & WL_RSPEC_RATE_MASK);
- txexp = (rspec & WL_RSPEC_TXEXP_MASK) >> WL_RSPEC_TXEXP_SHIFT;
-
- switch (encode) {
- case WL_RSPEC_ENCODE_HT:
- /* check Rx MCS Map for HT */
- for (i = 0; i < MAX_STREAMS_SUPPORTED; i++) {
- int8 bitmap = 0xFF;
- if (i == MAX_STREAMS_SUPPORTED-1) {
- bitmap = 0x7F;
- }
- if (bi->basic_mcs[i] & bitmap) {
- nss++;
- }
- }
- break;
- case WL_RSPEC_ENCODE_VHT:
- /* check Rx MCS Map for VHT */
- for (i = 1; i <= VHT_CAP_MCS_MAP_NSS_MAX; i++) {
- mcs_map = VHT_MCS_MAP_GET_MCS_PER_SS(i, dtoh16(bi->vht_rxmcsmap));
- if (mcs_map != VHT_CAP_MCS_MAP_NONE) {
- nss++;
- }
- }
- break;
- }
+#ifdef BT_WIFI_HANDOVER
+static int
+wl_tbow_teardown(struct net_device *dev, char *command, int total_len)
+{
+ int err = BCME_OK;
+ char buf[WLC_IOCTL_SMLEN];
+ tbow_setup_netinfo_t netinfo;
+ memset(&netinfo, 0, sizeof(netinfo));
+ netinfo.opmode = TBOW_HO_MODE_TEARDOWN;
- /* check MIMO capability with nss in beacon */
- if (nss > 1) {
- result |= WL_ANDROID_LINK_AP_MIMO_SUPPORT;
+ err = wldev_iovar_setbuf_bsscfg(dev, "tbow_doho", &netinfo,
+ sizeof(tbow_setup_netinfo_t), buf, WLC_IOCTL_SMLEN, 0, NULL);
+ if (err < 0) {
+ ANDROID_ERROR(("tbow_doho iovar error %d\n", err));
+ return err;
}
+ return err;
+}
+#endif /* BT_WIFI_HANOVER */
+
+#ifdef SET_RPS_CPUS
+static int
+wl_android_set_rps_cpus(struct net_device *dev, char *command, int total_len)
+{
+ int error, enable;
- single_stream = (encode == WL_RSPEC_ENCODE_RATE) ||
- ((encode == WL_RSPEC_ENCODE_HT) && rate < 8) ||
- ((encode == WL_RSPEC_ENCODE_VHT) &&
- ((rspec & WL_RSPEC_VHT_NSS_MASK) >> WL_RSPEC_VHT_NSS_SHIFT) == 1);
+ enable = command[strlen(CMD_RPSMODE) + 1] - '0';
+ error = dhd_rps_cpus_enable(dev, enable);
- if (txexp == 0) {
- if ((rspec & WL_RSPEC_STBC) && single_stream) {
- stf = OLD_NRATE_STF_STBC;
+#if defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE) && defined(WL_CFG80211)
+ if (!error) {
+ void *dhdp = wl_cfg80211_get_dhdp();
+ if (enable) {
+ ANDROID_TRACE(("%s : set ack suppress. TCPACK_SUP_HOLD.\n", __FUNCTION__));
+ dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_HOLD);
} else {
- stf = (single_stream) ? OLD_NRATE_STF_SISO : OLD_NRATE_STF_SDM;
+ ANDROID_TRACE(("%s : clear ack suppress.\n", __FUNCTION__));
+ dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF);
}
- } else if (txexp == 1 && single_stream) {
- stf = OLD_NRATE_STF_CDD;
}
+#endif /* DHDTCPACK_SUPPRESS && BCMPCIE && WL_CFG80211 */
- /* check 11ac (VHT) */
- if (encode == WL_RSPEC_ENCODE_VHT) {
- if (CHSPEC_IS5G(bi->chanspec)) {
- result |= WL_ANDROID_LINK_VHT;
- }
- }
+ return error;
+}
+#endif /* SET_RPS_CPUS */
+#ifdef P2P_LISTEN_OFFLOADING
+s32
+wl_cfg80211_p2plo_offload(struct net_device *dev, char *cmd, char* buf, int len)
+{
+ int ret = 0;
- /* check MIMO */
- if (result & WL_ANDROID_LINK_AP_MIMO_SUPPORT) {
- switch (stf) {
- case OLD_NRATE_STF_SISO:
- break;
- case OLD_NRATE_STF_CDD:
- case OLD_NRATE_STF_STBC:
- result |= WL_ANDROID_LINK_MIMO;
- break;
- case OLD_NRATE_STF_SDM:
- if (!single_stream) {
- result |= WL_ANDROID_LINK_MIMO;
- }
- break;
- }
- }
+ ANDROID_ERROR(("Entry cmd:%s arg_len:%d \n", cmd, len));
- ANDROID_TRACE(("%s:result=%d, stf=%d, single_stream=%d, mcs map=%d\n",
- __FUNCTION__, result, stf, single_stream, nss));
+ if (strncmp(cmd, "P2P_LO_START", strlen("P2P_LO_START")) == 0) {
+ ret = wl_cfg80211_p2plo_listen_start(dev, buf, len);
+ } else if (strncmp(cmd, "P2P_LO_STOP", strlen("P2P_LO_STOP")) == 0) {
+ ret = wl_cfg80211_p2plo_listen_stop(dev);
+ } else {
+ ANDROID_ERROR(("Request for Unsupported CMD:%s \n", buf));
+ ret = -EINVAL;
+ }
+ return ret;
+}
+#endif /* P2P_LISTEN_OFFLOADING */
- bytes_written = sprintf(command, "%s %d", CMD_GET_LINK_STATUS, result);
+#ifdef WL_CFG80211
+int
+wl_android_murx_bfe_cap(struct net_device *dev, int val)
+{
+ int err = BCME_OK;
+ int iface_count = wl_cfg80211_iface_count();
- return bytes_written;
+ if (iface_count > 1) {
+ ANDROID_ERROR(("%s: murx_bfe_cap change is not allowed when "
+ "there are multiple interfaces\n", __FUNCTION__));
+ return -EINVAL;
+ }
+ /* Now there is only single interface */
+ err = wldev_iovar_setint(dev, "murx_bfe_cap", val);
+ if (err) {
+ ANDROID_ERROR(("%s: Failed to set murx_bfe_cap IOVAR to %d,"
+ "error %d\n", __FUNCTION__, val, err));
+ err = -EINVAL;
+ }
+ return err;
}
+#endif
int
wl_android_get_channel(
}
if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) {
- bytes_written = wl_android_wifi_off(net);
+ bytes_written = wl_android_wifi_off(net, FALSE);
}
+#ifdef WL_CFG80211
else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) {
- /* TBD: SCAN-ACTIVE */
+ wl_cfg80211_set_passive_scan(net, command);
}
else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) {
- /* TBD: SCAN-PASSIVE */
+ wl_cfg80211_set_passive_scan(net, command);
}
+#endif
else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len);
}
int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
}
-#if defined(CUSTOM_PLATFORM_NV_TEGRA)
- else if (strnicmp(command, CMD_PKT_FILTER_MODE, strlen(CMD_PKT_FILTER_MODE)) == 0) {
- dhd_set_packet_filter_mode(net, &command[strlen(CMD_PKT_FILTER_MODE) + 1]);
- } else if (strnicmp(command, CMD_PKT_FILTER_PORTS, strlen(CMD_PKT_FILTER_PORTS)) == 0) {
- bytes_written = dhd_set_packet_filter_ports(net,
- &command[strlen(CMD_PKT_FILTER_PORTS) + 1]);
- ret = bytes_written;
- }
-#endif /* defined(CUSTOM_PLATFORM_NV_TEGRA) */
#endif /* PKT_FILTER_SUPPORT */
else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) {
/* TBD: BTCOEXSCAN-START */
}
else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
-#ifdef WL_HOST_BAND_MGMT
- s32 ret = 0;
- if ((ret = wl_cfg80211_set_band(net, band)) < 0) {
- if (ret == BCME_UNSUPPORTED) {
- /* If roam_var is unsupported, fallback to the original method */
- ANDROID_ERROR(("WL_HOST_BAND_MGMT defined, "
- "but roam_band iovar unsupported in the firmware\n"));
- } else {
- bytes_written = -1;
- goto exit;
- }
+ if (dhd_conf_get_band(dhd_get_pub(net)) != WLC_BAND_AUTO) {
+ printf("%s: Band is fixed in config.txt\n", __FUNCTION__);
+ goto exit;
}
- if ((band == WLC_BAND_AUTO) || (ret == BCME_UNSUPPORTED))
- bytes_written = wldev_set_band(net, band);
-#else
bytes_written = wldev_set_band(net, band);
-#endif /* WL_HOST_BAND_MGMT */
}
else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
#ifdef WL_CFG80211
/* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
+ /*
+ * Usage examples:
+ * DRIVER COUNTRY US
+ * DRIVER COUNTRY US/7
+ */
char *country_code = command + strlen(CMD_COUNTRY) + 1;
-#ifdef CUSTOMER_HW5
- /* Customer_hw5 want to keep connections */
- bytes_written = wldev_set_country(net, country_code, true, false);
-#else
- bytes_written = wldev_set_country(net, country_code, true, true);
-#endif
+ char *rev_info_delim = country_code + 2; /* 2 bytes of country code */
+ int revinfo = -1;
+ if ((rev_info_delim) &&
+ (strnicmp(rev_info_delim, CMD_COUNTRY_DELIMITER,
+ strlen(CMD_COUNTRY_DELIMITER)) == 0) &&
+ (rev_info_delim + 1)) {
+ revinfo = bcm_atoi(rev_info_delim + 1);
+ }
+ bytes_written = wldev_set_country(net, country_code, true, true, revinfo);
+#ifdef FCC_PWR_LIMIT_2G
+ if (wldev_iovar_setint(net, "fccpwrlimit2g", FALSE)) {
+ ANDROID_ERROR(("%s: fccpwrlimit2g deactivation is failed\n", __FUNCTION__));
+ } else {
+ ANDROID_ERROR(("%s: fccpwrlimit2g is deactivated\n", __FUNCTION__));
+ }
+#endif /* FCC_PWR_LIMIT_2G */
}
#endif /* WL_CFG80211 */
-
+ else if (strnicmp(command, CMD_SET_CSA, strlen(CMD_SET_CSA)) == 0) {
+ bytes_written = wl_android_set_csa(net, command, priv_cmd.total_len);
+ } else if (strnicmp(command, CMD_80211_MODE, strlen(CMD_80211_MODE)) == 0) {
+ bytes_written = wl_android_get_80211_mode(net, command, priv_cmd.total_len);
+ } else if (strnicmp(command, CMD_CHANSPEC, strlen(CMD_CHANSPEC)) == 0) {
+ bytes_written = wl_android_get_chanspec(net, command, priv_cmd.total_len);
+ } else if (strnicmp(command, CMD_DATARATE, strlen(CMD_DATARATE)) == 0) {
+ bytes_written = wl_android_get_datarate(net, command, priv_cmd.total_len);
+ } else if (strnicmp(command, CMD_ASSOC_CLIENTS, strlen(CMD_ASSOC_CLIENTS)) == 0) {
+ bytes_written = wl_android_get_assoclist(net, command, priv_cmd.total_len);
+ }
+
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+#ifdef WLTDLS
+ else if (strnicmp(command, CMD_TDLS_RESET, strlen(CMD_TDLS_RESET)) == 0) {
+ bytes_written = wl_android_tdls_reset(net);
+ }
+#endif /* WLTDLS */
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
#ifdef PNO_SUPPORT
else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
priv_cmd.total_len - skip);
}
-#ifdef WL_SDO
- else if (strnicmp(command, CMD_P2P_SD_OFFLOAD, strlen(CMD_P2P_SD_OFFLOAD)) == 0) {
- u8 *buf = command;
- u8 *cmd_id = NULL;
- int len;
-
- cmd_id = strsep((char **)&buf, " ");
- /* if buf == NULL, means no arg */
- if (buf == NULL)
- len = 0;
- else
- len = strlen(buf);
-
- bytes_written = wl_cfg80211_sd_offload(net, cmd_id, buf, len);
+#ifdef P2P_LISTEN_OFFLOADING
+ else if (strnicmp(command, CMD_P2P_LISTEN_OFFLOAD, strlen(CMD_P2P_LISTEN_OFFLOAD)) == 0) {
+ u8 *sub_command = strchr(command, ' ');
+ bytes_written = wl_cfg80211_p2plo_offload(net, command, sub_command,
+ sub_command ? strlen(sub_command) : 0);
}
-#endif /* WL_SDO */
+#endif /* P2P_LISTEN_OFFLOADING */
#ifdef WL_NAN
else if (strnicmp(command, CMD_NAN, strlen(CMD_NAN)) == 0) {
bytes_written = wl_cfg80211_nan_cmd_handler(net, command,
bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip,
priv_cmd.total_len - skip);
}
+ else if (strnicmp(command, CMD_P2P_ECSA, strlen(CMD_P2P_ECSA)) == 0) {
+ int skip = strlen(CMD_P2P_ECSA) + 1;
+ bytes_written = wl_cfg80211_set_p2p_ecsa(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) {
bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
priv_cmd.total_len - skip, *(command + skip - 2) - '0');
}
-#ifdef WLFBT
- else if (strnicmp(command, CMD_GET_FTKEY, strlen(CMD_GET_FTKEY)) == 0) {
- wl_cfg80211_get_fbt_key(command);
- bytes_written = FBT_KEYLEN;
- }
-#endif /* WLFBT */
#endif /* WL_CFG80211 */
- 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);
-#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 */
#if defined(WL_SUPPORT_AUTO_CHANNEL)
else if (strnicmp(command, CMD_GET_BEST_CHANNELS,
strlen(CMD_GET_BEST_CHANNELS)) == 0) {
priv_cmd.total_len);
}
#endif /* WL_SUPPORT_AUTO_CHANNEL */
+#if defined(WL_SUPPORT_AUTO_CHANNEL)
+ else if (strnicmp(command, CMD_SET_HAPD_AUTO_CHANNEL,
+ strlen(CMD_SET_HAPD_AUTO_CHANNEL)) == 0) {
+ int skip = strlen(CMD_SET_HAPD_AUTO_CHANNEL) + 1;
+ bytes_written = wl_android_set_auto_channel(net, (const char*)command+skip, command,
+ priv_cmd.total_len);
+ }
+#endif /* WL_SUPPORT_AUTO_CHANNEL */
+#ifdef CUSTOMER_HW4_PRIVATE_CMD
+#ifdef SUPPORT_SET_LPC
+ else if (strnicmp(command, CMD_HAPD_LPC_ENABLED,
+ strlen(CMD_HAPD_LPC_ENABLED)) == 0) {
+ int skip = strlen(CMD_HAPD_LPC_ENABLED) + 3;
+ wl_android_set_lpc(net, (const char*)command+skip);
+ }
+#endif /* SUPPORT_SET_LPC */
+#ifdef SUPPORT_TRIGGER_HANG_EVENT
+ else if (strnicmp(command, CMD_TEST_FORCE_HANG,
+ strlen(CMD_TEST_FORCE_HANG)) == 0) {
+ int skip = strlen(CMD_TEST_FORCE_HANG) + 1;
+ net_os_send_hang_message_reason(net, (const char*)command+skip);
+ }
+#endif /* SUPPORT_TRIGGER_HANG_EVENT */
+ 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);
+ else if (strnicmp(command, CMD_SET_RMC_ENABLE, strlen(CMD_SET_RMC_ENABLE)) == 0) {
+ int rmc_enable = *(command + strlen(CMD_SET_RMC_ENABLE) + 1) - '0';
+ bytes_written = wl_android_rmc_enable(net, rmc_enable);
+ }
+ else if (strnicmp(command, CMD_SET_RMC_TXRATE, strlen(CMD_SET_RMC_TXRATE)) == 0) {
+ int rmc_txrate;
+ sscanf(command, "%*s %10d", &rmc_txrate);
+ bytes_written = wldev_iovar_setint(net, "rmc_txrate", rmc_txrate * 2);
+ }
+ else if (strnicmp(command, CMD_SET_RMC_ACTPERIOD, strlen(CMD_SET_RMC_ACTPERIOD)) == 0) {
+ int actperiod;
+ sscanf(command, "%*s %10d", &actperiod);
+ bytes_written = wldev_iovar_setint(net, "rmc_actf_time", actperiod);
+ }
+ else if (strnicmp(command, CMD_SET_RMC_IDLEPERIOD, strlen(CMD_SET_RMC_IDLEPERIOD)) == 0) {
+ int acktimeout;
+ sscanf(command, "%*s %10d", &acktimeout);
+ acktimeout *= 1000;
+ bytes_written = wldev_iovar_setint(net, "rmc_acktmo", acktimeout);
+ }
+ else if (strnicmp(command, CMD_SET_RMC_LEADER, strlen(CMD_SET_RMC_LEADER)) == 0) {
+ int skip = strlen(CMD_SET_RMC_LEADER) + 1;
+ bytes_written = wl_android_rmc_set_leader(net, (const char*)command+skip);
+ }
+ else if (strnicmp(command, CMD_SET_RMC_EVENT,
+ strlen(CMD_SET_RMC_EVENT)) == 0)
+ bytes_written = wl_android_set_rmc_event(net, command, priv_cmd.total_len);
+ else if (strnicmp(command, CMD_GET_SCSCAN, strlen(CMD_GET_SCSCAN)) == 0) {
+ bytes_written = wl_android_get_singlecore_scan(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_SET_SCSCAN, strlen(CMD_SET_SCSCAN)) == 0) {
+ bytes_written = wl_android_set_singlecore_scan(net, command, priv_cmd.total_len);
+ }
+#ifdef TEST_TX_POWER_CONTROL
+ else if (strnicmp(command, CMD_TEST_SET_TX_POWER,
+ strlen(CMD_TEST_SET_TX_POWER)) == 0) {
+ int skip = strlen(CMD_TEST_SET_TX_POWER) + 1;
+ wl_android_set_tx_power(net, (const char*)command+skip);
+ }
+ else if (strnicmp(command, CMD_TEST_GET_TX_POWER,
+ strlen(CMD_TEST_GET_TX_POWER)) == 0) {
+ wl_android_get_tx_power(net, command, priv_cmd.total_len);
+ }
+#endif /* TEST_TX_POWER_CONTROL */
+ else if (strnicmp(command, CMD_SARLIMIT_TX_CONTROL,
+ strlen(CMD_SARLIMIT_TX_CONTROL)) == 0) {
+ int skip = strlen(CMD_SARLIMIT_TX_CONTROL) + 1;
+ wl_android_set_sarlimit_txctrl(net, (const char*)command+skip);
+ }
+#ifdef IPV6_NDO_SUPPORT
+ else if (strnicmp(command, CMD_NDRA_LIMIT, strlen(CMD_NDRA_LIMIT)) == 0) {
+ bytes_written = wl_android_nd_ra_limit(net, command, priv_cmd.total_len);
+ }
+#endif /* IPV6_NDO_SUPPORT */
+#endif /* CUSTOMER_HW4_PRIVATE_CMD */
else if (strnicmp(command, CMD_HAPD_MAC_FILTER, strlen(CMD_HAPD_MAC_FILTER)) == 0) {
int skip = strlen(CMD_HAPD_MAC_FILTER) + 1;
wl_android_set_mac_address_filter(net, (const char*)command+skip);
#ifdef WL_CFG80211
else if (strnicmp(command, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0)
bytes_written = wl_android_set_miracast(net, command, priv_cmd.total_len);
-#if defined(CUSTOM_PLATFORM_NV_TEGRA)
- else if (strnicmp(command, CMD_SETMIRACAST, strlen(CMD_SETMIRACAST)) == 0)
- bytes_written = wldev_miracast_tuning(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_ASSOCRESPIE, strlen(CMD_ASSOCRESPIE)) == 0)
- bytes_written = wldev_get_assoc_resp_ie(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_RXRATESTATS, strlen(CMD_RXRATESTATS)) == 0)
- bytes_written = wldev_get_rx_rate_stats(net, command, priv_cmd.total_len);
-#endif /* defined(CUSTOM_PLATFORM_NV_TEGRA) */
+#ifdef WL11ULB
+ else if (strnicmp(command, CMD_ULB_MODE, strlen(CMD_ULB_MODE)) == 0)
+ bytes_written = wl_android_set_ulb_mode(net, command, priv_cmd.total_len);
+ else if (strnicmp(command, CMD_ULB_BW, strlen(CMD_ULB_BW)) == 0)
+ bytes_written = wl_android_set_ulb_bw(net, command, priv_cmd.total_len);
+#endif /* WL11ULB */
else if (strnicmp(command, CMD_SETIBSSBEACONOUIDATA, strlen(CMD_SETIBSSBEACONOUIDATA)) == 0)
bytes_written = wl_android_set_ibss_beacon_ouidata(net,
command, priv_cmd.total_len);
#endif
-#ifdef WLAIBSS
- else if (strnicmp(command, CMD_SETIBSSTXFAILEVENT,
- strlen(CMD_SETIBSSTXFAILEVENT)) == 0)
- bytes_written = wl_android_set_ibss_txfail_event(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO_ALL,
- strlen(CMD_GET_IBSS_PEER_INFO_ALL)) == 0)
- bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len,
- TRUE);
- else if (strnicmp(command, CMD_GET_IBSS_PEER_INFO,
- strlen(CMD_GET_IBSS_PEER_INFO)) == 0)
- bytes_written = wl_android_get_ibss_peer_info(net, command, priv_cmd.total_len,
- FALSE);
- else if (strnicmp(command, CMD_SETIBSSROUTETABLE,
- strlen(CMD_SETIBSSROUTETABLE)) == 0)
- bytes_written = wl_android_set_ibss_routetable(net, command,
- priv_cmd.total_len);
- else if (strnicmp(command, CMD_SETIBSSAMPDU, strlen(CMD_SETIBSSAMPDU)) == 0)
- bytes_written = wl_android_set_ibss_ampdu(net, command, priv_cmd.total_len);
- else if (strnicmp(command, CMD_SETIBSSANTENNAMODE, strlen(CMD_SETIBSSANTENNAMODE)) == 0)
- bytes_written = wl_android_set_ibss_antenna(net, command, priv_cmd.total_len);
-#endif /* WLAIBSS */
else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {
int skip = strlen(CMD_KEEP_ALIVE) + 1;
bytes_written = wl_keep_alive_set(net, command + skip, priv_cmd.total_len - skip);
command + strlen(CMD_ROAM_OFFLOAD_APLIST) + 1);
}
#endif
+#if defined(WL_VIRTUAL_APSTA)
+ else if (strnicmp(command, CMD_INTERFACE_CREATE, strlen(CMD_INTERFACE_CREATE)) == 0) {
+ char *name = (command + strlen(CMD_INTERFACE_CREATE) +1);
+ ANDROID_INFO(("Creating %s interface\n", name));
+ bytes_written = wl_cfg80211_interface_create(net, name);
+ }
+ else if (strnicmp(command, CMD_INTERFACE_DELETE, strlen(CMD_INTERFACE_DELETE)) == 0) {
+ char *name = (command + strlen(CMD_INTERFACE_DELETE) +1);
+ ANDROID_INFO(("Deleteing %s interface\n", name));
+ bytes_written = wl_cfg80211_interface_delete(net, name);
+ }
+#endif /* defined (WL_VIRTUAL_APSTA) */
#ifdef P2PRESP_WFDIE_SRC
else if (strnicmp(command, CMD_P2P_SET_WFDIE_RESP,
strlen(CMD_P2P_SET_WFDIE_RESP)) == 0) {
bytes_written = wl_android_get_wfdie_resp(net, command, priv_cmd.total_len);
}
#endif /* P2PRESP_WFDIE_SRC */
- else if (strnicmp(command, CMD_GET_LINK_STATUS, strlen(CMD_GET_LINK_STATUS)) == 0) {
- bytes_written = wl_android_get_link_status(net, command, priv_cmd.total_len);
+#ifdef WL_CFG80211
+ else if (strnicmp(command, CMD_DFS_AP_MOVE, strlen(CMD_DFS_AP_MOVE)) == 0) {
+ char *data = (command + strlen(CMD_DFS_AP_MOVE) +1);
+ bytes_written = wl_cfg80211_dfs_ap_move(net, data, command, priv_cmd.total_len);
}
-#ifdef CONNECTION_STATISTICS
- else if (strnicmp(command, CMD_GET_CONNECTION_STATS,
- strlen(CMD_GET_CONNECTION_STATS)) == 0) {
- bytes_written = wl_android_get_connection_stats(net, command,
- priv_cmd.total_len);
+#endif
+ else if (strnicmp(command, CMD_WBTEXT_ENABLE, strlen(CMD_WBTEXT_ENABLE)) == 0) {
+ bytes_written = wl_android_wbtext(net, command, priv_cmd.total_len);
+ }
+#ifdef WL_CFG80211
+ else if (strnicmp(command, CMD_WBTEXT_PROFILE_CONFIG,
+ strlen(CMD_WBTEXT_PROFILE_CONFIG)) == 0) {
+ char *data = (command + strlen(CMD_WBTEXT_PROFILE_CONFIG) + 1);
+ bytes_written = wl_cfg80211_wbtext_config(net, data, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_WBTEXT_WEIGHT_CONFIG,
+ strlen(CMD_WBTEXT_WEIGHT_CONFIG)) == 0) {
+ char *data = (command + strlen(CMD_WBTEXT_WEIGHT_CONFIG) + 1);
+ bytes_written = wl_cfg80211_wbtext_weight_config(net, data,
+ command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_WBTEXT_TABLE_CONFIG,
+ strlen(CMD_WBTEXT_TABLE_CONFIG)) == 0) {
+ char *data = (command + strlen(CMD_WBTEXT_TABLE_CONFIG) + 1);
+ bytes_written = wl_cfg80211_wbtext_table_config(net, data,
+ command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_WBTEXT_DELTA_CONFIG,
+ strlen(CMD_WBTEXT_DELTA_CONFIG)) == 0) {
+ char *data = (command + strlen(CMD_WBTEXT_DELTA_CONFIG) + 1);
+ bytes_written = wl_cfg80211_wbtext_delta_config(net, data,
+ command, priv_cmd.total_len);
+ }
+#endif
+#ifdef SET_RPS_CPUS
+ else if (strnicmp(command, CMD_RPSMODE, strlen(CMD_RPSMODE)) == 0) {
+ bytes_written = wl_android_set_rps_cpus(net, command, priv_cmd.total_len);
+ }
+#endif /* SET_RPS_CPUS */
+#ifdef WLWFDS
+ else if (strnicmp(command, CMD_ADD_WFDS_HASH, strlen(CMD_ADD_WFDS_HASH)) == 0) {
+ bytes_written = wl_android_set_wfds_hash(net, command, priv_cmd.total_len, 1);
+ }
+ else if (strnicmp(command, CMD_DEL_WFDS_HASH, strlen(CMD_DEL_WFDS_HASH)) == 0) {
+ bytes_written = wl_android_set_wfds_hash(net, command, priv_cmd.total_len, 0);
+ }
+#endif /* WLWFDS */
+#ifdef BT_WIFI_HANDOVER
+ else if (strnicmp(command, CMD_TBOW_TEARDOWN, strlen(CMD_TBOW_TEARDOWN)) == 0) {
+ ret = wl_tbow_teardown(net, command, priv_cmd.total_len);
+ }
+#endif /* BT_WIFI_HANDOVER */
+#ifdef FCC_PWR_LIMIT_2G
+ else if (strnicmp(command, CMD_GET_FCC_PWR_LIMIT_2G,
+ strlen(CMD_GET_FCC_PWR_LIMIT_2G)) == 0) {
+ bytes_written = wl_android_get_fcc_pwr_limit_2g(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_SET_FCC_PWR_LIMIT_2G,
+ strlen(CMD_SET_FCC_PWR_LIMIT_2G)) == 0) {
+ bytes_written = wl_android_set_fcc_pwr_limit_2g(net, command, priv_cmd.total_len);
+ }
+#endif /* FCC_PWR_LIMIT_2G */
+#ifdef WL_CFG80211
+ else if (strnicmp(command, CMD_MURX_BFE_CAP,
+ strlen(CMD_MURX_BFE_CAP)) == 0) {
+ uint val = *(command + strlen(CMD_MURX_BFE_CAP) + 1) - '0';
+ bytes_written = wl_android_murx_bfe_cap(net, val);
}
#endif
+#if defined(DHD_ENABLE_BIGDATA_LOGGING)
+ else if (strnicmp(command, CMD_GET_BSS_INFO, strlen(CMD_GET_BSS_INFO)) == 0) {
+ bytes_written = wl_cfg80211_get_bss_info(net, command, priv_cmd.total_len);
+ }
+ else if (strnicmp(command, CMD_GET_ASSOC_REJECT_INFO, strlen(CMD_GET_ASSOC_REJECT_INFO))
+ == 0) {
+ bytes_written = wl_cfg80211_get_connect_failed_status(net, command,
+ priv_cmd.total_len);
+ }
+#endif /* DHD_ENABLE_BIGDATA_LOGGING */
+#if defined(SUPPORT_RANDOM_MAC_SCAN)
+ else if (strnicmp(command, ENABLE_RANDOM_MAC, strlen(ENABLE_RANDOM_MAC)) == 0) {
+ bytes_written = wl_cfg80211_set_random_mac(net, TRUE);
+ } else if (strnicmp(command, DISABLE_RANDOM_MAC, strlen(DISABLE_RANDOM_MAC)) == 0) {
+ bytes_written = wl_cfg80211_set_random_mac(net, FALSE);
+ }
+#endif /* SUPPORT_RANDOM_MAC_SCAN */
+#ifdef DHD_LOG_DUMP
+ else if (strnicmp(command, CMD_NEW_DEBUG_PRINT_DUMP,
+ strlen(CMD_NEW_DEBUG_PRINT_DUMP)) == 0) {
+ dhd_pub_t *dhdp = wl_cfg80211_get_dhdp();
+#ifdef DHD_TRACE_WAKE_LOCK
+ dhd_wk_lock_stats_dump(dhdp);
+#endif /* DHD_TRACE_WAKE_LOCK */
+ dhd_schedule_log_dump(dhdp);
+#if defined(DHD_DEBUG) && defined(BCMPCIE) && defined(DHD_FW_COREDUMP)
+ dhdp->memdump_type = DUMP_TYPE_BY_SYSDUMP;
+ dhd_bus_mem_dump(dhdp);
+#endif /* DHD_DEBUG && BCMPCIE && DHD_FW_COREDUMP */
+ }
+#endif /* DHD_LOG_DUMP */
else if(strnicmp(command, CMD_GET_CHANNEL, strlen(CMD_GET_CHANNEL)) == 0) {
bytes_written = wl_android_get_channel(net, command, priv_cmd.total_len);
}
ret = -EFAULT;
}
}
+#ifdef CONNECTION_STATISTICS
+ else if (strnicmp(command, CMD_GET_CONNECTION_STATS,
+ strlen(CMD_GET_CONNECTION_STATS)) == 0) {
+ bytes_written = wl_android_get_connection_stats(net, command,
+ priv_cmd.total_len);
+ }
+#endif
else {
ret = bytes_written;
}
bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ);
}
-#ifdef WL_GENL
- wl_genl_init();
-#endif
wl_netlink_init();
return ret;
int ret = 0;
struct io_cfg *cur, *q;
-#ifdef WL_GENL
- wl_genl_deinit();
-#endif /* WL_GENL */
wl_netlink_deinit();
list_for_each_entry_safe(cur, q, &miracast_resume_list, list) {
g_wifi_on = FALSE;
}
-#ifdef WL_GENL
-/* Generic Netlink Initializaiton */
-static int wl_genl_init(void)
-{
- int ret;
-
- ANDROID_TRACE(("GEN Netlink Init\n\n"));
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
- /* register new family */
- ret = genl_register_family(&wl_genl_family);
- if (ret != 0)
- goto failure;
-
- /* register functions (commands) of the new family */
- ret = genl_register_ops(&wl_genl_family, &wl_genl_ops);
- if (ret != 0) {
- ANDROID_ERROR(("register ops failed: %i\n", ret));
- genl_unregister_family(&wl_genl_family);
- goto failure;
- }
-
- ret = genl_register_mc_group(&wl_genl_family, &wl_genl_mcast);
-#else
- ret = genl_register_family_with_ops_groups(&wl_genl_family, wl_genl_ops, wl_genl_mcast);
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
- if (ret != 0) {
- ANDROID_ERROR(("register mc_group failed: %i\n", ret));
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
- genl_unregister_ops(&wl_genl_family, &wl_genl_ops);
-#endif
- genl_unregister_family(&wl_genl_family);
- goto failure;
- }
-
- return 0;
-
-failure:
- ANDROID_ERROR(("Registering Netlink failed!!\n"));
- return -1;
-}
-
-/* Generic netlink deinit */
-static int wl_genl_deinit(void)
-{
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
- if (genl_unregister_ops(&wl_genl_family, &wl_genl_ops) < 0)
- ANDROID_ERROR(("Unregister wl_genl_ops failed\n"));
-#endif
- if (genl_unregister_family(&wl_genl_family) < 0)
- ANDROID_ERROR(("Unregister wl_genl_ops failed\n"));
-
- return 0;
-}
-
-s32 wl_event_to_bcm_event(u16 event_type)
-{
- u16 event = -1;
-
- switch (event_type) {
- case WLC_E_SERVICE_FOUND:
- event = BCM_E_SVC_FOUND;
- break;
- case WLC_E_P2PO_ADD_DEVICE:
- event = BCM_E_DEV_FOUND;
- break;
- case WLC_E_P2PO_DEL_DEVICE:
- event = BCM_E_DEV_LOST;
- break;
- /* Above events are supported from BCM Supp ver 47 Onwards */
-#ifdef BT_WIFI_HANDOVER
- case WLC_E_BT_WIFI_HANDOVER_REQ:
- event = BCM_E_DEV_BT_WIFI_HO_REQ;
- break;
-#endif /* BT_WIFI_HANDOVER */
-
- default:
- ANDROID_ERROR(("Event not supported\n"));
- }
-
- return event;
-}
-
-s32
-wl_genl_send_msg(
- struct net_device *ndev,
- u32 event_type,
- u8 *buf,
- u16 len,
- u8 *subhdr,
- u16 subhdr_len)
-{
- int ret = 0;
- struct sk_buff *skb = NULL;
- void *msg;
- u32 attr_type = 0;
- bcm_event_hdr_t *hdr = NULL;
- int mcast = 1; /* By default sent as mutlicast type */
- int pid = 0;
- u8 *ptr = NULL, *p = NULL;
- u32 tot_len = sizeof(bcm_event_hdr_t) + subhdr_len + len;
- u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
-
-
- ANDROID_TRACE(("Enter \n"));
-
- /* Decide between STRING event and Data event */
- if (event_type == 0)
- attr_type = BCM_GENL_ATTR_STRING;
- else
- attr_type = BCM_GENL_ATTR_MSG;
-
- skb = genlmsg_new(NLMSG_GOODSIZE, kflags);
- if (skb == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- msg = genlmsg_put(skb, 0, 0, &wl_genl_family, 0, BCM_GENL_CMD_MSG);
- if (msg == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
-
- if (attr_type == BCM_GENL_ATTR_STRING) {
- /* Add a BCM_GENL_MSG attribute. Since it is specified as a string.
- * make sure it is null terminated
- */
- if (subhdr || subhdr_len) {
- ANDROID_ERROR(("No sub hdr support for the ATTR STRING type \n"));
- ret = -EINVAL;
- goto out;
- }
-
- ret = nla_put_string(skb, BCM_GENL_ATTR_STRING, buf);
- if (ret != 0) {
- ANDROID_ERROR(("nla_put_string failed\n"));
- goto out;
- }
- } else {
- /* ATTR_MSG */
-
- /* Create a single buffer for all */
- p = ptr = kzalloc(tot_len, kflags);
- if (!ptr) {
- ret = -ENOMEM;
- ANDROID_ERROR(("ENOMEM!!\n"));
- goto out;
- }
-
- /* Include the bcm event header */
- hdr = (bcm_event_hdr_t *)ptr;
- hdr->event_type = wl_event_to_bcm_event(event_type);
- hdr->len = len + subhdr_len;
- ptr += sizeof(bcm_event_hdr_t);
-
- /* Copy subhdr (if any) */
- if (subhdr && subhdr_len) {
- memcpy(ptr, subhdr, subhdr_len);
- ptr += subhdr_len;
- }
-
- /* Copy the data */
- if (buf && len) {
- memcpy(ptr, buf, len);
- }
-
- ret = nla_put(skb, BCM_GENL_ATTR_MSG, tot_len, p);
- if (ret != 0) {
- ANDROID_ERROR(("nla_put_string failed\n"));
- goto out;
- }
- }
-
- if (mcast) {
- int err = 0;
- /* finalize the message */
- genlmsg_end(skb, msg);
- /* NETLINK_CB(skb).dst_group = 1; */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
- if ((err = genlmsg_multicast(skb, 0, wl_genl_mcast.id, GFP_ATOMIC)) < 0)
-#else
- if ((err = genlmsg_multicast(&wl_genl_family, skb, 0, 0, GFP_ATOMIC)) < 0)
-#endif
- ANDROID_ERROR(("genlmsg_multicast for attr(%d) failed. Error:%d \n",
- attr_type, err));
- else
- ANDROID_TRACE(("Multicast msg sent successfully. attr_type:%d len:%d \n",
- attr_type, tot_len));
- } else {
- NETLINK_CB(skb).dst_group = 0; /* Not in multicast group */
-
- /* finalize the message */
- genlmsg_end(skb, msg);
-
- /* send the message back */
- if (genlmsg_unicast(&init_net, skb, pid) < 0)
- ANDROID_ERROR(("genlmsg_unicast failed\n"));
- }
-
-out:
- if (p)
- kfree(p);
- if (ret)
- nlmsg_free(skb);
-
- return ret;
-}
-
-static s32
-wl_genl_handle_msg(
- struct sk_buff *skb,
- struct genl_info *info)
-{
- struct nlattr *na;
- u8 *data = NULL;
-
- ANDROID_TRACE(("Enter \n"));
-
- if (info == NULL) {
- return -EINVAL;
- }
-
- na = info->attrs[BCM_GENL_ATTR_MSG];
- if (!na) {
- ANDROID_ERROR(("nlattribute NULL\n"));
- return -EINVAL;
- }
-
- data = (char *)nla_data(na);
- if (!data) {
- ANDROID_ERROR(("Invalid data\n"));
- return -EINVAL;
- } else {
- /* Handle the data */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)) || defined(WL_COMPAT_WIRELESS)
- ANDROID_TRACE(("%s: Data received from pid (%d) \n", __func__,
- info->snd_pid));
-#else
- ANDROID_TRACE(("%s: Data received from pid (%d) \n", __func__,
- info->snd_portid));
-#endif /* (LINUX_VERSION < VERSION(3, 7, 0) || WL_COMPAT_WIRELESS */
- }
-
- return 0;
-}
-#endif /* WL_GENL */
-
-
#if defined(RSSIAVG)
void
wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
int j, k=0;
int rssi, error=0;
+ scb_val_t scbval;
struct ether_addr bssid;
struct timeval now, timeout;
return 0;
}
if (error) {
- ANDROID_ERROR(("Could not get bssid (%d)\n", error));
+ ANDROID_ERROR(("%s: Could not get bssid (%d)\n", __FUNCTION__, error));
}
- error = wldev_get_rssi(net, &rssi);
+ memset(&scbval, 0, sizeof(scb_val_t));
+ error = wldev_get_rssi(net, &scbval);
+ rssi = scbval.val;
if (error) {
- ANDROID_ERROR(("Could not get rssi (%d)\n", error));
+ ANDROID_ERROR(("%s: Could not get rssi (%d)\n", __FUNCTION__, error));
return error;
}
leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
if (!leaf) {
ANDROID_ERROR(("%s: Memory alloc failure %d\n",
- __FUNCTION__, sizeof(wl_rssi_cache_t)));
+ __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
return 0;
}
- ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%d in the leaf\n",
+ ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n",
__FUNCTION__, k, &bssid, rssi));
leaf->next = NULL;
bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
for (;node;) {
if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
- ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n",
+ ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
__FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
for (j=0; j<RSSIAVG_LEN-1; j++)
node->RSSI[j] = node->RSSI[j+1];
leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
if (!leaf) {
ANDROID_ERROR(("%s: Memory alloc failure %d\n",
- __FUNCTION__, sizeof(wl_rssi_cache_t)));
+ __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
return;
}
- ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n",
+ ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\" in the leaf\n",
__FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
leaf->next = NULL;
int
wl_update_rssi_offset(struct net_device *net, int rssi)
{
- uint chip, chiprev;
+#if defined(RSSIOFFSET_NEW)
+ int j;
+#endif
if (!g_wifi_on)
return rssi;
- chip = dhd_conf_get_chip(dhd_get_pub(net));
- chiprev = dhd_conf_get_chiprev(dhd_get_pub(net));
- if (chip == BCM4330_CHIP_ID && chiprev == BCM4330B2_CHIP_REV) {
#if defined(RSSIOFFSET_NEW)
- int j;
- for (j=0; j<RSSI_OFFSET; j++) {
- if (rssi - (RSSI_OFFSET_MINVAL+RSSI_OFFSET_INTVAL*(j+1)) < 0)
- break;
- }
- rssi += j;
+ for (j=0; j<RSSI_OFFSET; j++) {
+ if (rssi - (RSSI_OFFSET_MINVAL+RSSI_OFFSET_INTVAL*(j+1)) < 0)
+ break;
+ }
+ rssi += j;
#else
- rssi += RSSI_OFFSET;
+ rssi += RSSI_OFFSET;
#endif
- }
return MIN(rssi, RSSI_MAXVAL);
}
#endif
#if defined(BSSCACHE)
-#define WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN 32
-
void
wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
{
tmp = 0;
prev->next = node->next;
}
- ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n",
+ ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
__FUNCTION__, i, &node->results.bss_info->BSSID,
dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));
kfree(node);
tmp = 0;
prev->next = node->next;
}
- ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%d, SSID \"%s\"\n",
+ ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
__FUNCTION__, i, &node->results.bss_info->BSSID,
dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));
kfree(node);
}
}
+void dump_bss_cache(
+#if defined(RSSIAVG)
+ wl_rssi_cache_ctrl_t *rssi_cache_ctrl,
+#endif
+ wl_bss_cache_t *node)
+{
+ int k = 0;
+ int16 rssi;
+
+ for (;node;) {
+#if defined(RSSIAVG)
+ rssi = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);
+#else
+ rssi = dtoh16(node->results.bss_info->RSSI);
+#endif
+ ANDROID_TRACE(("%s: dump %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, k, &node->results.bss_info->BSSID, rssi, node->results.bss_info->SSID));
+ k++;
+ node = node->next;
+ }
+}
+
void
-wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, wl_scan_results_t *ss_list)
+wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl,
+#if defined(RSSIAVG)
+ wl_rssi_cache_ctrl_t *rssi_cache_ctrl,
+#endif
+ wl_scan_results_t *ss_list)
{
- wl_bss_cache_t *node, *prev, *leaf, *tmp, **bss_head;
+ wl_bss_cache_t *node, *prev, *leaf, **bss_head;
wl_bss_info_t *bi = NULL;
int i, k=0;
+#if defined(SORT_BSS_BY_RSSI)
+ int16 rssi, rssi_node;
+#endif
struct timeval now, timeout;
if (!ss_list->count)
for (;node;) {
if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
- tmp = node;
- leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL);
- if (!leaf) {
- ANDROID_ERROR(("%s: Memory alloc failure %d and keep old BSS info\n",
- __FUNCTION__, dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN));
- break;
+ if (node == *bss_head)
+ *bss_head = node->next;
+ else {
+ prev->next = node->next;
}
-
- memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));
- leaf->next = node->next;
- leaf->dirty = 0;
- leaf->tv = timeout;
- leaf->results.count = 1;
- leaf->results.version = ss_list->version;
- ANDROID_TRACE(("%s: Update %d with BSSID %pM, RSSI=%d, SSID \"%s\", length=%d\n",
- __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID, dtoh32(bi->length)));
- if (!prev)
- *bss_head = leaf;
- else
- prev->next = leaf;
- node = leaf;
- prev = node;
-
- kfree(tmp);
- k++;
break;
}
prev = node;
node = node->next;
}
- if (node)
- continue;
-
- leaf = kmalloc(dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN, GFP_KERNEL);
+ leaf = kmalloc(dtoh32(bi->length) + sizeof(wl_bss_cache_t), GFP_KERNEL);
if (!leaf) {
ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__,
- dtoh32(bi->length) + WLC_IW_SS_CACHE_CTRL_FIELD_MAXLEN));
+ dtoh32(bi->length) + (int)sizeof(wl_bss_cache_t)));
return;
}
- ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%d, SSID \"%s\" in the leaf\n",
+ if (node) {
+ kfree(node);
+ node = NULL;
+ ANDROID_TRACE(("%s: Update %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
+ __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
+ } else
+ ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",
__FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));
memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));
leaf->results.version = ss_list->version;
k++;
- if (!prev)
+ if (*bss_head == NULL)
*bss_head = leaf;
- else
- prev->next = leaf;
+ else {
+#if defined(SORT_BSS_BY_RSSI)
+ node = *bss_head;
+#if defined(RSSIAVG)
+ rssi = wl_get_avg_rssi(rssi_cache_ctrl, &leaf->results.bss_info->BSSID);
+#else
+ rssi = dtoh16(leaf->results.bss_info->RSSI);
+#endif
+ for (;node;) {
+#if defined(RSSIAVG)
+ rssi_node = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);
+#else
+ rssi_node = dtoh16(node->results.bss_info->RSSI);
+#endif
+ if (rssi > rssi_node) {
+ leaf->next = node;
+ if (node == *bss_head)
+ *bss_head = leaf;
+ else
+ prev->next = leaf;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ }
+ if (node == NULL)
+ prev->next = leaf;
+#else
+ leaf->next = *bss_head;
+ *bss_head = leaf;
+#endif
+ }
}
+ dump_bss_cache(
+#if defined(RSSIAVG)
+ rssi_cache_ctrl,
+#endif
+ *bss_head);
}
void