summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRongjun Chen <rongjun.chen@amlogic.com>2017-12-25 13:24:00 +0800
committerRongjun Chen <rongjun.chen@amlogic.com>2017-12-25 13:24:00 +0800
commit91a2c11741597ad535bd522a5151ebb8076da262 (patch)
tree6eb56ac267e5e57e0174d9cd252498d3ed756b5a
parent5b98d48eda3cbc408c361b4aa81a3c8575e4ba69 (diff)
downloaddhd-driver-91a2c11741597ad535bd522a5151ebb8076da262.tar.gz
wifi: update bcm 1.57 wifi driver to fix ap6255 country code issue
PD# 157312 update wifi driver Change-Id: I6a98921411f990dce92a2de5a6eb0d37da33fd4f
-rwxr-xr-x[-rw-r--r--]bcmdhd.1.579.77.41.1.cn/Kconfig0
-rwxr-xr-x[-rw-r--r--]bcmdhd.1.579.77.41.1.cn/Makefile35
-rw-r--r--bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c12
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd.h6
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_config.c494
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_config.h37
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_gpio.c25
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_linux.c34
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c23
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_pcie.c42
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_pcie.h1
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c15
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_pno.c4
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_sdio.c33
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c2
-rw-r--r--bcmdhd.1.579.77.41.1.cn/include/epivers.h2
-rw-r--r--bcmdhd.1.579.77.41.1.cn/include/wlioctl.h7
-rw-r--r--bcmdhd.1.579.77.41.1.cn/wl_android_ext.c4236
-rw-r--r--bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c8
-rw-r--r--bcmdhd.1.579.77.41.1.cn/wldev_common.c2
20 files changed, 2746 insertions, 2272 deletions
diff --git a/bcmdhd.1.579.77.41.1.cn/Kconfig b/bcmdhd.1.579.77.41.1.cn/Kconfig
index bba8b4f..bba8b4f 100644..100755
--- a/bcmdhd.1.579.77.41.1.cn/Kconfig
+++ b/bcmdhd.1.579.77.41.1.cn/Kconfig
diff --git a/bcmdhd.1.579.77.41.1.cn/Makefile b/bcmdhd.1.579.77.41.1.cn/Makefile
index 5788bb3..0e7e33d 100644..100755
--- a/bcmdhd.1.579.77.41.1.cn/Makefile
+++ b/bcmdhd.1.579.77.41.1.cn/Makefile
@@ -20,8 +20,7 @@ DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER -DSDTEST \
-DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY \
-DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DPNO_SUPPORT -DDHDTCPACK_SUPPRESS \
-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DRXFRAME_THREAD \
- -DTSQ_MULTIPLIER -DMFP \
- -DBCMSDIOH_TXGLOM_EXT -DWL_EXT_IAPSTA \
+ -DTSQ_MULTIPLIER -DMFP -DWL_EXT_IAPSTA \
-DENABLE_INSMOD_NO_FW_LOAD \
-I$(src) -I$(src)/include
@@ -34,20 +33,9 @@ DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \
ifneq ($(CONFIG_BCMDHD_SDIO),)
DHDCFLAGS += \
-DBCMSDIO -DMMC_SDIO_ABORT -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR \
- -DBDC -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM \
+ -DBDC -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM -DBCMSDIOH_TXGLOM_EXT \
-DCUSTOM_SDIO_F2_BLKSIZE=256
-ifeq ($(CONFIG_VTS_SUPPORT),y)
-DHDCFLAGS += \
- -DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG \
- -DLINKSTAT_SUPPORT -DDEBUGABILITY -DDBG_PKT_MON -DKEEP_ALIVE -DPKT_FILTER_SUPPORT \
- -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHDTCPACK_SUPPRESS -DDHD_WAKE_STATUS \
- -DCUSTOM_COUNTRY_CODE -DDHD_FW_COREDUMP -DDHD_USE_STATIC_MEMDUMP
-
-DHDOFILES += dhd_debug_linux.o dhd_debug.o bcmxtlv.o \
- dhd_rtt.o bcm_app_utils.o
-endif
-
DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \
dhd_sdio.o dhd_cdc.o dhd_wlfc.o
@@ -74,12 +62,28 @@ ifneq ($(CONFIG_BCMDHD_PCIE),)
DHDCFLAGS += \
-DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1
DHDCFLAGS += -DDHD_PCIE_BAR1_WIN_BASE_FIX=0x200000
+ifneq ($(CONFIG_PCI_MSI),)
DHDCFLAGS += -DDHD_USE_MSI
+endif
+ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
+DHDCFLAGS += -DDHD_USE_STATIC_CTRLBUF
+endif
DHDOFILES += dhd_pcie.o dhd_pcie_linux.o pcie_core.o dhd_flowring.o \
dhd_msgbuf.o
endif
+ifeq ($(CONFIG_VTS_SUPPORT),y)
+DHDCFLAGS += \
+ -DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG \
+ -DLINKSTAT_SUPPORT -DDEBUGABILITY -DDBG_PKT_MON -DKEEP_ALIVE -DPKT_FILTER_SUPPORT \
+ -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHDTCPACK_SUPPRESS -DDHD_WAKE_STATUS \
+ -DCUSTOM_COUNTRY_CODE -DDHD_FW_COREDUMP -DEXPLICIT_DISCIF_CLEANUP
+
+DHDOFILES += dhd_debug_linux.o dhd_debug.o bcmxtlv.o \
+ dhd_rtt.o bcm_app_utils.o
+endif
+
obj-$(CONFIG_BCMDHD) += dhd.o
dhd-objs += $(DHDOFILES)
@@ -96,7 +100,8 @@ endif
ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
#obj-m += dhd_static_buf.o
-DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF -DCONFIG_DHD_USE_STATIC_BUF
+DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
+DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP -DCONFIG_DHD_USE_STATIC_BUF
endif
ifneq ($(CONFIG_WIRELESS_EXT),)
diff --git a/bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c b/bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c
index d98411f..0921a6c 100644
--- a/bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c
+++ b/bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c
@@ -57,18 +57,6 @@ mmc_host_clk_release(struct mmc_host *host)
#include <drivers/mmc/core/host.h>
#else
#include <linux/mmc/host.h>
-static inline void mmc_host_clk_hold(struct mmc_host *host)
-{
-}
-
-static inline void mmc_host_clk_release(struct mmc_host *host)
-{
-}
-
-static inline unsigned int mmc_host_clk_rate(struct mmc_host *host)
-{
- return host->ios.clock;
-}
#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 0, 0)) */
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd.h b/bcmdhd.1.579.77.41.1.cn/dhd.h
index 0c46434..bccc5bf 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd.h
+++ b/bcmdhd.1.579.77.41.1.cn/dhd.h
@@ -443,12 +443,8 @@ enum dhd_rsdb_scan_features {
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
-#ifdef CUSTOM_SDIO_F2_BLKSIZE
-#define DHD_SDALIGN CUSTOM_SDIO_F2_BLKSIZE
-#else
#define DHD_SDALIGN 32
#endif
-#endif
/**
* DMA-able buffer parameters
@@ -1494,7 +1490,7 @@ extern void dhd_os_dhdiovar_lock(dhd_pub_t *pub);
extern void dhd_os_dhdiovar_unlock(dhd_pub_t *pub);
extern int dhd_os_proto_block(dhd_pub_t * pub);
extern int dhd_os_proto_unblock(dhd_pub_t * pub);
-extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition);
+extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition, bool resched);
extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub);
extern unsigned int dhd_os_get_ioctl_resp_timeout(void);
extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_config.c b/bcmdhd.1.579.77.41.1.cn/dhd_config.c
index 700573f..5fddc37 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_config.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_config.c
@@ -59,6 +59,7 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
#define CONFIG_BCM43341B0 "config_43341b0.txt"
#define CONFIG_BCM43241B4 "config_43241b4.txt"
#define CONFIG_BCM4339A0 "config_4339a0.txt"
+#define CONFIG_BCM43454C0 "config_43454c0.txt"
#define CONFIG_BCM43455C0 "config_43455c0.txt"
#define CONFIG_BCM43456C5 "config_43456c5.txt"
#define CONFIG_BCM4354A1 "config_4354a1.txt"
@@ -80,7 +81,7 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
#define FW_BCM43438A0 "fw_bcm43438a0"
#define FW_BCM43438A1 "fw_bcm43438a1"
#define FW_BCM43436B0 "fw_bcm43436b0"
-#define FW_BCM43012B0 "fw_bcm43012b0"
+#define FW_BCM43013B0 "fw_bcm43013b0"
#define FW_BCM43341B1 "fw_bcm43341b0_ag"
#define FW_BCM43241B4 "fw_bcm43241b4_ag"
#define FW_BCM4339A0 "fw_bcm4339a0_ag"
@@ -92,10 +93,11 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
#define FW_BCM4359B1 "fw_bcm4359b1_ag"
#define FW_BCM4359C0 "fw_bcm4359c0_ag"
-#define CLM_BCM43012B0 "clm_bcm43012b0"
+#define CLM_BCM43013B0 "clm_bcm43013b0"
#endif
#ifdef BCMPCIE
#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"
+#define FW_BCM4359C0 "fw_bcm4359c0_pcie_ag"
#endif
#define htod32(i) i
@@ -390,6 +392,21 @@ dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)
#endif
void
+dhd_conf_free_country_list(conf_country_list_t *country_list)
+{
+ int i;
+
+ CONFIG_TRACE(("%s called\n", __FUNCTION__));
+ for (i=0; i<country_list->count; i++) {
+ if (country_list->cspec[i]) {
+ CONFIG_TRACE(("%s Free cspec %p\n", __FUNCTION__, country_list->cspec[i]));
+ kfree(country_list->cspec[i]);
+ }
+ }
+ country_list->count = 0;
+}
+
+void
dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
{
int fw_type, ag_type;
@@ -417,7 +434,10 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
/* find out the last '/' */
i = strlen(fw_path);
while (i > 0) {
- if (fw_path[i] == '/') break;
+ if (fw_path[i] == '/') {
+ i++;
+ break;
+ }
i--;
}
#ifdef BAND_AG
@@ -447,92 +467,93 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
case BCM4330_CHIP_ID:
if (ag_type == FW_TYPE_G) {
if (chiprev == BCM4330B2_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4330B2);
+ strcpy(&fw_path[i], FW_BCM4330B2);
} else {
if (chiprev == BCM4330B2_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4330B2_AG);
+ strcpy(&fw_path[i], FW_BCM4330B2_AG);
}
break;
case BCM43362_CHIP_ID:
if (chiprev == BCM43362A0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43362A0);
+ strcpy(&fw_path[i], FW_BCM43362A0);
else
- strcpy(&fw_path[i+1], FW_BCM43362A2);
+ strcpy(&fw_path[i], FW_BCM43362A2);
break;
case BCM43430_CHIP_ID:
if (chiprev == BCM43430A0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43438A0);
+ strcpy(&fw_path[i], FW_BCM43438A0);
else if (chiprev == BCM43430A1_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43438A1);
+ strcpy(&fw_path[i], FW_BCM43438A1);
else if (chiprev == BCM43430A2_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43436B0);
+ strcpy(&fw_path[i], FW_BCM43436B0);
break;
case BCM43012_CHIP_ID:
- if (chiprev == BCM43012B0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43012B0);
+ if (chiprev == BCM43013B0_CHIP_REV)
+ strcpy(&fw_path[i], FW_BCM43013B0);
break;
case BCM4334_CHIP_ID:
if (chiprev == BCM4334B1_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4334B1);
+ strcpy(&fw_path[i], FW_BCM4334B1);
break;
case BCM43340_CHIP_ID:
case BCM43341_CHIP_ID:
if (chiprev == BCM43341B0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43341B1);
+ strcpy(&fw_path[i], FW_BCM43341B1);
break;
case BCM4324_CHIP_ID:
if (chiprev == BCM43241B4_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43241B4);
+ strcpy(&fw_path[i], FW_BCM43241B4);
break;
case BCM4335_CHIP_ID:
if (chiprev == BCM4335A0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4339A0);
+ strcpy(&fw_path[i], FW_BCM4339A0);
break;
case BCM4339_CHIP_ID:
if (chiprev == BCM4339A0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4339A0);
- break;
- case BCM43454_CHIP_ID:
- if (chiprev == BCM43455C0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43455C0);
+ strcpy(&fw_path[i], FW_BCM4339A0);
break;
case BCM4345_CHIP_ID:
+ case BCM43454_CHIP_ID:
if (chiprev == BCM43455C0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43455C0);
- else if (chiprev == BCM43455C5_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM43456C5);
+ strcpy(&fw_path[i], FW_BCM43455C0);
+ else if (chiprev == BCM43456C5_CHIP_REV)
+ strcpy(&fw_path[i], FW_BCM43456C5);
break;
case BCM4354_CHIP_ID:
if (chiprev == BCM4354A1_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4354A1);
+ strcpy(&fw_path[i], FW_BCM4354A1);
else if (chiprev == BCM4356A2_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4356A2);
+ strcpy(&fw_path[i], FW_BCM4356A2);
break;
case BCM4356_CHIP_ID:
case BCM4371_CHIP_ID:
if (chiprev == BCM4356A2_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4356A2);
+ strcpy(&fw_path[i], FW_BCM4356A2);
break;
case BCM43569_CHIP_ID:
if (chiprev == BCM4358A3_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4358A3);
+ strcpy(&fw_path[i], FW_BCM4358A3);
break;
case BCM4359_CHIP_ID:
if (chiprev == BCM4359B1_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4359B1);
+ strcpy(&fw_path[i], FW_BCM4359B1);
else if (chiprev == BCM4359C0_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4359C0);
+ strcpy(&fw_path[i], FW_BCM4359C0);
break;
#endif
#ifdef BCMPCIE
case BCM4354_CHIP_ID:
case BCM4356_CHIP_ID:
if (chiprev == BCM4356A2_CHIP_REV)
- strcpy(&fw_path[i+1], FW_BCM4356A2);
+ strcpy(&fw_path[i], FW_BCM4356A2);
+ break;
+ case BCM4359_CHIP_ID:
+ if (chiprev == BCM4359C0_CHIP_REV)
+ strcpy(&fw_path[i], FW_BCM4359C0);
break;
#endif
default:
- strcpy(&fw_path[i+1], "fw_bcmdhd");
+ strcpy(&fw_path[i], "fw_bcmdhd");
}
strcat(fw_path, fw_tail);
@@ -557,7 +578,10 @@ dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
/* find out the last '/' */
i = strlen(clm_path);
while (i > 0) {
- if (clm_path[i] == '/') break;
+ if (clm_path[i] == '/') {
+ i++;
+ break;
+ }
i--;
}
@@ -566,12 +590,12 @@ dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
switch (chip) {
#ifdef BCMSDIO
case BCM43012_CHIP_ID:
- if (chiprev == BCM43012B0_CHIP_REV)
- strcpy(&clm_path[i+1], CLM_BCM43012B0);
+ if (chiprev == BCM43013B0_CHIP_REV)
+ strcpy(&clm_path[i], CLM_BCM43013B0);
break;
#endif
default:
- strcpy(&clm_path[i+1], "clm_bcmdhd");
+ strcpy(&clm_path[i], "clm_bcmdhd");
}
strcat(clm_path, fw_tail);
@@ -612,11 +636,14 @@ dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
/* find out the last '/' */
i = strlen(nv_path);
while (i > 0) {
- if (nv_path[i] == '/') break;
+ if (nv_path[i] == '/') {
+ i++;
+ break;
+ }
i--;
}
- strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);
+ strcpy(&nv_path[i], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);
CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path));
}
@@ -635,10 +662,13 @@ dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path
/* find out the last '/' */
i = strlen(dst_path);
while (i > 0) {
- if (dst_path[i] == '/') break;
+ if (dst_path[i] == '/') {
+ i++;
+ break;
+ }
i--;
}
- strcpy(&dst_path[i+1], dst_name);
+ strcpy(&dst_path[i], dst_name);
CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));
}
@@ -661,7 +691,10 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
/* find out the last '/' */
i = strlen(conf_path);
while (i > 0) {
- if (conf_path[i] == '/') break;
+ if (conf_path[i] == '/') {
+ i++;
+ break;
+ }
i--;
}
@@ -669,77 +702,84 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
#ifdef BCMSDIO
case BCM4330_CHIP_ID:
if (chiprev == BCM4330B2_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4330B2);
+ strcpy(&conf_path[i], CONFIG_BCM4330B2);
break;
case BCM43362_CHIP_ID:
if (chiprev == BCM43362A0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43362A0);
+ strcpy(&conf_path[i], CONFIG_BCM43362A0);
else
- strcpy(&conf_path[i+1], CONFIG_BCM43362A2);
+ strcpy(&conf_path[i], CONFIG_BCM43362A2);
break;
case BCM43430_CHIP_ID:
if (chiprev == BCM43430A0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43438A0);
+ strcpy(&conf_path[i], CONFIG_BCM43438A0);
else if (chiprev == BCM43430A1_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43438A1);
+ strcpy(&conf_path[i], CONFIG_BCM43438A1);
else if (chiprev == BCM43430A2_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43436B0);
+ strcpy(&conf_path[i], CONFIG_BCM43436B0);
break;
case BCM4334_CHIP_ID:
if (chiprev == BCM4334B1_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4334B1);
+ strcpy(&conf_path[i], CONFIG_BCM4334B1);
break;
case BCM43340_CHIP_ID:
case BCM43341_CHIP_ID:
if (chiprev == BCM43341B0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43341B0);
+ strcpy(&conf_path[i], CONFIG_BCM43341B0);
break;
case BCM4324_CHIP_ID:
if (chiprev == BCM43241B4_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43241B4);
+ strcpy(&conf_path[i], CONFIG_BCM43241B4);
break;
case BCM4335_CHIP_ID:
if (chiprev == BCM4335A0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
+ strcpy(&conf_path[i], CONFIG_BCM4339A0);
break;
- case BCM4345_CHIP_ID:
case BCM43454_CHIP_ID:
if (chiprev == BCM43455C0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43455C0);
- else if (chiprev == BCM43455C5_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM43456C5);
+ strcpy(&conf_path[i], CONFIG_BCM43454C0);
+ break;
+ case BCM4345_CHIP_ID:
+ if (chiprev == BCM43455C0_CHIP_REV)
+ strcpy(&conf_path[i], CONFIG_BCM43455C0);
+ else if (chiprev == BCM43456C5_CHIP_REV)
+ strcpy(&conf_path[i], CONFIG_BCM43456C5);
break;
case BCM4339_CHIP_ID:
if (chiprev == BCM4339A0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
+ strcpy(&conf_path[i], CONFIG_BCM4339A0);
break;
case BCM4354_CHIP_ID:
if (chiprev == BCM4354A1_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4354A1);
+ strcpy(&conf_path[i], CONFIG_BCM4354A1);
else if (chiprev == BCM4356A2_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
+ strcpy(&conf_path[i], CONFIG_BCM4356A2);
break;
case BCM4356_CHIP_ID:
case BCM4371_CHIP_ID:
if (chiprev == BCM4356A2_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
+ strcpy(&conf_path[i], CONFIG_BCM4356A2);
break;
case BCM43569_CHIP_ID:
if (chiprev == BCM4358A3_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4358A3);
+ strcpy(&conf_path[i], CONFIG_BCM4358A3);
break;
case BCM4359_CHIP_ID:
if (chiprev == BCM4359B1_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4359B1);
+ strcpy(&conf_path[i], CONFIG_BCM4359B1);
else if (chiprev == BCM4359C0_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4359C0);
+ strcpy(&conf_path[i], CONFIG_BCM4359C0);
break;
#endif
#ifdef BCMPCIE
case BCM4354_CHIP_ID:
case BCM4356_CHIP_ID:
if (chiprev == BCM4356A2_CHIP_REV)
- strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
+ strcpy(&conf_path[i], CONFIG_BCM4356A2);
+ break;
+ case BCM4359_CHIP_ID:
+ if (chiprev == BCM4359C0_CHIP_REV)
+ strcpy(&conf_path[i], CONFIG_BCM4359C0);
break;
#endif
}
@@ -839,19 +879,6 @@ dhd_conf_get_band(dhd_pub_t *dhd)
}
int
-dhd_conf_set_country(dhd_pub_t *dhd)
-{
- int bcmerror = -1;
-
- memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
- printf("%s: set country %s, revision %d\n", __FUNCTION__,
- dhd->conf->cspec.ccode, dhd->conf->cspec.rev);
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);
-
- return bcmerror;
-}
-
-int
dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
{
int bcmerror = -1;
@@ -860,23 +887,28 @@ dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));
if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)
CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));
- else
- printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
return bcmerror;
}
int
-dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
+dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs)
{
int bcmerror = -1, i;
struct dhd_conf *conf = dhd->conf;
+ conf_country_list_t *country_list;
+
+ if ((nodfs > 0 || dhd->op_mode & DHD_FLAG_HOSTAP_MODE) &&
+ conf->country_list_nodfs.count > 0) {
+ country_list = &conf->country_list_nodfs;
+ } else {
+ country_list = &conf->country_list;
+ }
- for (i = 0; i < conf->country_list.count; i++) {
- if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) {
- memcpy(cspec->ccode,
- conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);
- cspec->rev = conf->country_list.cspec[i].rev;
+ for (i = 0; i < country_list->count; i++) {
+ if (!strncmp(cspec->country_abbrev, country_list->cspec[i]->country_abbrev, 2)) {
+ memcpy(cspec->ccode, country_list->cspec[i]->ccode, WLC_CNTRY_BUF_SZ);
+ cspec->rev = country_list->cspec[i]->rev;
printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
return 0;
}
@@ -886,12 +918,28 @@ dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
}
int
+dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+ int bcmerror = -1;
+
+ memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
+
+ printf("%s: set country %s, revision %d\n", __FUNCTION__, cspec->ccode, cspec->rev);
+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec, sizeof(wl_country_t), FALSE);
+ dhd_conf_get_country(dhd, cspec);
+ printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
+
+ return bcmerror;
+}
+
+int
dhd_conf_fix_country(dhd_pub_t *dhd)
{
int bcmerror = -1;
uint band;
wl_uint32_list_t *list;
u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+ wl_country_t cspec;
if (!(dhd && dhd->conf)) {
return bcmerror;
@@ -910,11 +958,13 @@ dhd_conf_fix_country(dhd_pub_t *dhd)
dtoh32(list->count)<11)) {
CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",
__FUNCTION__, bcmerror, dtoh32(list->count)));
- if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {
- strcpy(dhd->conf->cspec.country_abbrev, "US");
- dhd->conf->cspec.rev = 0;
- strcpy(dhd->conf->cspec.ccode, "US");
- dhd_conf_set_country(dhd);
+ dhd_conf_map_country_list(dhd, &dhd->conf->cspec, 0);
+ if ((bcmerror = dhd_conf_set_country(dhd, &dhd->conf->cspec)) < 0) {
+ strcpy(cspec.country_abbrev, "US");
+ cspec.rev = 0;
+ strcpy(cspec.ccode, "US");
+ dhd_conf_map_country_list(dhd, &cspec, 0);
+ dhd_conf_set_country(dhd, &cspec);
}
}
@@ -1131,12 +1181,32 @@ dhd_conf_set_wme(dhd_pub_t *dhd, int mode)
return;
}
+void
+dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int p2p_mode, int miracast_mode)
+{
+ int i;
+ struct dhd_conf *conf = dhd->conf;
+ bool set = true;
+
+ for (i=0; i<MCHAN_MAX_NUM; i++) {
+ set = true;
+ set &= (conf->mchan[i].bw >= 0);
+ set &= ((conf->mchan[i].p2p_mode == -1) | (conf->mchan[i].p2p_mode == p2p_mode));
+ set &= ((conf->mchan[i].miracast_mode == -1) | (conf->mchan[i].miracast_mode == miracast_mode));
+ if (set) {
+ dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mchan_bw", conf->mchan[i].bw, 0, FALSE);
+ }
+ }
+
+ return;
+}
+
#ifdef PKT_FILTER_SUPPORT
void
dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
{
int i, j;
- char str[12];
+ char str[16];
#define MACS "%02x%02x%02x%02x%02x%02x"
/*
@@ -1157,17 +1227,17 @@ dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
}
dhd->pktfilter_count += i;
- for(i=0; i<dhd->conf->magic_pkt_filter_add.count; i++) {
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+ if (dhd->conf->magic_pkt_filter_add) {
+ strcat(dhd->conf->magic_pkt_filter_add, " 0x");
+ strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
for (j=0; j<16; j++)
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+ strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
+ strcat(dhd->conf->magic_pkt_filter_add, " 0x");
+ strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));
for (j=0; j<16; j++)
- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str);
- dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i];
+ strncat(dhd->conf->magic_pkt_filter_add, str, 12);
+ dhd->pktfilter[dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add;
dhd->pktfilter_count += 1;
}
}
@@ -1730,6 +1800,7 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
char *pch, *pick_tmp;
struct dhd_conf *conf = dhd->conf;
char *data = full_param+len_param;
+ wl_country_t *cspec;
/* Process country_list:
* country_list=[country1]:[ccode1]/[regrev1],
@@ -1743,23 +1814,125 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
pch = bcmstrtok(&pick_tmp, ":", 0);
if (!pch)
break;
- strcpy(conf->country_list.cspec[i].country_abbrev, pch);
+ cspec = NULL;
+ if (!(cspec = kmalloc(sizeof(wl_country_t), GFP_KERNEL))) {
+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+ break;
+ }
+ conf->country_list.count++;
+ memset(cspec, 0, sizeof(wl_country_t));
+ conf->country_list.cspec[i] = cspec;
+
+ strcpy(cspec->country_abbrev, pch);
pch = bcmstrtok(&pick_tmp, "/", 0);
if (!pch)
break;
- memcpy(conf->country_list.cspec[i].ccode, pch, 2);
+ memcpy(cspec->ccode, pch, 2);
pch = bcmstrtok(&pick_tmp, ", ", 0);
if (!pch)
break;
- conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);
- conf->country_list.count ++;
+ cspec->rev = (int32)simple_strtol(pch, NULL, 10);
CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,
- conf->country_list.cspec[i].country_abbrev,
- conf->country_list.cspec[i].ccode,
- conf->country_list.cspec[i].rev));
+ cspec->country_abbrev, cspec->ccode, cspec->rev));
}
printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);
}
+ else if (!strncmp("country_list_nodfs=", full_param, len_param)) {
+ pick_tmp = data;
+ for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {
+ /* Process country code */
+ pch = bcmstrtok(&pick_tmp, ":", 0);
+ if (!pch)
+ break;
+ cspec = NULL;
+ if (!(cspec = kmalloc(sizeof(wl_country_t), GFP_KERNEL))) {
+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+ break;
+ }
+ conf->country_list_nodfs.count++;
+ memset(cspec, 0, sizeof(wl_country_t));
+ conf->country_list_nodfs.cspec[i] = cspec;
+
+ strcpy(cspec->country_abbrev, pch);
+ pch = bcmstrtok(&pick_tmp, "/", 0);
+ if (!pch)
+ break;
+ memcpy(cspec->ccode, pch, 2);
+ pch = bcmstrtok(&pick_tmp, ", ", 0);
+ if (!pch)
+ break;
+ cspec->rev = (int32)simple_strtol(pch, NULL, 10);
+ CONFIG_TRACE(("%s: country_list_nodfs abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,
+ cspec->country_abbrev, cspec->ccode, cspec->rev));
+ }
+ printf("%s: %d nodfs country in list\n", __FUNCTION__, conf->country_list_nodfs.count);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+bool
+dhd_conf_read_mchan_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+ int i;
+ char *pch, *pick_tmp, *pick_tmp2;
+ struct dhd_conf *conf = dhd->conf;
+ char *data = full_param+len_param;
+
+ /* Process mchan_bw and btc_params_mgmt:
+ * mchan_bw=[val]/[any/go/gc]/[any/source/sink]
+ * Ex: mchan_bw=80/go/source, 30/gc/sink
+ */
+ if (!strncmp("mchan_bw=", full_param, len_param)) {
+ pick_tmp = data;
+ for (i=0; i<MCHAN_MAX_NUM; i++) {
+ pick_tmp2 = bcmstrtok(&pick_tmp, ", ", 0);
+ if (!pick_tmp2)
+ break;
+ pch = bcmstrtok(&pick_tmp2, "/", 0);
+ if (!pch) {
+ break;
+ } else {
+ conf->mchan[i].bw = (int)simple_strtol(pch, NULL, 0);
+ if (conf->mchan[i].bw < 0 || conf->mchan[i].bw > 100) {
+ CONFIG_ERROR(("%s: wrong bw %d\n", __FUNCTION__, conf->mchan[i].bw));
+ conf->mchan[i].bw = 0;
+ break;
+ }
+ }
+ pch = bcmstrtok(&pick_tmp2, "/", 0);
+ if (!pch) {
+ break;
+ } else {
+ if (bcmstrstr(pch, "any")) {
+ conf->mchan[i].p2p_mode = -1;
+ } else if (bcmstrstr(pch, "go")) {
+ conf->mchan[i].p2p_mode = WL_P2P_IF_GO;
+ } else if (bcmstrstr(pch, "gc")) {
+ conf->mchan[i].p2p_mode = WL_P2P_IF_CLIENT;
+ }
+ }
+ pch = bcmstrtok(&pick_tmp2, "/", 0);
+ if (!pch) {
+ break;
+ } else {
+ if (bcmstrstr(pch, "any")) {
+ conf->mchan[i].miracast_mode = -1;
+ } else if (bcmstrstr(pch, "source")) {
+ conf->mchan[i].miracast_mode = MIRACAST_SOURCE;
+ } else if (bcmstrstr(pch, "sink")) {
+ conf->mchan[i].miracast_mode = MIRACAST_SINK;
+ }
+ }
+ }
+ for (i=0; i<MCHAN_MAX_NUM; i++) {
+ if (conf->mchan[i].bw >= 0)
+ printf("%s: mchan_bw=%d/%d/%d\n", __FUNCTION__,
+ conf->mchan[i].bw, conf->mchan[i].p2p_mode, conf->mchan[i].miracast_mode);
+ }
+ }
else
return false;
@@ -1815,16 +1988,13 @@ dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param)
printf("\n");
}
else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {
- pick_tmp = data;
- pch = bcmstrtok(&pick_tmp, ",.-", 0);
- i=0;
- while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
- strcpy(&conf->magic_pkt_filter_add.filter[i][0], pch);
- printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]);
- pch = bcmstrtok(&pick_tmp, ",.-", 0);
- i++;
+ if (!(conf->magic_pkt_filter_add = kmalloc(MAGIC_PKT_FILTER_LEN, GFP_KERNEL))) {
+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+ } else {
+ memset(conf->magic_pkt_filter_add, 0, MAGIC_PKT_FILTER_LEN);
+ strcpy(conf->magic_pkt_filter_add, data);
+ printf("%s: magic_pkt_filter_add = %s\n", __FUNCTION__, conf->magic_pkt_filter_add);
}
- conf->magic_pkt_filter_add.count = i;
}
else
return false;
@@ -2007,13 +2177,6 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
conf->bus_rxglom = TRUE;
printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);
}
- else if (!strncmp("dhd_poll=", full_param, len_param)) {
- if (!strncmp(data, "0", 1))
- conf->dhd_poll = 0;
- else
- conf->dhd_poll = 1;
- printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);
- }
else if (!strncmp("deferred_tx_len=", full_param, len_param)) {
conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);
printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);
@@ -2048,6 +2211,27 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
}
#endif
+#ifdef BCMPCIE
+bool
+dhd_conf_read_pcie_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+ struct dhd_conf *conf = dhd->conf;
+ char *data = full_param+len_param;
+
+ if (!strncmp("bus:deepsleep_disable=", full_param, len_param)) {
+ if (!strncmp(data, "0", 1))
+ conf->bus_deepsleep_disable = 0;
+ else
+ conf->bus_deepsleep_disable = 1;
+ printf("%s: bus:deepsleep_disable = %d\n", __FUNCTION__, conf->bus_deepsleep_disable);
+ }
+ else
+ return false;
+
+ return true;
+}
+#endif
+
bool
dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
{
@@ -2088,6 +2272,15 @@ dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);
printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);
}
+#ifdef SUSPEND_EVENT
+ else if (!strncmp("suspend_eventmask_enable=", full_param, len_param)) {
+ if (!strncmp(data, "1", 1))
+ conf->suspend_eventmask_enable = TRUE;
+ else
+ conf->suspend_eventmask_enable = FALSE;
+ printf("%s: suspend_eventmask_enable = %d\n", __FUNCTION__, conf->suspend_eventmask_enable);
+ }
+#endif
else
return false;
@@ -2103,7 +2296,18 @@ dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
char *pch, *pick_tmp;
int i;
- if (!strncmp("band=", full_param, len_param)) {
+ if (!strncmp("dhd_poll=", full_param, len_param)) {
+ if (!strncmp(data, "0", 1))
+ conf->dhd_poll = 0;
+ else
+ conf->dhd_poll = 1;
+ printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);
+ }
+ else if (!strncmp("dhd_watchdog_ms=", full_param, len_param)) {
+ dhd_watchdog_ms = (int)simple_strtol(data, NULL, 10);
+ printf("%s: dhd_watchdog_ms = %d\n", __FUNCTION__, dhd_watchdog_ms);
+ }
+ else if (!strncmp("band=", full_param, len_param)) {
/* Process band:
* band=a for 5GHz only and band=b for 2.4GHz only
*/
@@ -2242,6 +2446,14 @@ dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
conf->tsq = (int)simple_strtol(data, NULL, 10);
printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);
}
+ else if (!strncmp("ctrl_resched=", full_param, len_param)) {
+ conf->ctrl_resched = (int)simple_strtol(data, NULL, 10);
+ printf("%s: ctrl_resched = %d\n", __FUNCTION__, conf->ctrl_resched);
+ }
+ else if (!strncmp("dhd_ioctl_timeout_msec=", full_param, len_param)) {
+ conf->dhd_ioctl_timeout_msec = (int)simple_strtol(data, NULL, 10);
+ printf("%s: dhd_ioctl_timeout_msec = %d\n", __FUNCTION__, conf->dhd_ioctl_timeout_msec);
+ }
else
return false;
@@ -2324,6 +2536,8 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
continue;
else if (dhd_conf_read_country_list(dhd, pick, len_param))
continue;
+ else if (dhd_conf_read_mchan_params(dhd, pick, len_param))
+ continue;
#ifdef PKT_FILTER_SUPPORT
else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))
continue;
@@ -2340,6 +2554,10 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
else if (dhd_conf_read_sdio_params(dhd, pick, len_param))
continue;
#endif /* BCMSDIO */
+#ifdef BCMPCIE
+ else if (dhd_conf_read_pcie_params(dhd, pick, len_param))
+ continue;
+#endif /* BCMPCIE */
else if (dhd_conf_read_pm_params(dhd, pick, len_param))
continue;
else if (dhd_conf_read_others(dhd, pick, len_param))
@@ -2435,6 +2653,7 @@ int
dhd_conf_preinit(dhd_pub_t *dhd)
{
struct dhd_conf *conf = dhd->conf;
+ int i;
CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -2443,6 +2662,10 @@ dhd_conf_preinit(dhd_pub_t *dhd)
dhd_conf_free_mac_list(&conf->nv_by_mac);
dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
#endif
+ dhd_conf_free_country_list(&conf->country_list);
+ dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);
+ if (conf->magic_pkt_filter_add)
+ kfree(conf->magic_pkt_filter_add);
memset(&conf->country_list, 0, sizeof(conf_country_list_t));
conf->band = -1;
conf->mimo_bw_cap = -1;
@@ -2499,7 +2722,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
#ifdef PKT_FILTER_SUPPORT
memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));
memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));
- memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t));
#endif
conf->srl = -1;
conf->lrl = -1;
@@ -2508,6 +2730,7 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->txbf = -1;
conf->lpc = -1;
conf->disable_proptx = -1;
+ conf->dhd_poll = -1;
#ifdef BCMSDIO
conf->bus_txglom = -1;
conf->use_rxchain = 0;
@@ -2515,7 +2738,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->txglom_ext = FALSE;
conf->tx_max_offset = 0;
conf->txglomsize = SDPCM_DEFGLOM_SIZE;
- conf->dhd_poll = -1;
conf->txctl_tmo_fix = 5;
conf->tx_in_rx = TRUE;
conf->txglom_mode = SDPCM_TXGLOM_MDESC;
@@ -2525,6 +2747,9 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->sd_f2_blocksize = 0;
conf->oob_enabled_later = FALSE;
#endif
+#ifdef BCMPCIE
+ conf->bus_deepsleep_disable = 1;
+#endif
conf->ampdu_ba_wsize = 0;
conf->ampdu_hostreorder = -1;
conf->dpc_cpucore = -1;
@@ -2537,6 +2762,11 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->num_different_channels = -1;
conf->xmit_in_suspend = TRUE;
conf->ap_in_suspend = 0;
+#ifdef SUSPEND_EVENT
+ conf->suspend_eventmask_enable = FALSE;
+ memset(&conf->suspend_eventmask, 0, sizeof(conf->suspend_eventmask));
+ memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));
+#endif
#ifdef IDHCP
conf->dhcpc_enable = -1;
conf->dhcpd_enable = -1;
@@ -2553,20 +2783,28 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->rsdb_mode = -2;
conf->vhtmode = -1;
conf->autocountry = -1;
+ conf->ctrl_resched = 2;
+ conf->dhd_ioctl_timeout_msec = 0;
#ifdef IAPSTA_PREINIT
memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init));
memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config));
memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable));
#endif
+ for (i=0; i<MCHAN_MAX_NUM; i++) {
+ memset(&conf->mchan[i], -1, sizeof(mchan_params_t));
+ }
#ifdef CUSTOMER_HW_AMLOGIC
dhd_slpauto = FALSE;
+ conf->txglom_mode = SDPCM_TXGLOM_CPY;
#endif
if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||
conf->chip == BCM4359_CHIP_ID) {
#ifdef DHDTCPACK_SUPPRESS
+#ifdef BCMSDIO
conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;
#endif
+#endif
dhd_rxbound = 128;
dhd_txbound = 64;
conf->txbf = 1;
@@ -2620,6 +2858,10 @@ dhd_conf_reset(dhd_pub_t *dhd)
dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
#endif
+ dhd_conf_free_country_list(&dhd->conf->country_list);
+ dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);
+ if (dhd->conf->magic_pkt_filter_add)
+ kfree(dhd->conf->magic_pkt_filter_add);
memset(dhd->conf, 0, sizeof(dhd_conf_t));
return 0;
}
@@ -2663,6 +2905,10 @@ dhd_conf_detach(dhd_pub_t *dhd)
dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
#endif
+ dhd_conf_free_country_list(&dhd->conf->country_list);
+ dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);
+ if (dhd->conf->magic_pkt_filter_add)
+ kfree(dhd->conf->magic_pkt_filter_add);
MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));
}
dhd->conf = NULL;
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_config.h b/bcmdhd.1.579.77.41.1.cn/dhd_config.h
index 5fdd538..ca295f1 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_config.h
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_config.h
@@ -23,7 +23,7 @@ extern uint dhd_slpauto;
#define BCM43430A0_CHIP_REV 0
#define BCM43430A1_CHIP_REV 1
#define BCM43430A2_CHIP_REV 2
-#define BCM43012B0_CHIP_REV 1
+#define BCM43013B0_CHIP_REV 1
#define BCM4330B2_CHIP_REV 4
#define BCM4334B1_CHIP_REV 3
#define BCM43341B0_CHIP_REV 2
@@ -31,13 +31,13 @@ extern uint dhd_slpauto;
#define BCM4335A0_CHIP_REV 2
#define BCM4339A0_CHIP_REV 1
#define BCM43455C0_CHIP_REV 6
-#define BCM43455C5_CHIP_REV 9
+#define BCM43456C5_CHIP_REV 9
#define BCM4354A1_CHIP_REV 1
#define BCM4359B1_CHIP_REV 5
-#define BCM4359C0_CHIP_REV 9
#endif
#define BCM4356A2_CHIP_REV 2
#define BCM4358A3_CHIP_REV 3
+#define BCM4359C0_CHIP_REV 9
typedef struct wl_mac_range {
uint32 oui;
@@ -82,6 +82,7 @@ typedef struct wmes_param {
#ifdef PKT_FILTER_SUPPORT
#define DHD_CONF_FILTER_MAX 8
#define PKT_FILTER_LEN 300
+#define MAGIC_PKT_FILTER_LEN 450
typedef struct conf_pkt_filter_add {
uint32 count;
char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];
@@ -96,9 +97,19 @@ typedef struct conf_pkt_filter_del {
#define CONFIG_COUNTRY_LIST_SIZE 100
typedef struct conf_country_list {
uint32 count;
- wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE];
+ wl_country_t *cspec[CONFIG_COUNTRY_LIST_SIZE];
} conf_country_list_t;
+/* mchan_params */
+#define MCHAN_MAX_NUM 4
+#define MIRACAST_SOURCE 1
+#define MIRACAST_SINK 2
+typedef struct mchan_params {
+ int bw;
+ int p2p_mode;
+ int miracast_mode;
+} mchan_params_t;
+
typedef struct dhd_conf {
uint chip;
uint chiprev;
@@ -106,6 +117,7 @@ typedef struct dhd_conf {
wl_mac_list_ctrl_t nv_by_mac;
wl_chip_nv_path_list_ctrl_t nv_by_chip;
conf_country_list_t country_list;
+ conf_country_list_t country_list_nodfs;
int band;
int mimo_bw_cap;
int bw_cap_2g;
@@ -114,7 +126,7 @@ typedef struct dhd_conf {
wl_channel_list_t channels;
uint roam_off;
uint roam_off_suspend;
- int roam_trigger[2];
+ int roam_trigger[2];
int roam_scan_period[2];
int roam_delta[2];
int fullroamperiod;
@@ -127,7 +139,7 @@ typedef struct dhd_conf {
#ifdef PKT_FILTER_SUPPORT
conf_pkt_filter_add_t pkt_filter_add;
conf_pkt_filter_del_t pkt_filter_del;
- conf_pkt_filter_add_t magic_pkt_filter_add;
+ char *magic_pkt_filter_add;
#endif
int srl;
int lrl;
@@ -136,6 +148,7 @@ typedef struct dhd_conf {
int txbf;
int lpc;
int disable_proptx;
+ int dhd_poll;
#ifdef BCMSDIO
int bus_txglom;
int use_rxchain;
@@ -148,7 +161,6 @@ typedef struct dhd_conf {
*/
int tx_max_offset;
uint txglomsize;
- int dhd_poll;
int txctl_tmo_fix;
bool tx_in_rx;
bool txglom_mode;
@@ -163,6 +175,9 @@ typedef struct dhd_conf {
uint sd_f2_blocksize;
bool oob_enabled_later;
#endif
+#ifdef BCMPCIE
+ int bus_deepsleep_disable;
+#endif
int ampdu_ba_wsize;
int ampdu_hostreorder;
int dpc_cpucore;
@@ -200,6 +215,9 @@ typedef struct dhd_conf {
char iapsta_enable[50];
#endif
int autocountry;
+ int ctrl_resched;
+ int dhd_ioctl_timeout_msec;
+ struct mchan_params mchan[MCHAN_MAX_NUM];
int tsq;
} dhd_conf_t;
@@ -224,14 +242,15 @@ int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def
int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx);
int dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, int len, bool down);
uint dhd_conf_get_band(dhd_pub_t *dhd);
-int dhd_conf_set_country(dhd_pub_t *dhd);
+int dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec);
int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);
-int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec);
+int dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs);
int dhd_conf_fix_country(dhd_pub_t *dhd);
bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);
int dhd_conf_set_roam(dhd_pub_t *dhd);
void dhd_conf_set_bw_cap(dhd_pub_t *dhd);
void dhd_conf_set_wme(dhd_pub_t *dhd, int mode);
+void dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int go, int source);
void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);
bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);
void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_gpio.c b/bcmdhd.1.579.77.41.1.cn/dhd_gpio.c
index 78537c8..1d2ce75 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_gpio.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_gpio.c
@@ -15,6 +15,9 @@
#include <linux/mmc/sdio_func.h>
#endif /* defined(BUS_POWER_RESTORE) && defined(BCMSDIO) */
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+extern void *bcmdhd_mem_prealloc(int section, unsigned long size);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
static int gpio_wl_reg_on = -1; // WL_REG_ON is input pin of WLAN module
#ifdef CUSTOMER_OOB
@@ -189,33 +192,21 @@ static int dhd_wlan_get_mac_addr(unsigned char *buf)
return err;
}
-#ifdef CONFIG_DHD_USE_STATIC_BUF
-extern void *bcmdhd_mem_prealloc(int section, unsigned long size);
-void* bcm_wlan_prealloc(int section, unsigned long size)
-{
- void *alloc_ptr = NULL;
- alloc_ptr = bcmdhd_mem_prealloc(section, size);
- if (alloc_ptr) {
- printf("success alloc section %d, size %ld\n", section, size);
- if (size != 0L)
- bzero(alloc_ptr, size);
- return alloc_ptr;
- }
- printf("can't alloc section %d\n", section);
- return NULL;
-}
-#endif
static struct cntry_locales_custom brcm_wlan_translate_custom_table[] = {
/* Table should be filled out based on custom platform regulatory requirement */
+#ifdef EXAMPLE_TABLE
{"", "XT", 49}, /* Universal if Country code is unknown or empty */
{"US", "US", 0},
+#endif /* EXMAPLE_TABLE */
};
#ifdef CUSTOM_FORCE_NODFS_FLAG
struct cntry_locales_custom brcm_wlan_translate_nodfs_table[] = {
+#ifdef EXAMPLE_TABLE
{"", "XT", 50}, /* Universal if Country code is unknown or empty */
{"US", "US", 0},
+#endif /* EXMAPLE_TABLE */
};
#endif
@@ -266,7 +257,7 @@ struct wifi_platform_data dhd_wlan_control = {
.set_carddetect = dhd_wlan_set_carddetect,
.get_mac_addr = dhd_wlan_get_mac_addr,
#ifdef CONFIG_DHD_USE_STATIC_BUF
- .mem_prealloc = bcm_wlan_prealloc,
+ .mem_prealloc = bcmdhd_mem_prealloc,
#endif /* CONFIG_DHD_USE_STATIC_BUF */
.get_country_code = dhd_wlan_get_country_code,
};
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_linux.c b/bcmdhd.1.579.77.41.1.cn/dhd_linux.c
index 3bf901c..70944f5 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_linux.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_linux.c
@@ -10995,7 +10995,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
if (ret < 0)
printf("%s: country code setting failed %d\n", __FUNCTION__, ret);
} else {
- dhd_conf_set_country(dhd);
+ dhd_conf_map_country_list(dhd, &dhd->conf->cspec, 0);
+ dhd_conf_set_country(dhd, &dhd->conf->cspec);
dhd_conf_fix_country(dhd);
}
dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "autocountry", dhd->conf->autocountry, 0, FALSE);
@@ -11678,6 +11679,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
// terence 20151210: set bus:txglom after dhd_txglom_enable since it's possible changed in dhd_conf_set_txglom_params
dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bus:txglom", dhd->conf->bus_txglom, 0, FALSE);
#endif /* defined(BCMSDIO) */
+#if defined(BCMPCIE)
+ dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bus:deepsleep_disable", dhd->conf->bus_deepsleep_disable, 0, FALSE);
+#endif /* defined(BCMPCIE) */
#if defined(BCMSDIO)
#ifdef PROP_TXSTATUS
@@ -12861,14 +12865,14 @@ void dhd_detach(dhd_pub_t *dhdp)
dhd->new_freq = NULL;
cpufreq_unregister_notifier(&dhd->freq_trans, CPUFREQ_TRANSITION_NOTIFIER);
#endif
+ DHD_TRACE(("wd wakelock count:%d\n", dhd->wakelock_wd_counter));
#ifdef CONFIG_HAS_WAKELOCK
dhd->wakelock_wd_counter = 0;
wake_lock_destroy(&dhd->wl_wdwake);
- // terence 20161023: can not destroy wl_wifi when wlan down, it will happen null pointer in dhd_ioctl_entry
- wake_lock_destroy(&dhd->wl_wifi);
+ // terence 20161023: can not destroy wl_wifi when wlan down, it will happen null pointer in dhd_ioctl_entry
+ wake_lock_destroy(&dhd->wl_wifi);
#endif /* CONFIG_HAS_WAKELOCK */
if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) {
- DHD_TRACE(("wd wakelock count:%d\n", dhd->wakelock_wd_counter));
DHD_OS_WAKE_LOCK_DESTROY(dhd);
}
@@ -13215,10 +13219,15 @@ dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
}
int
-dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition)
+dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool resched)
{
dhd_info_t * dhd = (dhd_info_t *)(pub->info);
- int timeout;
+ int timeout, timeout_tmp = dhd_ioctl_timeout_msec;
+
+ if (!resched && pub->conf->ctrl_resched>0 && pub->conf->dhd_ioctl_timeout_msec>0) {
+ timeout_tmp = dhd_ioctl_timeout_msec;
+ dhd_ioctl_timeout_msec = pub->conf->dhd_ioctl_timeout_msec;
+ }
/* Convert timeout in millsecond to jiffies */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
@@ -13231,6 +13240,10 @@ dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition)
timeout = wait_event_timeout(dhd->ioctl_resp_wait, (*condition), timeout);
+ if (!resched && pub->conf->ctrl_resched>0 && pub->conf->dhd_ioctl_timeout_msec>0) {
+ dhd_ioctl_timeout_msec = timeout_tmp;
+ }
+
DHD_PERIM_LOCK(pub);
return timeout;
@@ -13631,19 +13644,23 @@ dhd_os_sdunlock_txq(dhd_pub_t *pub)
void
dhd_os_sdlock_rxq(dhd_pub_t *pub)
{
+#if 0
dhd_info_t *dhd;
dhd = (dhd_info_t *)(pub->info);
spin_lock_bh(&dhd->rxqlock);
+#endif
}
void
dhd_os_sdunlock_rxq(dhd_pub_t *pub)
{
+#if 0
dhd_info_t *dhd;
dhd = (dhd_info_t *)(pub->info);
spin_unlock_bh(&dhd->rxqlock);
+#endif
}
static void
@@ -14124,6 +14141,9 @@ dhd_dev_get_feature_set(struct net_device *dev)
if (dhd_is_pno_supported(dhd)) {
feature_set |= WIFI_FEATURE_PNO;
#ifdef GSCAN_SUPPORT
+ /* terence 20171115: remove to get GTS PASS
+ * com.google.android.gts.wifi.WifiHostTest#testWifiScannerBatchTimestamp
+ */
// feature_set |= WIFI_FEATURE_GSCAN;
// feature_set |= WIFI_FEATURE_HAL_EPNO;
#endif /* GSCAN_SUPPORT */
@@ -15675,6 +15695,7 @@ void dhd_get_customized_country_code(struct net_device *dev, char *country_iso_c
BCM_REFERENCE(dhd);
}
+
void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify)
{
dhd_info_t *dhd = DHD_DEV_INFO(dev);
@@ -19135,6 +19156,7 @@ static void dhd_sysfs_exit(dhd_info_t *dhd)
DHD_ERROR(("%s(): dhd is NULL \r\n", __FUNCTION__));
return;
}
+
if (&dhd->dhd_kobj != NULL)
kobject_put(&dhd->dhd_kobj);
}
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c b/bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c
index e602d24..455f125 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c
@@ -52,6 +52,7 @@
#include <pcie_core.h>
#include <bcmpcie.h>
#include <dhd_pcie.h>
+#include <dhd_config.h>
#ifdef DHD_TIMESYNC
#include <dhd_timesync.h>
#endif /* DHD_TIMESYNC */
@@ -6013,6 +6014,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
int timeleft;
unsigned long flags;
int ret = 0;
+ static uint cnt = 0;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -6021,7 +6023,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
goto out;
}
- timeleft = dhd_os_ioctl_resp_wait(dhd, (uint *)&prot->ioctl_received);
+ timeleft = dhd_os_ioctl_resp_wait(dhd, (uint *)&prot->ioctl_received, false);
#ifdef DHD_RECOVER_TIMEOUT
if (prot->ioctl_received == 0) {
@@ -6053,6 +6055,25 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
}
#endif /* DHD_RECOVER_TIMEOUT */
+ if (dhd->conf->ctrl_resched > 0 && timeleft == 0 && (!dhd_query_bus_erros(dhd))) {
+ cnt++;
+ if (cnt <= dhd->conf->ctrl_resched) {
+ uint32 intstatus = 0, intmask = 0;
+ intstatus = si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, PCIMailBoxInt, 0, 0);
+ intmask = si_corereg(dhd->bus->sih, dhd->bus->sih->buscoreidx, PCIMailBoxMask, 0, 0);
+ if (intstatus) {
+ DHD_ERROR(("%s: reschedule dhd_dpc, cnt=%d, intstatus=0x%x, intmask=0x%x\n",
+ __FUNCTION__, cnt, intstatus, intmask));
+ dhd->bus->ipend = TRUE;
+ dhd->bus->dpc_sched = TRUE;
+ dhd_sched_dpc(dhd);
+ timeleft = dhd_os_ioctl_resp_wait(dhd, &prot->ioctl_received, true);
+ }
+ }
+ } else {
+ cnt = 0;
+ }
+
if (timeleft == 0 && (!dhd_query_bus_erros(dhd))) {
uint32 intstatus;
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_pcie.c b/bcmdhd.1.579.77.41.1.cn/dhd_pcie.c
index 77995b5..48e3d19 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_pcie.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_pcie.c
@@ -497,7 +497,9 @@ uint32
dhdpcie_bus_intstatus(dhd_bus_t *bus)
{
uint32 intstatus = 0;
+#ifndef DHD_READ_INTSTATUS_IN_DPC
uint32 intmask = 0;
+#endif /* DHD_READ_INTSTATUS_IN_DPC */
if ((bus->dhd->busstate == DHD_BUS_SUSPEND || bus->d3_suspend_pending) &&
bus->wait_for_d3_ack) {
@@ -521,10 +523,12 @@ dhdpcie_bus_intstatus(dhd_bus_t *bus)
/* this is a PCIE core register..not a config register... */
intstatus = si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxInt, 0, 0);
+#ifndef DHD_READ_INTSTATUS_IN_DPC
/* this is a PCIE core register..not a config register... */
intmask = si_corereg(bus->sih, bus->sih->buscoreidx, PCIMailBoxMask, 0, 0);
intstatus &= intmask;
+#endif /* DHD_READ_INTSTATUS_IN_DPC */
/* Is device removed. intstatus & intmask read 0xffffffff */
if (intstatus == (uint32)-1) {
DHD_ERROR(("%s: Device is removed or Link is down.\n", __FUNCTION__));
@@ -600,6 +604,7 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
}
}
+#ifndef DHD_READ_INTSTATUS_IN_DPC
intstatus = dhdpcie_bus_intstatus(bus);
/* Check if the interrupt is ours or not */
@@ -627,6 +632,7 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
/* Count the interrupt call */
bus->intrcount++;
+#endif /* DHD_READ_INTSTATUS_IN_DPC */
bus->ipend = TRUE;
@@ -1008,6 +1014,8 @@ dhdpcie_dongle_attach(dhd_bus_t *bus)
/* Set the poll and/or interrupt flags */
bus->intr = (bool)dhd_intr;
+ if ((bus->poll = (bool)dhd_poll))
+ bus->pollrate = 1;
bus->wait_for_d3_ack = 1;
#ifdef PCIE_OOB
@@ -1530,6 +1538,14 @@ bool dhd_bus_watchdog(dhd_pub_t *dhd)
}
}
+#ifdef DHD_READ_INTSTATUS_IN_DPC
+ if (bus->poll) {
+ bus->ipend = TRUE;
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd); /* queue DPC now!! */
+ }
+#endif /* DHD_READ_INTSTATUS_IN_DPC */
+
#if defined(PCIE_OOB) || defined(PCIE_INB_DW)
/* If haven't communicated with device for a while, deassert the Device_Wake GPIO */
if (dhd_doorbell_timeout != 0 && dhd->busstate == DHD_BUS_DATA &&
@@ -1639,6 +1655,17 @@ dhd_set_path_params(struct dhd_bus *bus)
}
+void
+dhd_set_bus_params(struct dhd_bus *bus)
+{
+ if (bus->dhd->conf->dhd_poll >= 0) {
+ bus->poll = bus->dhd->conf->dhd_poll;
+ if (!bus->pollrate)
+ bus->pollrate = 1;
+ printf("%s: set polling mode %d\n", __FUNCTION__, bus->dhd->conf->dhd_poll);
+ }
+}
+
static int
dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh)
{
@@ -1680,6 +1707,7 @@ dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh)
DHD_OS_WAKE_LOCK(bus->dhd);
dhd_set_path_params(bus);
+ dhd_set_bus_params(bus);
ret = _dhdpcie_download_firmware(bus);
@@ -6066,10 +6094,24 @@ dhd_bus_dpc(struct dhd_bus *bus)
DHD_BUS_BUSY_SET_IN_DPC(bus->dhd);
DHD_GENERAL_UNLOCK(bus->dhd, flags);
+#ifdef DHD_READ_INTSTATUS_IN_DPC
+ if (bus->ipend) {
+ bus->ipend = FALSE;
+ bus->intstatus = dhdpcie_bus_intstatus(bus);
+ /* Check if the interrupt is ours or not */
+ if (bus->intstatus == 0) {
+ goto INTR_ON;
+ }
+ bus->intrcount++;
+ }
+#endif /* DHD_READ_INTSTATUS_IN_DPC */
resched = dhdpcie_bus_process_mailbox_intr(bus, bus->intstatus);
if (!resched) {
bus->intstatus = 0;
+#ifdef DHD_READ_INTSTATUS_IN_DPC
+INTR_ON:
+#endif /* DHD_READ_INTSTATUS_IN_DPC */
bus->dpc_intr_enable_count++;
dhdpcie_bus_intr_enable(bus); /* Enable back interrupt using Intmask!! */
}
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_pcie.h b/bcmdhd.1.579.77.41.1.cn/dhd_pcie.h
index eb8de62..92b07c6 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_pcie.h
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_pcie.h
@@ -259,6 +259,7 @@ typedef struct dhd_bus {
struct pktq txq; /* Queue length used for flow-control */
bool intr; /* Use interrupts */
+ bool poll; /* Use polling */
bool ipend; /* Device interrupt is pending */
bool intdis; /* Interrupts disabled by isr */
uint intrcount; /* Count of device interrupt callbacks */
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c b/bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c
index 51664a7..5c9561a 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c
@@ -1029,10 +1029,22 @@ dhdpcie_request_irq(dhdpcie_info_t *dhdpcie_info)
if (!bus->irq_registered) {
snprintf(dhdpcie_info->pciname, sizeof(dhdpcie_info->pciname),
"dhdpcie:%s", pci_name(pdev));
+#ifdef DHD_USE_MSI
+ printf("%s: MSI enabled\n", __FUNCTION__);
+ err = pci_enable_msi(pdev);
+ if (err < 0) {
+ DHD_ERROR(("%s: pci_enable_msi() failed, %d, fall back to INTx\n", __FUNCTION__, err));
+ }
+#else
+ printf("%s: MSI not enabled\n", __FUNCTION__);
+#endif /* DHD_USE_MSI */
err = request_irq(pdev->irq, dhdpcie_isr, IRQF_SHARED,
dhdpcie_info->pciname, bus);
if (err) {
DHD_ERROR(("%s: request_irq() failed\n", __FUNCTION__));
+#ifdef DHD_USE_MSI
+ pci_disable_msi(pdev);
+#endif /* DHD_USE_MSI */
return -1;
} else {
bus->irq_registered = TRUE;
@@ -1497,6 +1509,9 @@ dhdpcie_free_irq(dhd_bus_t *bus)
if (bus->irq_registered) {
free_irq(pdev->irq, bus);
bus->irq_registered = FALSE;
+#ifdef DHD_USE_MSI
+ pci_disable_msi(pdev);
+#endif /* DHD_USE_MSI */
} else {
DHD_ERROR(("%s: PCIe IRQ is not registered\n", __FUNCTION__));
}
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_pno.c b/bcmdhd.1.579.77.41.1.cn/dhd_pno.c
index c553733..c20ed7b 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_pno.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_pno.c
@@ -910,6 +910,7 @@ exit:
bytes_written = (int32)(bp - buf);
return bytes_written;
}
+
static int
_dhd_pno_clear_all_batch_results(dhd_pub_t *dhd, struct list_head *head, bool only_last)
{
@@ -992,6 +993,7 @@ _dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan)
exit:
return err;
}
+
static int
_dhd_pno_reinitialize_prof(dhd_pub_t *dhd, dhd_pno_params_t *params, dhd_pno_mode_t mode)
{
@@ -1084,6 +1086,7 @@ _dhd_pno_reinitialize_prof(dhd_pub_t *dhd, dhd_pno_params_t *params, dhd_pno_mod
mutex_unlock(&_pno_state->pno_mutex);
return err;
}
+
static int
_dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid)
{
@@ -4007,6 +4010,7 @@ exit:
kfree(buf);
return err;
}
+
int dhd_pno_deinit(dhd_pub_t *dhd)
{
int err = BCME_OK;
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c b/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
index 1dcdd28..fe2e874 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
@@ -696,7 +696,7 @@ static int dhdsdio_txpkt_preprocess(dhd_bus_t *bus, void *pkt, int chan, int txs
int prev_chain_total_len, bool last_chained_pkt,
int *pad_pkt_len, void **new_pkt
#if defined(BCMSDIOH_TXGLOM_EXT)
- , int frist_frame
+ , int first_frame
#endif
);
static int dhdsdio_txpkt_postprocess(dhd_bus_t *bus, void *pkt);
@@ -1040,7 +1040,7 @@ dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on)
uint8 wr_val = 0, rd_val, cmp_val, bmask;
int err = 0;
int try_cnt = 0;
- return 0;
+
KSO_DBG(("%s> op:%s\n", __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR")));
wr_val |= (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
@@ -2910,6 +2910,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
{
int timeleft;
uint rxlen = 0;
+ static uint cnt = 0;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -2917,7 +2918,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
return -EIO;
/* Wait until control frame is available */
- timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen);
+ timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, false);
dhd_os_sdlock(bus->dhd);
rxlen = bus->rxlen;
@@ -2925,6 +2926,32 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
bus->rxlen = 0;
dhd_os_sdunlock(bus->dhd);
+ if (bus->dhd->conf->ctrl_resched > 0 && !rxlen && timeleft == 0) {
+ cnt++;
+ if (cnt <= bus->dhd->conf->ctrl_resched) {
+ uint32 status, retry = 0;
+ R_SDREG(status, &bus->regs->intstatus, retry);
+ if ((status & I_HMB_HOST_INT) || PKT_AVAILABLE(bus, status)) {
+ DHD_ERROR(("%s: reschedule dhd_dpc, cnt=%d, status=0x%x\n",
+ __FUNCTION__, cnt, status));
+ bus->ipend = TRUE;
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+
+ /* Wait until control frame is available */
+ timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, true);
+
+ dhd_os_sdlock(bus->dhd);
+ rxlen = bus->rxlen;
+ bcopy(bus->rxctl, msg, MIN(msglen, rxlen));
+ bus->rxlen = 0;
+ dhd_os_sdunlock(bus->dhd);
+ }
+ }
+ } else {
+ cnt = 0;
+ }
+
if (rxlen) {
DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n",
__FUNCTION__, rxlen, msglen));
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c b/bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c
index 50573e4..33997cd 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c
@@ -73,7 +73,7 @@ enum dhd_prealloc_index {
#define DHD_PREALLOC_OSL_BUF_SIZE (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
#define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)
#define DHD_PREALLOC_DHD_INFO_SIZE (30 * 1024)
-#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (770 * 1024)
+#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (810 * 1024)
#define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE (73 * 1024)
#define DHD_PREALLOC_WL_ESCAN_INFO_SIZE (66 * 1024)
#ifdef CONFIG_64BIT
diff --git a/bcmdhd.1.579.77.41.1.cn/include/epivers.h b/bcmdhd.1.579.77.41.1.cn/include/epivers.h
index 4cf4c70..a2dc35e 100644
--- a/bcmdhd.1.579.77.41.1.cn/include/epivers.h
+++ b/bcmdhd.1.579.77.41.1.cn/include/epivers.h
@@ -46,6 +46,6 @@
#define EPI_VERSION_DEV 1.579.77.41
/* Driver Version String, ASCII, 32 chars max */
-#define EPI_VERSION_STR "1.579.77.41.2 (r)"
+#define EPI_VERSION_STR "1.579.77.41.3 (r)"
#endif /* _epivers_h_ */
diff --git a/bcmdhd.1.579.77.41.1.cn/include/wlioctl.h b/bcmdhd.1.579.77.41.1.cn/include/wlioctl.h
index 82c4b4f..1e6a3a2 100644
--- a/bcmdhd.1.579.77.41.1.cn/include/wlioctl.h
+++ b/bcmdhd.1.579.77.41.1.cn/include/wlioctl.h
@@ -11554,13 +11554,6 @@ typedef struct wl_interface_create {
struct ether_addr mac_addr; /* Optional Mac address */
} wl_interface_create_t;
-typedef struct wl_interface_create_v0 {
- uint16 ver; /* version of this struct */
- struct ether_addr mac_addr; /* MAC address of the interface */
- char ifname[BCM_MSG_IFNAME_MAX]; /* name of interface */
- uint8 bsscfgidx; /* source bsscfg index */
-} wl_interface_info_t;
-
typedef struct wl_interface_create_v1 {
uint16 ver; /**< version of this struct */
uint8 pad1[2]; /**< Padding bytes */
diff --git a/bcmdhd.1.579.77.41.1.cn/wl_android_ext.c b/bcmdhd.1.579.77.41.1.cn/wl_android_ext.c
index 507edc1..6265338 100644
--- a/bcmdhd.1.579.77.41.1.cn/wl_android_ext.c
+++ b/bcmdhd.1.579.77.41.1.cn/wl_android_ext.c
@@ -1,150 +1,150 @@
-
-
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <net/netlink.h>
-
-#include <wl_android.h>
-#include <wldev_common.h>
-#include <wlioctl.h>
-#include <bcmutils.h>
-#include <linux_osl.h>
-#include <dhd_dbg.h>
-#include <dngl_stats.h>
-#include <dhd.h>
-#include <dhd_config.h>
-
-#define htod32(i) i
-#define htod16(i) i
-#define dtoh32(i) i
-#define dtoh16(i) i
-#define htodchanspec(i) i
-#define dtohchanspec(i) i
-#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
-
-#define CMD_CHANNEL "CHANNEL"
-#define CMD_CHANNELS "CHANNELS"
-#define CMD_ROAM_TRIGGER "ROAM_TRIGGER"
-#define CMD_KEEP_ALIVE "KEEP_ALIVE"
-#define CMD_PM "PM"
-#define CMD_MONITOR "MONITOR"
-#define CMD_SET_SUSPEND_BCN_LI_DTIM "SET_SUSPEND_BCN_LI_DTIM"
-
-#ifdef WL_EXT_IAPSTA
-#define CMD_IAPSTA_INIT "IAPSTA_INIT"
-#define CMD_IAPSTA_CONFIG "IAPSTA_CONFIG"
-#define CMD_IAPSTA_ENABLE "IAPSTA_ENABLE"
-#define CMD_IAPSTA_DISABLE "IAPSTA_DISABLE"
-#ifdef PROP_TXSTATUS
-#ifdef PROP_TXSTATUS_VSDB
-#include <dhd_wlfc.h>
+
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/netlink.h>
+
+#include <wl_android.h>
+#include <wldev_common.h>
+#include <wlioctl.h>
+#include <bcmutils.h>
+#include <linux_osl.h>
+#include <dhd_dbg.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_config.h>
+
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
+#define dtohchanspec(i) i
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+
+#define CMD_CHANNEL "CHANNEL"
+#define CMD_CHANNELS "CHANNELS"
+#define CMD_ROAM_TRIGGER "ROAM_TRIGGER"
+#define CMD_KEEP_ALIVE "KEEP_ALIVE"
+#define CMD_PM "PM"
+#define CMD_MONITOR "MONITOR"
+#define CMD_SET_SUSPEND_BCN_LI_DTIM "SET_SUSPEND_BCN_LI_DTIM"
+
+#ifdef WL_EXT_IAPSTA
+#define CMD_IAPSTA_INIT "IAPSTA_INIT"
+#define CMD_IAPSTA_CONFIG "IAPSTA_CONFIG"
+#define CMD_IAPSTA_ENABLE "IAPSTA_ENABLE"
+#define CMD_IAPSTA_DISABLE "IAPSTA_DISABLE"
+#ifdef PROP_TXSTATUS
+#ifdef PROP_TXSTATUS_VSDB
+#include <dhd_wlfc.h>
extern int disable_proptx;
-#endif /* PROP_TXSTATUS_VSDB */
-#endif
-#endif
-#ifdef IDHCP
-#define CMD_DHCPC_ENABLE "DHCPC_ENABLE"
-#define CMD_DHCPC_DUMP "DHCPC_DUMP"
-#endif
-#define CMD_WL "WL"
-
-#define IEEE80211_BAND_2GHZ 0
-#define IEEE80211_BAND_5GHZ 1
-
-int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
-{
- int ret;
-
- ret = wldev_ioctl(dev, cmd, arg, len, set);
- if (ret)
- ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret));
- return ret;
-}
-
-int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val)
-{
- int ret;
-
- ret = wldev_iovar_getint(dev, iovar, val);
- if (ret)
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));
-
- return ret;
-}
-
-int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val)
-{
- int ret;
-
- ret = wldev_iovar_setint(dev, iovar, val);
- if (ret)
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));
-
- return ret;
-}
-
-int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
-{
- int ret;
-
- ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);
- if (ret != 0)
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));
-
- return ret;
-}
-
-int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
-{
- int ret;
-
- ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);
- if (ret != 0)
- ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));
-
- return ret;
-}
-
-#ifdef WL_EXT_IAPSTA
-int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
-{
- int ret;
-
- ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen,
- buf, buflen, bsscfg_idx, buf_sync);
- if (ret < 0)
- ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));
-
- return ret;
-}
-
-int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name,
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
-{
- int ret;
-
- ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen,
- buf, buflen, bsscfg_idx, buf_sync);
- if (ret < 0)
- ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));
-
- return ret;
-}
-#endif
+#endif /* PROP_TXSTATUS_VSDB */
+#endif
+#endif
+#ifdef IDHCP
+#define CMD_DHCPC_ENABLE "DHCPC_ENABLE"
+#define CMD_DHCPC_DUMP "DHCPC_DUMP"
+#endif
+#define CMD_WL "WL"
+
+#define IEEE80211_BAND_2GHZ 0
+#define IEEE80211_BAND_5GHZ 1
+
+int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
+{
+ int ret;
+
+ ret = wldev_ioctl(dev, cmd, arg, len, set);
+ if (ret)
+ ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret));
+ return ret;
+}
+
+int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val)
+{
+ int ret;
+
+ ret = wldev_iovar_getint(dev, iovar, val);
+ if (ret)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val)
+{
+ int ret;
+
+ ret = wldev_iovar_setint(dev, iovar, val);
+ if (ret)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);
+ if (ret != 0)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);
+ if (ret != 0)
+ ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+
+#ifdef WL_EXT_IAPSTA
+int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen,
+ buf, buflen, bsscfg_idx, buf_sync);
+ if (ret < 0)
+ ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+
+int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name,
+ void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
+{
+ int ret;
+
+ ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen,
+ buf, buflen, bsscfg_idx, buf_sync);
+ if (ret < 0)
+ ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));
+
+ return ret;
+}
+#endif
/* Return a legacy chanspec given a new chanspec
* Returns INVCHANSPEC on error
*/
static chanspec_t
-wl_ext_chspec_to_legacy(chanspec_t chspec)
+wl_ext_chspec_to_legacy(chanspec_t chspec)
{
chanspec_t lchspec;
if (wf_chspec_malformed(chspec)) {
- ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n",
+ ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n",
chspec));
return INVCHANSPEC;
}
@@ -173,25 +173,25 @@ wl_ext_chspec_to_legacy(chanspec_t chspec)
} else {
/* cannot express the bandwidth */
char chanbuf[CHANSPEC_STR_LEN];
- ANDROID_ERROR((
- "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "
+ ANDROID_ERROR((
+ "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "
"to pre-11ac format\n",
wf_chspec_ntoa(chspec, chanbuf), chspec));
return INVCHANSPEC;
}
return lchspec;
-}
+}
/* given a chanspec value, do the endian and chanspec version conversion to
* a chanspec_t value
* Returns INVCHANSPEC on error
*/
static chanspec_t
-wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)
+wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)
{
- if (ioctl_ver == 1) {
- chanspec = wl_ext_chspec_to_legacy(chanspec);
+ if (ioctl_ver == 1) {
+ chanspec = wl_ext_chspec_to_legacy(chanspec);
if (chanspec == INVCHANSPEC) {
return chanspec;
}
@@ -199,99 +199,99 @@ wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)
chanspec = htodchanspec(chanspec);
return chanspec;
-}
-
-static int
-wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver)
-{
- int ret = 0;
- s32 val = 0;
-
- val = 1;
- ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0);
- if (ret) {
- ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret));
- return ret;
- }
- val = dtoh32(val);
- if (val != WLC_IOCTL_VERSION && val != 1) {
- ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
- val, WLC_IOCTL_VERSION));
- return BCME_VERSION;
- }
- *ioctl_ver = val;
-
- return ret;
-}
-
-static int
-wl_ext_set_chanspec(struct net_device *dev, uint16 channel)
-{
- s32 _chan = channel;
+}
+
+static int
+wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver)
+{
+ int ret = 0;
+ s32 val = 0;
+
+ val = 1;
+ ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0);
+ if (ret) {
+ ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret));
+ return ret;
+ }
+ val = dtoh32(val);
+ if (val != WLC_IOCTL_VERSION && val != 1) {
+ ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+ val, WLC_IOCTL_VERSION));
+ return BCME_VERSION;
+ }
+ *ioctl_ver = val;
+
+ return ret;
+}
+
+static int
+wl_ext_set_chanspec(struct net_device *dev, uint16 channel)
+{
+ s32 _chan = channel;
chanspec_t chspec = 0;
- chanspec_t fw_chspec = 0;
- u32 bw = WL_CHANSPEC_BW_20;
+ chanspec_t fw_chspec = 0;
+ u32 bw = WL_CHANSPEC_BW_20;
s32 err = BCME_OK;
- s32 bw_cap = 0;
- s8 iovar_buf[WLC_IOCTL_SMLEN];
+ s32 bw_cap = 0;
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
struct {
u32 band;
u32 bw_cap;
- } param = {0, 0};
- uint band;
- int ioctl_ver = 0;
-
- if (_chan <= CH_MAX_2G_CHANNEL)
- band = IEEE80211_BAND_2GHZ;
- else
- band = IEEE80211_BAND_5GHZ;
- wl_ext_get_ioctl_ver(dev, &ioctl_ver);
-
- if (band == IEEE80211_BAND_5GHZ) {
+ } param = {0, 0};
+ uint band;
+ int ioctl_ver = 0;
+
+ if (_chan <= CH_MAX_2G_CHANNEL)
+ band = IEEE80211_BAND_2GHZ;
+ else
+ band = IEEE80211_BAND_5GHZ;
+ wl_ext_get_ioctl_ver(dev, &ioctl_ver);
+
+ if (band == IEEE80211_BAND_5GHZ) {
param.band = WLC_BAND_5G;
err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
if (err) {
if (err != BCME_UNSUPPORTED) {
- ANDROID_ERROR(("bw_cap failed, %d\n", err));
+ ANDROID_ERROR(("bw_cap failed, %d\n", err));
return err;
} else {
err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
if (err) {
- ANDROID_ERROR(("error get mimo_bw_cap (%d)\n", err));
+ ANDROID_ERROR(("error get mimo_bw_cap (%d)\n", err));
}
if (bw_cap != WLC_N_BW_20ALL)
bw = WL_CHANSPEC_BW_40;
}
} else {
- if (WL_BW_CAP_80MHZ(iovar_buf[0]))
+ if (WL_BW_CAP_80MHZ(iovar_buf[0]))
bw = WL_CHANSPEC_BW_80;
- else if (WL_BW_CAP_40MHZ(iovar_buf[0]))
+ else if (WL_BW_CAP_40MHZ(iovar_buf[0]))
bw = WL_CHANSPEC_BW_40;
else
bw = WL_CHANSPEC_BW_20;
- }
- }
- else if (band == IEEE80211_BAND_2GHZ)
- bw = WL_CHANSPEC_BW_20;
-
+ }
+ }
+ else if (band == IEEE80211_BAND_2GHZ)
+ bw = WL_CHANSPEC_BW_20;
+
set_channel:
chspec = wf_channel2chspec(_chan, bw);
if (wf_chspec_valid(chspec)) {
- fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec);
+ fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec);
if (fw_chspec != INVCHANSPEC) {
- if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) {
+ if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) {
if (bw == WL_CHANSPEC_BW_80)
- goto change_bw;
- wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);
- printf("%s: channel %d\n", __FUNCTION__, _chan);
+ goto change_bw;
+ wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);
+ printf("%s: channel %d\n", __FUNCTION__, _chan);
} else if (err) {
- ANDROID_ERROR(("%s: failed to set chanspec error %d\n", __FUNCTION__, err));
- } else
- printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec);
+ ANDROID_ERROR(("%s: failed to set chanspec error %d\n", __FUNCTION__, err));
+ } else
+ printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec);
} else {
- ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__));
+ ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__));
err = BCME_ERROR;
}
} else {
@@ -304,1875 +304,1973 @@ change_bw:
bw = 0;
if (bw)
goto set_channel;
- ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec));
+ ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec));
err = BCME_ERROR;
- }
-
- return err;
-}
-
-int
-wl_ext_channel(struct net_device *dev, char* command, int total_len)
-{
- int ret;
- int channel=0;
- channel_info_t ci;
- int bytes_written = 0;
-
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
-
- sscanf(command, "%*s %d", &channel);
-
- if (channel > 0) {
- ret = wl_ext_set_chanspec(dev, channel);
- } else {
- if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
- ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel));
- ANDROID_TRACE(("target_channel %d\n", ci.target_channel));
- ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel));
- bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
- }
-
- return ret;
-}
-
-int
-wl_ext_channels(struct net_device *dev, char* command, int total_len)
-{
- int ret, i;
- int bytes_written = -1;
- u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
- wl_uint32_list_t *list;
-
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
-
- memset(valid_chan_list, 0, sizeof(valid_chan_list));
- list = (wl_uint32_list_t *)(void *) valid_chan_list;
- list->count = htod32(WL_NUMCHANNELS);
- ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0);
- if (ret<0) {
- ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret));
- } else {
- bytes_written = snprintf(command, total_len, "channels");
- for (i = 0; i < dtoh32(list->count); i++) {
- bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i]));
- printf("%d ", dtoh32(list->element[i]));
- }
- printf("\n");
- ret = bytes_written;
- }
-
- return ret;
-}
-
-int
-wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len)
-{
- int ret = 0;
- int roam_trigger[2] = {0, 0};
- int trigger[2]= {0, 0};
- int bytes_written=-1;
-
- sscanf(command, "%*s %10d", &roam_trigger[0]);
-
- if (roam_trigger[0]) {
- roam_trigger[1] = WLC_BAND_ALL;
- ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1);
- if (ret)
- ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
- } else {
- roam_trigger[1] = WLC_BAND_2G;
- ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);
- if (!ret)
- trigger[0] = roam_trigger[0];
- else
- ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
-
- roam_trigger[1] = WLC_BAND_5G;
- ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);
- if (!ret)
- trigger[1] = roam_trigger[0];
- else
- ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
-
- ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1]));
- bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]);
- ret = bytes_written;
- }
-
- return ret;
-}
-
-static int
-wl_ext_pattern_atoh(char *src, char *dst)
-{
- int i;
- if (strncmp(src, "0x", 2) != 0 &&
- strncmp(src, "0X", 2) != 0) {
- ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n"));
- return -1;
- }
- src = src + 2; /* Skip past 0x */
- if (strlen(src) % 2 != 0) {
- DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));
- return -1;
- }
- for (i = 0; *src != '\0'; i++) {
- char num[3];
- bcm_strncpy_s(num, sizeof(num), src, 2);
- num[2] = '\0';
- dst[i] = (uint8)strtoul(num, NULL, 16);
- src += 2;
- }
- return i;
-}
-
-int
-wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)
-{
- wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
- int ret = -1, i;
- int id, period=-1, len_bytes=0, buf_len=0;
- char data[200]="\0";
- char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0";
- int bytes_written = -1;
-
- ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command));
- sscanf(command, "%*s %d %d %s", &id, &period, data);
- ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data));
-
- if (period >= 0) {
- mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf;
- mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION);
- mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
- mkeep_alive_pktp->keep_alive_id = id;
- buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
- mkeep_alive_pktp->period_msec = period;
- if (strlen(data)) {
- len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data);
- buf_len += len_bytes;
- }
- mkeep_alive_pktp->len_bytes = htod16(len_bytes);
-
- ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len,
- iovar_buf, sizeof(iovar_buf), NULL);
- } else {
- if (id < 0)
- id = 0;
- ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL);
- if (ret) {
- goto exit;
- } else {
- mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;
- printf("Id :%d\n"
- "Period (msec) :%d\n"
- "Length :%d\n"
- "Packet :0x",
- mkeep_alive_pktp->keep_alive_id,
- dtoh32(mkeep_alive_pktp->period_msec),
- dtoh16(mkeep_alive_pktp->len_bytes));
- for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
- printf("%02x", mkeep_alive_pktp->data[i]);
- }
- printf("\n");
- }
- bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec));
- bytes_written += snprintf(command+bytes_written, total_len, "0x");
- for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
- bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]);
- }
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
-
-exit:
- return ret;
-}
-
-int
-wl_ext_pm(struct net_device *dev, char *command, int total_len)
-{
- int pm=-1, ret = -1;
- char *pm_local;
- int bytes_written=-1;
-
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
-
- sscanf(command, "%*s %d", &pm);
-
- if (pm >= 0) {
- ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE);
- if (ret)
- ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret));
- } else {
- ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE);
- if (!ret) {
- ANDROID_TRACE(("%s: PM = %d\n", __func__, pm));
- if (pm == PM_OFF)
- pm_local = "PM_OFF";
- else if(pm == PM_MAX)
- pm_local = "PM_MAX";
- else if(pm == PM_FAST)
- pm_local = "PM_FAST";
- else {
- pm = 0;
- pm_local = "Invalid";
- }
- bytes_written = snprintf(command, total_len, "PM %s", pm_local);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
- }
-
- return ret;
-}
-
-static int
-wl_ext_monitor(struct net_device *dev, char *command, int total_len)
-{
- int val, ret = -1;
- int bytes_written=-1;
-
- sscanf(command, "%*s %d", &val);
-
- if (val >=0) {
- ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1);
- if (ret)
- ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret));
- } else {
- ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE);
- if (!ret) {
- ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val));
- bytes_written = snprintf(command, total_len, "monitor %d", val);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
- }
-
- return ret;
-}
-
-#ifdef WL_EXT_IAPSTA
-struct wl_apsta_params g_apsta_params;
-static int
-wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)
-{
- char hex[] = "XX";
- unsigned char *data = wsec_key->data;
- char *keystr = key;
-
- switch (strlen(keystr)) {
- case 5:
- case 13:
- case 16:
- wsec_key->len = strlen(keystr);
- memcpy(data, keystr, wsec_key->len + 1);
- break;
- case 12:
- case 28:
- case 34:
- case 66:
- /* strip leading 0x */
- if (!strnicmp(keystr, "0x", 2))
- keystr += 2;
- else
- return -1;
- /* fall through */
- case 10:
- case 26:
- case 32:
- case 64:
- wsec_key->len = strlen(keystr) / 2;
- while (*keystr) {
- strncpy(hex, keystr, 2);
- *data++ = (char) strtoul(hex, NULL, 16);
- keystr += 2;
- }
- break;
- default:
- return -1;
- }
-
- switch (wsec_key->len) {
- case 5:
- wsec_key->algo = CRYPTO_ALGO_WEP1;
- break;
- case 13:
- wsec_key->algo = CRYPTO_ALGO_WEP128;
- break;
- case 16:
- /* default to AES-CCM */
- wsec_key->algo = CRYPTO_ALGO_AES_CCM;
- break;
- case 32:
- wsec_key->algo = CRYPTO_ALGO_TKIP;
- break;
- default:
- return -1;
- }
-
- /* Set as primary wsec_key by default */
- wsec_key->flags |= WL_PRIMARY_KEY;
-
- return 0;
-}
-
-static int
-wl_ext_set_bgnmode(struct wl_if_info *cur_if)
-{
- struct net_device *dev = cur_if->dev;
- bgnmode_t bgnmode = cur_if->bgnmode;
- int val;
-
- if (bgnmode == 0)
- return 0;
-
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- if (bgnmode == IEEE80211B) {
- wl_ext_iovar_setint(dev, "nmode", 0);
- val = 0;
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
- ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__));
- } else if (bgnmode == IEEE80211G) {
- wl_ext_iovar_setint(dev, "nmode", 0);
- val = 2;
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
- ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__));
- } else if (bgnmode == IEEE80211BG) {
- wl_ext_iovar_setint(dev, "nmode", 0);
- val = 1;
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
- ANDROID_TRACE(("%s: Network mode: : B/G mixed\n", __FUNCTION__));
- } else if (bgnmode == IEEE80211BGN) {
- wl_ext_iovar_setint(dev, "nmode", 0);
- wl_ext_iovar_setint(dev, "nmode", 1);
- wl_ext_iovar_setint(dev, "vhtmode", 0);
- val = 1;
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
- ANDROID_TRACE(("%s: Network mode: : B/G/N mixed\n", __FUNCTION__));
- } else if (bgnmode == IEEE80211BGNAC) {
- wl_ext_iovar_setint(dev, "nmode", 0);
- wl_ext_iovar_setint(dev, "nmode", 1);
- wl_ext_iovar_setint(dev, "vhtmode", 1);
- val = 1;
- wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
- ANDROID_TRACE(("%s: Network mode: : B/G/N/AC mixed\n", __FUNCTION__));
- }
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
-
- return 0;
-}
-
-static int
-wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)
-{
- struct net_device *dev = cur_if->dev;
- authmode_t amode = cur_if->amode;
- int auth=0, wpa_auth=0;
-
- if (amode == AUTH_OPEN) {
- auth = 0;
- wpa_auth = 0;
- ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__));
- } else if (amode == AUTH_SHARED) {
- auth = 1;
- wpa_auth = 0;
- ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__));
- } else if (amode == AUTH_WPAPSK) {
- auth = 0;
- wpa_auth = 4;
- ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__));
- } else if (amode == AUTH_WPA2PSK) {
- auth = 0;
- wpa_auth = 128;
- ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__));
- } else if (amode == AUTH_WPAWPA2PSK) {
- auth = 0;
- wpa_auth = 132;
- ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__));
- }
- wl_ext_iovar_setint(dev, "auth", auth);
-
- wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);
-
- return 0;
-}
-
-static int
-wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)
-{
- struct net_device *dev = cur_if->dev;
- int wsec=0;
- struct wl_wsec_key wsec_key;
- wsec_pmk_t psk;
- encmode_t emode = cur_if->emode;
- char *key = cur_if->key;
-
- memset(&wsec_key, 0, sizeof(wsec_key));
- memset(&psk, 0, sizeof(psk));
- if (emode == ENC_NONE) {
- wsec = 0;
- ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__));
- } else if (emode == ENC_WEP) {
- wsec = 1;
- wl_ext_parse_wep(key, &wsec_key);
- ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__));
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, wsec_key.data));
- } else if (emode == ENC_TKIP) {
- wsec = 2;
- psk.key_len = strlen(key);
- psk.flags = WSEC_PASSPHRASE;
- memcpy(psk.key, key, strlen(key));
- ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__));
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));
- } else if (emode == ENC_AES) {
- wsec = 4;
- psk.key_len = strlen(key);
- psk.flags = WSEC_PASSPHRASE;
- memcpy(psk.key, key, strlen(key));
- ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__));
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));
- } else if (emode == ENC_TKIPAES) {
- wsec = 6;
- psk.key_len = strlen(key);
- psk.flags = WSEC_PASSPHRASE;
- memcpy(psk.key, key, strlen(key));
- ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__));
- ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));
- }
-
- wl_ext_iovar_setint(dev, "wsec", wsec);
-
- if (wsec == 1) {
- wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1);
- } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) {
- if (dev) {
- if (cur_if->ifmode == ISTA_MODE)
- wl_ext_iovar_setint(dev, "sup_wpa", 1);
- wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1);
- } else {
- ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__));
- }
- }
-
- return 0;
-}
-
-static int
-wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
-{
- s32 val = 0;
- char *pch, *pick_tmp, *param;
- wlc_ssid_t ssid = { 0, {0} };
- s8 iovar_buf[WLC_IOCTL_SMLEN];
- struct wl_apsta_params *apsta_params = &g_apsta_params;
- wl_interface_create_t iface;
- struct dhd_pub *dhd;
- wl_p2p_if_t ifreq;
-
- if (apsta_params->init) {
- ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));
- return -1;
- }
-
- dhd = dhd_get_pub(dev);
- memset(apsta_params, 0, sizeof(struct wl_apsta_params));
-
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
-
- pick_tmp = command;
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init
- param = bcmstrtok(&pick_tmp, " ", 0);
- while (param != NULL) {
- if (!strcmp(param, "mode")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch) {
- if (!strcmp(pch, "sta")) {
- apsta_params->apstamode = ISTAONLY_MODE;
- } else if (!strcmp(pch, "ap")) {
- apsta_params->apstamode = IAPONLY_MODE;
- } else if (!strcmp(pch, "apsta")) {
- apsta_params->apstamode = IAPSTA_MODE;
- } else if (!strcmp(pch, "dualap")) {
- apsta_params->apstamode = IDUALAP_MODE;
- } else if (!strcmp(pch, "gosta")) {
- if (!FW_SUPPORTED(dhd, p2p)) {
- return -1;
- }
- apsta_params->apstamode = IGOSTA_MODE;
- } else if (!strcmp(pch, "gcsta")) {
- if (!FW_SUPPORTED(dhd, p2p)) {
- return -1;
- }
- apsta_params->apstamode = IGCSTA_MODE;
- } else {
- ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
- return -1;
- }
- }
- } else if (!strcmp(param, "vifname")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- strcpy(apsta_params->vif.ifname, pch);
- else {
- ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__));
- return -1;
- }
- }
- param = bcmstrtok(&pick_tmp, " ", 0);
- }
-
- if (apsta_params->apstamode == 0) {
- ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
- return -1;
- }
-
- apsta_params->pif.dev = dev;
- apsta_params->pif.bssidx = 0;
- strcpy(apsta_params->pif.ifname, dev->name);
- strcpy(apsta_params->pif.ssid, "tttp");
- apsta_params->pif.maxassoc = -1;
- apsta_params->pif.channel = 1;
-
- if (!strlen(apsta_params->vif.ifname))
- strcpy(apsta_params->vif.ifname, "wlan1");
- strcpy(apsta_params->vif.ssid, "tttv");
- apsta_params->vif.maxassoc = -1;
- apsta_params->vif.channel = 1;
-
- if (apsta_params->apstamode == ISTAONLY_MODE) {
- apsta_params->pif.ifmode = ISTA_MODE;
- apsta_params->pif.ifstate = IF_STATE_INIT;
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls
- // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- } else if (apsta_params->apstamode == IAPONLY_MODE) {
- apsta_params->pif.ifmode = IAP_MODE;
- apsta_params->pif.ifstate = IF_STATE_INIT;
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ }
+
+ return err;
+}
+
+int
+wl_ext_channel(struct net_device *dev, char* command, int total_len)
+{
+ int ret;
+ int channel=0;
+ channel_info_t ci;
+ int bytes_written = 0;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%*s %d", &channel);
+
+ if (channel > 0) {
+ ret = wl_ext_set_chanspec(dev, channel);
+ } else {
+ if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
+ ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel));
+ ANDROID_TRACE(("target_channel %d\n", ci.target_channel));
+ ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel));
+ bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+int
+wl_ext_channels(struct net_device *dev, char* command, int total_len)
+{
+ int ret, i;
+ int bytes_written = -1;
+ u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+ wl_uint32_list_t *list;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ memset(valid_chan_list, 0, sizeof(valid_chan_list));
+ list = (wl_uint32_list_t *)(void *) valid_chan_list;
+ list->count = htod32(WL_NUMCHANNELS);
+ ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0);
+ if (ret<0) {
+ ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret));
+ } else {
+ bytes_written = snprintf(command, total_len, "channels");
+ for (i = 0; i < dtoh32(list->count); i++) {
+ bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i]));
+ printf("%d ", dtoh32(list->element[i]));
+ }
+ printf("\n");
+ ret = bytes_written;
+ }
+
+ return ret;
+}
+
+int
+wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len)
+{
+ int ret = 0;
+ int roam_trigger[2] = {0, 0};
+ int trigger[2]= {0, 0};
+ int bytes_written=-1;
+
+ sscanf(command, "%*s %10d", &roam_trigger[0]);
+
+ if (roam_trigger[0]) {
+ roam_trigger[1] = WLC_BAND_ALL;
+ ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1);
+ if (ret)
+ ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
+ } else {
+ roam_trigger[1] = WLC_BAND_2G;
+ ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);
+ if (!ret)
+ trigger[0] = roam_trigger[0];
+ else
+ ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
+
+ roam_trigger[1] = WLC_BAND_5G;
+ ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);
+ if (!ret)
+ trigger[1] = roam_trigger[0];
+ else
+ ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));
+
+ ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1]));
+ bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]);
+ ret = bytes_written;
+ }
+
+ return ret;
+}
+
+static int
+wl_ext_pattern_atoh(char *src, char *dst)
+{
+ int i;
+ if (strncmp(src, "0x", 2) != 0 &&
+ strncmp(src, "0X", 2) != 0) {
+ ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+ return -1;
+ }
+ src = src + 2; /* Skip past 0x */
+ if (strlen(src) % 2 != 0) {
+ DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));
+ return -1;
+ }
+ for (i = 0; *src != '\0'; i++) {
+ char num[3];
+ bcm_strncpy_s(num, sizeof(num), src, 2);
+ num[2] = '\0';
+ dst[i] = (uint8)strtoul(num, NULL, 16);
+ src += 2;
+ }
+ return i;
+}
+
+int
+wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)
+{
+ wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
+ int ret = -1, i;
+ int id, period=-1, len_bytes=0, buf_len=0;
+ char data[200]="\0";
+ char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0";
+ int bytes_written = -1;
+
+ ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command));
+ sscanf(command, "%*s %d %d %s", &id, &period, data);
+ ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data));
+
+ if (period >= 0) {
+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf;
+ mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION);
+ mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
+ mkeep_alive_pktp->keep_alive_id = id;
+ buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
+ mkeep_alive_pktp->period_msec = period;
+ if (strlen(data)) {
+ len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data);
+ buf_len += len_bytes;
+ }
+ mkeep_alive_pktp->len_bytes = htod16(len_bytes);
+
+ ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len,
+ iovar_buf, sizeof(iovar_buf), NULL);
+ } else {
+ if (id < 0)
+ id = 0;
+ ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL);
+ if (ret) {
+ goto exit;
+ } else {
+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;
+ printf("Id :%d\n"
+ "Period (msec) :%d\n"
+ "Length :%d\n"
+ "Packet :0x",
+ mkeep_alive_pktp->keep_alive_id,
+ dtoh32(mkeep_alive_pktp->period_msec),
+ dtoh16(mkeep_alive_pktp->len_bytes));
+ for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
+ printf("%02x", mkeep_alive_pktp->data[i]);
+ }
+ printf("\n");
+ }
+ bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec));
+ bytes_written += snprintf(command+bytes_written, total_len, "0x");
+ for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
+ bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]);
+ }
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+
+exit:
+ return ret;
+}
+
+int
+wl_ext_pm(struct net_device *dev, char *command, int total_len)
+{
+ int pm=-1, ret = -1;
+ char *pm_local;
+ int bytes_written=-1;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%*s %d", &pm);
+
+ if (pm >= 0) {
+ ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE);
+ if (ret)
+ ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret));
+ } else {
+ ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE);
+ if (!ret) {
+ ANDROID_TRACE(("%s: PM = %d\n", __func__, pm));
+ if (pm == PM_OFF)
+ pm_local = "PM_OFF";
+ else if(pm == PM_MAX)
+ pm_local = "PM_MAX";
+ else if(pm == PM_FAST)
+ pm_local = "PM_FAST";
+ else {
+ pm = 0;
+ pm_local = "Invalid";
+ }
+ bytes_written = snprintf(command, total_len, "PM %s", pm_local);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+static int
+wl_ext_monitor(struct net_device *dev, char *command, int total_len)
+{
+ int val, ret = -1;
+ int bytes_written=-1;
+
+ sscanf(command, "%*s %d", &val);
+
+ if (val >=0) {
+ ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1);
+ if (ret)
+ ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret));
+ } else {
+ ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE);
+ if (!ret) {
+ ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val));
+ bytes_written = snprintf(command, total_len, "monitor %d", val);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+#ifdef WL_EXT_IAPSTA
+struct wl_apsta_params g_apsta_params;
+static int
+wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)
+{
+ char hex[] = "XX";
+ unsigned char *data = wsec_key->data;
+ char *keystr = key;
+
+ switch (strlen(keystr)) {
+ case 5:
+ case 13:
+ case 16:
+ wsec_key->len = strlen(keystr);
+ memcpy(data, keystr, wsec_key->len + 1);
+ break;
+ case 12:
+ case 28:
+ case 34:
+ case 66:
+ /* strip leading 0x */
+ if (!strnicmp(keystr, "0x", 2))
+ keystr += 2;
+ else
+ return -1;
+ /* fall through */
+ case 10:
+ case 26:
+ case 32:
+ case 64:
+ wsec_key->len = strlen(keystr) / 2;
+ while (*keystr) {
+ strncpy(hex, keystr, 2);
+ *data++ = (char) strtoul(hex, NULL, 16);
+ keystr += 2;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ switch (wsec_key->len) {
+ case 5:
+ wsec_key->algo = CRYPTO_ALGO_WEP1;
+ break;
+ case 13:
+ wsec_key->algo = CRYPTO_ALGO_WEP128;
+ break;
+ case 16:
+ /* default to AES-CCM */
+ wsec_key->algo = CRYPTO_ALGO_AES_CCM;
+ break;
+ case 32:
+ wsec_key->algo = CRYPTO_ALGO_TKIP;
+ break;
+ default:
+ return -1;
+ }
+
+ /* Set as primary wsec_key by default */
+ wsec_key->flags |= WL_PRIMARY_KEY;
+
+ return 0;
+}
+
+static int
+wl_ext_set_bgnmode(struct wl_if_info *cur_if)
+{
+ struct net_device *dev = cur_if->dev;
+ bgnmode_t bgnmode = cur_if->bgnmode;
+ int val;
+
+ if (bgnmode == 0)
+ return 0;
+
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ if (bgnmode == IEEE80211B) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ val = 0;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211G) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ val = 2;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211BG) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B/G mixed\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211BGN) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ wl_ext_iovar_setint(dev, "nmode", 1);
+ wl_ext_iovar_setint(dev, "vhtmode", 0);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B/G/N mixed\n", __FUNCTION__));
+ } else if (bgnmode == IEEE80211BGNAC) {
+ wl_ext_iovar_setint(dev, "nmode", 0);
+ wl_ext_iovar_setint(dev, "nmode", 1);
+ wl_ext_iovar_setint(dev, "vhtmode", 1);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);
+ ANDROID_TRACE(("%s: Network mode: B/G/N/AC mixed\n", __FUNCTION__));
+ }
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+
+ return 0;
+}
+
+static int
+wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)
+{
+ struct net_device *dev = cur_if->dev;
+ authmode_t amode = cur_if->amode;
+ int auth=0, wpa_auth=0;
+
+ if (amode == AUTH_OPEN) {
+ auth = 0;
+ wpa_auth = 0;
+ ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__));
+ } else if (amode == AUTH_SHARED) {
+ auth = 1;
+ wpa_auth = 0;
+ ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__));
+ } else if (amode == AUTH_WPAPSK) {
+ auth = 0;
+ wpa_auth = 4;
+ ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__));
+ } else if (amode == AUTH_WPA2PSK) {
+ auth = 0;
+ wpa_auth = 128;
+ ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__));
+ } else if (amode == AUTH_WPAWPA2PSK) {
+ auth = 0;
+ wpa_auth = 132;
+ ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__));
+ }
+ wl_ext_iovar_setint(dev, "auth", auth);
+
+ wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);
+
+ return 0;
+}
+
+static int
+wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)
+{
+ struct net_device *dev = cur_if->dev;
+ int wsec=0;
+ struct wl_wsec_key wsec_key;
+ wsec_pmk_t psk;
+ encmode_t emode = cur_if->emode;
+ char *key = cur_if->key;
+
+ memset(&wsec_key, 0, sizeof(wsec_key));
+ memset(&psk, 0, sizeof(psk));
+ if (emode == ENC_NONE) {
+ wsec = 0;
+ ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__));
+ } else if (emode == ENC_WEP) {
+ wsec = 1;
+ wl_ext_parse_wep(key, &wsec_key);
+ ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, wsec_key.data));
+ } else if (emode == ENC_TKIP) {
+ wsec = 2;
+ psk.key_len = strlen(key);
+ psk.flags = WSEC_PASSPHRASE;
+ memcpy(psk.key, key, strlen(key));
+ ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, psk.key));
+ } else if (emode == ENC_AES) {
+ wsec = 4;
+ psk.key_len = strlen(key);
+ psk.flags = WSEC_PASSPHRASE;
+ memcpy(psk.key, key, strlen(key));
+ ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, psk.key));
+ } else if (emode == ENC_TKIPAES) {
+ wsec = 6;
+ psk.key_len = strlen(key);
+ psk.flags = WSEC_PASSPHRASE;
+ memcpy(psk.key, key, strlen(key));
+ ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__));
+ ANDROID_TRACE(("%s: Key: \"%s\"\n", __FUNCTION__, psk.key));
+ }
+
+ wl_ext_iovar_setint(dev, "wsec", wsec);
+
+ if (wsec == 1) {
+ wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1);
+ } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) {
+ if (dev) {
+ if (cur_if->ifmode == ISTA_MODE)
+ wl_ext_iovar_setint(dev, "sup_wpa", 1);
+ wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1);
+ } else {
+ ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__));
+ }
+ }
+
+ return 0;
+}
+
+static int
+wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)
+{
+ s32 val = 0;
+ char *pch, *pick_tmp, *param;
+ wlc_ssid_t ssid = { 0, {0} };
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ wl_interface_create_t iface;
+ struct dhd_pub *dhd;
+ wl_p2p_if_t ifreq;
+ wl_country_t cspec = {{0}, 0, {0}};
+
+ if (apsta_params->init) {
+ ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));
+ return -1;
+ }
+
+ dhd = dhd_get_pub(dev);
+ memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ while (param != NULL) {
+ if (!strcmp(param, "mode")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch) {
+ if (!strcmp(pch, "sta")) {
+ apsta_params->apstamode = ISTAONLY_MODE;
+ } else if (!strcmp(pch, "ap")) {
+ apsta_params->apstamode = IAPONLY_MODE;
+ } else if (!strcmp(pch, "apsta")) {
+ apsta_params->apstamode = IAPSTA_MODE;
+ } else if (!strcmp(pch, "dualap")) {
+ apsta_params->apstamode = IDUALAP_MODE;
+ } else if (!strcmp(pch, "gosta")) {
+ if (!FW_SUPPORTED(dhd, p2p)) {
+ return -1;
+ }
+ apsta_params->apstamode = IGOSTA_MODE;
+ } else if (!strcmp(pch, "gcsta")) {
+ if (!FW_SUPPORTED(dhd, p2p)) {
+ return -1;
+ }
+ apsta_params->apstamode = IGCSTA_MODE;
+ } else {
+ ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ } else if (!strcmp(param, "vifname")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch)
+ strcpy(apsta_params->vif.ifname, pch);
+ else {
+ ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ }
+
+ if (apsta_params->apstamode == 0) {
+ ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
+ return -1;
+ }
+
+ apsta_params->pif.dev = dev;
+ apsta_params->pif.bssidx = 0;
+ strcpy(apsta_params->pif.ifname, dev->name);
+ strcpy(apsta_params->pif.ssid, "tttp");
+ apsta_params->pif.maxassoc = -1;
+ apsta_params->pif.channel = 1;
+
+ if (!strlen(apsta_params->vif.ifname))
+ strcpy(apsta_params->vif.ifname, "wlan1");
+ strcpy(apsta_params->vif.ssid, "tttv");
+ apsta_params->vif.maxassoc = -1;
+ apsta_params->vif.channel = 1;
+
+ if (apsta_params->apstamode == ISTAONLY_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls
+ // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ } else if (apsta_params->apstamode == IAPONLY_MODE) {
+ apsta_params->pif.ifmode = IAP_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ dhd_conf_get_country(dhd, &cspec);
+ if (!dhd_conf_map_country_list(dhd, &cspec, 1)) {
+ dhd_conf_set_country(dhd, &cspec);
+ dhd_bus_country_set(dev, &cspec, TRUE);
+ }
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is enabled, disable arpoe */
- dhd_arp_offload_set(dhd, 0);
- dhd_arp_offload_enable(dhd, FALSE);
-#endif /* ARP_OFFLOAD_SUPPORT */
- wl_ext_iovar_setint(dev, "mpc", 0);
- wl_ext_iovar_setint(dev, "apsta", 0);
- val = 1;
- wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
- } else if (apsta_params->apstamode == IAPSTA_MODE) {
- apsta_params->pif.ifmode = ISTA_MODE;
- apsta_params->pif.ifstate = IF_STATE_INIT;
- apsta_params->vif.ifmode = IAP_MODE;
- apsta_params->vif.ifstate = IF_STATE_INIT;
- wl_ext_iovar_setint(dev, "mpc", 0);
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- wl_ext_iovar_setint(dev, "apsta", 1);
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- if (FW_SUPPORTED(dhd, rsdb)) {
- bzero(&iface, sizeof(wl_interface_create_t));
- iface.ver = WL_INTERFACE_CREATE_VER;
- iface.flags = WL_INTERFACE_CREATE_AP;
- wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,
- WLC_IOCTL_SMLEN, 1, NULL);
- } else {
- wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,
- WLC_IOCTL_SMLEN, 1, NULL);
- }
- }
- else if (apsta_params->apstamode == IDUALAP_MODE) {
- apsta_params->pif.ifmode = IAP_MODE;
- apsta_params->pif.ifstate = IF_STATE_INIT;
- apsta_params->vif.ifmode = IAP_MODE;
- apsta_params->vif.ifstate = IF_STATE_INIT;
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- wl_ext_iovar_setint(dev, "apsta", 0);
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- val = 1;
- wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
- /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */
+ /* IF SoftAP is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ wl_ext_iovar_setint(dev, "mpc", 0);
+ wl_ext_iovar_setint(dev, "apsta", 0);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
+ } else if (apsta_params->apstamode == IAPSTA_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = IAP_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ dhd_conf_get_country(dhd, &cspec);
+ if (!dhd_conf_map_country_list(dhd, &cspec, 1)) {
+ dhd_conf_set_country(dhd, &cspec);
+ dhd_bus_country_set(dev, &cspec, TRUE);
+ }
+ wl_ext_iovar_setint(dev, "mpc", 0);
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ if (FW_SUPPORTED(dhd, rsdb)) {
+ bzero(&iface, sizeof(wl_interface_create_t));
+ iface.ver = WL_INTERFACE_CREATE_VER;
+ iface.flags = WL_INTERFACE_CREATE_AP;
+ wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface),
+ iovar_buf, WLC_IOCTL_SMLEN, 1, NULL);
+ } else {
+ wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,
+ WLC_IOCTL_SMLEN, 1, NULL);
+ }
+ }
+ else if (apsta_params->apstamode == IDUALAP_MODE) {
+ apsta_params->pif.ifmode = IAP_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = IAP_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ dhd_conf_get_country(dhd, &cspec);
+ if (!dhd_conf_map_country_list(dhd, &cspec, 1)) {
+ dhd_conf_set_country(dhd, &cspec);
+ dhd_bus_country_set(dev, &cspec, TRUE);
+ }
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 0);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
+ /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */
#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is enabled, disable arpoe */
- dhd_arp_offload_set(dhd, 0);
- dhd_arp_offload_enable(dhd, FALSE);
-#endif /* ARP_OFFLOAD_SUPPORT */
- bzero(&iface, sizeof(wl_interface_create_t));
- iface.ver = WL_INTERFACE_CREATE_VER;
- iface.flags = WL_INTERFACE_CREATE_AP;
- wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,
- WLC_IOCTL_SMLEN, 1, NULL);
- }
- else if (apsta_params->apstamode == IGOSTA_MODE) {
- apsta_params->pif.ifmode = ISTA_MODE;
- apsta_params->pif.ifstate = IF_STATE_INIT;
- apsta_params->vif.ifmode = IAP_MODE;
- apsta_params->vif.ifstate = IF_STATE_INIT;
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- wl_ext_iovar_setint(dev, "apsta", 1);
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- bzero(&ifreq, sizeof(wl_p2p_if_t));
- ifreq.type = htod32(WL_P2P_IF_GO);
- wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);
- }
- else if (apsta_params->apstamode == IGCSTA_MODE) {
- apsta_params->pif.ifmode = ISTA_MODE;
- apsta_params->pif.ifstate = IF_STATE_INIT;
- apsta_params->vif.ifmode = ISTA_MODE;
- apsta_params->vif.ifstate = IF_STATE_INIT;
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- wl_ext_iovar_setint(dev, "apsta", 1);
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- bzero(&ifreq, sizeof(wl_p2p_if_t));
- ifreq.type = htod32(WL_P2P_IF_CLIENT);
- wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);
- }
-
- wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
- printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);
-
- apsta_params->init = TRUE;
-
- return 0;
-}
-
-static int
-wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)
-{
- int i;
- char *pch, *pick_tmp, *param;
- struct wl_apsta_params *apsta_params = &g_apsta_params;
- char ifname[IFNAMSIZ+1];
- struct wl_if_info *cur_if = &apsta_params->pif;
-
- if (!apsta_params->init) {
- ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
- return -1;
- }
-
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
-
- pick_tmp = command;
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config
- param = bcmstrtok(&pick_tmp, " ", 0);
-
- if (param != NULL) {
- if (strcmp(param, "ifname")) {
- ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__));
- return -1;
- }
- }
-
- while (param != NULL) {
- if (!strcmp(param, "ifname")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- strcpy(ifname, pch);
- else {
- ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
- return -1;
- }
- if (!strcmp(apsta_params->pif.dev->name, ifname)) {
- cur_if = &apsta_params->pif;
- } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
- cur_if = &apsta_params->vif;
- } else {
- ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__,
- ifname, apsta_params->apstamode));
- return -1;
- }
- } else if (!strcmp(param, "ssid")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- strcpy(cur_if->ssid, pch);
- } else if (!strcmp(param, "bssid")) {
- pch = bcmstrtok(&pick_tmp, ": ", 0);
- for (i=0; i<6 && pch; i++) {
- ((u8 *)&cur_if->bssid)[i] = (int)simple_strtol(pch, NULL, 16);
- pch = bcmstrtok(&pick_tmp, ": ", 0);
- }
- } else if (!strcmp(param, "bgnmode")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch) {
- if (!strcmp(pch, "b"))
- cur_if->bgnmode = IEEE80211B;
- else if (!strcmp(pch, "g"))
- cur_if->bgnmode = IEEE80211G;
- else if (!strcmp(pch, "bg"))
- cur_if->bgnmode = IEEE80211BG;
- else if (!strcmp(pch, "bgn"))
- cur_if->bgnmode = IEEE80211BGN;
- else if (!strcmp(pch, "bgnac"))
- cur_if->bgnmode = IEEE80211BGNAC;
- else {
- ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__));
- return -1;
- }
- }
- } else if (!strcmp(param, "hidden")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch) {
- if (!strcmp(pch, "n"))
- cur_if->hidden = 0;
- else if (!strcmp(pch, "y"))
- cur_if->hidden = 1;
- else {
- ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__));
- return -1;
- }
- }
- } else if (!strcmp(param, "maxassoc")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- cur_if->maxassoc = (int)simple_strtol(pch, NULL, 10);
- } else if (!strcmp(param, "chan")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- cur_if->channel = (int)simple_strtol(pch, NULL, 10);
- } else if (!strcmp(param, "amode")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch) {
- if (!strcmp(pch, "open"))
- cur_if->amode = AUTH_OPEN;
- else if (!strcmp(pch, "shared"))
- cur_if->amode = AUTH_SHARED;
- else if (!strcmp(pch, "wpapsk"))
- cur_if->amode = AUTH_WPAPSK;
- else if (!strcmp(pch, "wpa2psk"))
- cur_if->amode = AUTH_WPA2PSK;
- else if (!strcmp(pch, "wpawpa2psk"))
- cur_if->amode = AUTH_WPAWPA2PSK;
- else {
- ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n",
- __FUNCTION__));
- return -1;
- }
- }
- } else if (!strcmp(param, "emode")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch) {
- if (!strcmp(pch, "none"))
- cur_if->emode = ENC_NONE;
- else if (!strcmp(pch, "wep"))
- cur_if->emode = ENC_WEP;
- else if (!strcmp(pch, "tkip"))
- cur_if->emode = ENC_TKIP;
- else if (!strcmp(pch, "aes"))
- cur_if->emode = ENC_AES;
- else if (!strcmp(pch, "tkipaes"))
- cur_if->emode = ENC_TKIPAES;
- else {
- ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n",
- __FUNCTION__));
- return -1;
- }
- }
- } else if (!strcmp(param, "key")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch) {
- strcpy(cur_if->key, pch);
- }
- }
- param = bcmstrtok(&pick_tmp, " ", 0);
- }
-
- return 0;
-}
-
-static int
-wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
-{
- char *pch, *pick_tmp, *param;
- s8 iovar_buf[WLC_IOCTL_SMLEN];
- wlc_ssid_t ssid = { 0, {0} };
- scb_val_t scbval;
- struct {
- s32 tmp;
+ /* IF SoftAP is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ bzero(&iface, sizeof(wl_interface_create_t));
+ iface.ver = WL_INTERFACE_CREATE_VER;
+ iface.flags = WL_INTERFACE_CREATE_AP;
+ wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface),
+ iovar_buf, WLC_IOCTL_SMLEN, 1, NULL);
+ }
+ else if (apsta_params->apstamode == IGOSTA_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = IAP_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ bzero(&ifreq, sizeof(wl_p2p_if_t));
+ ifreq.type = htod32(WL_P2P_IF_GO);
+ wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+ else if (apsta_params->apstamode == IGCSTA_MODE) {
+ apsta_params->pif.ifmode = ISTA_MODE;
+ apsta_params->pif.ifstate = IF_STATE_INIT;
+ apsta_params->vif.ifmode = ISTA_MODE;
+ apsta_params->vif.ifstate = IF_STATE_INIT;
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_iovar_setint(dev, "apsta", 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ bzero(&ifreq, sizeof(wl_p2p_if_t));
+ ifreq.type = htod32(WL_P2P_IF_CLIENT);
+ wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+ wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
+ printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);
+
+ apsta_params->init = TRUE;
+
+ return 0;
+}
+
+static int
+wl_ext_parse_config(struct wl_if_info *cur_if, char *command, char **pick_next)
+{
+ char *pch, *pick_tmp;
+ char name[20], data[100];
+ int i, j;
+ char *ifname_head = NULL;
+
+ typedef struct config_map_t {
+ char name[20];
+ char *head;
+ char *tail;
+ } config_map_t;
+
+ config_map_t config_map [] = {
+ {" ifname ", NULL, NULL},
+ {" ssid ", NULL, NULL},
+ {" bssid ", NULL, NULL},
+ {" bgnmode ", NULL, NULL},
+ {" hidden ", NULL, NULL},
+ {" maxassoc ", NULL, NULL},
+ {" chan ", NULL, NULL},
+ {" amode ", NULL, NULL},
+ {" emode ", NULL, NULL},
+ {" key ", NULL, NULL},
+ };
+ config_map_t *row, *row_prev;
+
+ pick_tmp = command;
+
+ // reset head and tail
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ row->head = NULL;
+ row->tail = pick_tmp + strlen(pick_tmp);;
+ }
+
+ // pick head
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ pch = strstr(pick_tmp, row->name);
+ if (pch) {
+ row->head = pch;
+ }
+ }
+
+ // sort by head
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]) - 1; i++) {
+ row_prev = &config_map[i];
+ for (j = i+1; j < sizeof(config_map)/sizeof(config_map[0]); j++) {
+ row = &config_map[j];
+ if (row->head < row_prev->head) {
+ strcpy(name, row_prev->name);
+ strcpy(row_prev->name, row->name);
+ strcpy(row->name, name);
+ pch = row_prev->head;
+ row_prev->head = row->head;
+ row->head = pch;
+ }
+ }
+ }
+
+ // pick tail
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]) - 1; i++) {
+ row_prev = &config_map[i];
+ row = &config_map[i+1];
+ if (row_prev->head) {
+ row_prev->tail = row->head;
+ }
+ }
+
+ // remove name from head
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ if (row->head) {
+ if (!strcmp(row->name, " ifname ")) {
+ ifname_head = row->head + 1;
+ break;
+ }
+ row->head += strlen(row->name);
+ }
+ }
+
+ for (i = 0; i < sizeof(config_map)/sizeof(config_map[0]); i++) {
+ row = &config_map[i];
+ if (row->head) {
+ memset(data, 0, sizeof(data));
+ if (row->tail) {
+ strncpy(data, row->head, row->tail-row->head);
+ } else {
+ strcpy(data, row->head);
+ }
+ pick_tmp = data;
+
+ if (!strcmp(row->name, " ssid ")) {
+ strcpy(cur_if->ssid, pick_tmp);
+ } else if (!strcmp(row->name, " bssid ")) {
+ pch = bcmstrtok(&pick_tmp, ": ", 0);
+ for (j=0; j<6 && pch; j++) {
+ ((u8 *)&cur_if->bssid)[j] = (int)simple_strtol(pch, NULL, 16);
+ pch = bcmstrtok(&pick_tmp, ": ", 0);
+ }
+ } else if (!strcmp(row->name, " bgnmode ")) {
+ if (!strcmp(pick_tmp, "b"))
+ cur_if->bgnmode = IEEE80211B;
+ else if (!strcmp(pick_tmp, "g"))
+ cur_if->bgnmode = IEEE80211G;
+ else if (!strcmp(pick_tmp, "bg"))
+ cur_if->bgnmode = IEEE80211BG;
+ else if (!strcmp(pick_tmp, "bgn"))
+ cur_if->bgnmode = IEEE80211BGN;
+ else if (!strcmp(pick_tmp, "bgnac"))
+ cur_if->bgnmode = IEEE80211BGNAC;
+ else {
+ ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " hidden ")) {
+ if (!strcmp(pick_tmp, "n"))
+ cur_if->hidden = 0;
+ else if (!strcmp(pick_tmp, "y"))
+ cur_if->hidden = 1;
+ else {
+ ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " maxassoc ")) {
+ cur_if->maxassoc = (int)simple_strtol(pick_tmp, NULL, 10);
+ } else if (!strcmp(row->name, " chan ")) {
+ cur_if->channel = (int)simple_strtol(pick_tmp, NULL, 10);
+ } else if (!strcmp(row->name, " amode ")) {
+ if (!strcmp(pick_tmp, "open"))
+ cur_if->amode = AUTH_OPEN;
+ else if (!strcmp(pick_tmp, "shared"))
+ cur_if->amode = AUTH_SHARED;
+ else if (!strcmp(pick_tmp, "wpapsk"))
+ cur_if->amode = AUTH_WPAPSK;
+ else if (!strcmp(pick_tmp, "wpa2psk"))
+ cur_if->amode = AUTH_WPA2PSK;
+ else if (!strcmp(pick_tmp, "wpawpa2psk"))
+ cur_if->amode = AUTH_WPAWPA2PSK;
+ else {
+ ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n",
+ __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " emode ")) {
+ if (!strcmp(pick_tmp, "none"))
+ cur_if->emode = ENC_NONE;
+ else if (!strcmp(pick_tmp, "wep"))
+ cur_if->emode = ENC_WEP;
+ else if (!strcmp(pick_tmp, "tkip"))
+ cur_if->emode = ENC_TKIP;
+ else if (!strcmp(pick_tmp, "aes"))
+ cur_if->emode = ENC_AES;
+ else if (!strcmp(pick_tmp, "tkipaes"))
+ cur_if->emode = ENC_TKIPAES;
+ else {
+ ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n",
+ __FUNCTION__));
+ return -1;
+ }
+ } else if (!strcmp(row->name, " key ")) {
+ strcpy(cur_if->key, pick_tmp);
+ }
+ }
+ }
+
+ *pick_next = ifname_head;
+ return 0;
+}
+
+static int
+wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)
+{
+ int ret=0;
+ char *pch, *pch2, *pick_tmp, *pick_next=NULL, *param;
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ char ifname[IFNAMSIZ+1];
+ struct wl_if_info *cur_if = &apsta_params->pif;
+
+ if (!apsta_params->init) {
+ ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+ return -1;
+ }
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config
+
+ while (pick_tmp != NULL) {
+ memset(ifname, 0, IFNAMSIZ+1);
+ if (!strncmp(pick_tmp, "ifname ", strlen("ifname "))) {
+ pch = pick_tmp + strlen("ifname ");
+ pch2 = strchr(pch, ' ');
+ if (pch && pch2) {
+ strncpy(ifname, pch, pch2-pch);
+ } else {
+ ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+ return -1;
+ }
+ if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+ cur_if = &apsta_params->pif;
+ } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+ cur_if = &apsta_params->vif;
+ } else {
+ ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__,
+ ifname, apsta_params->apstamode));
+ return -1;
+ }
+ ret = wl_ext_parse_config(cur_if, pick_tmp, &pick_next);
+ if (ret)
+ return -1;
+ pick_tmp = pick_next;
+ } else {
+ ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__));
+ return -1;
+ }
+
+ }
+
+ return 0;
+}
+
+static int
+wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
+{
+ char *pch, *pick_tmp, *param;
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ wlc_ssid_t ssid = { 0, {0} };
+ scb_val_t scbval;
+ struct {
+ s32 tmp;
s32 cfg;
s32 val;
- } bss_setbuf;
- struct wl_apsta_params *apsta_params = &g_apsta_params;
- apstamode_t apstamode = apsta_params->apstamode;
- char ifname[IFNAMSIZ+1];
- struct wl_if_info *cur_if;
- struct dhd_pub *dhd;
-
- if (!apsta_params->init) {
- ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
- return -1;
- }
-
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
- dhd = dhd_get_pub(dev);
-
- pick_tmp = command;
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable
- param = bcmstrtok(&pick_tmp, " ", 0);
- while (param != NULL) {
- if (!strcmp(param, "ifname")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- strcpy(ifname, pch);
- else {
- ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
- return -1;
- }
- }
- param = bcmstrtok(&pick_tmp, " ", 0);
- }
- if (!strcmp(apsta_params->pif.dev->name, ifname)) {
- cur_if = &apsta_params->pif;
- } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
- cur_if = &apsta_params->vif;
- } else {
- ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
- return -1;
- }
- if (!cur_if->dev) {
- ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
- return -1;
- }
-
- if (cur_if->ifmode == ISTA_MODE) {
- wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
- } else if (cur_if->ifmode == IAP_MODE) {
- // deauthenticate all STA first
- memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);
- wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
- }
-
- if (apstamode == IAPONLY_MODE) {
- wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
- wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid
- wl_ext_iovar_setint(dev, "mpc", 1);
- } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) &&
- cur_if->ifmode == IAP_MODE) {
- // vif is AP mode
- bss_setbuf.tmp = 0xffffffff;
- bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
- bss_setbuf.val = htod32(0);
- wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);
- wl_ext_iovar_setint(dev, "mpc", 1);
-#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is disabled, enable arpoe back for STA mode. */
- dhd_arp_offload_set(dhd, dhd_arp_mode);
- dhd_arp_offload_enable(dhd, TRUE);
-#endif /* ARP_OFFLOAD_SUPPORT */
- } else if (apstamode == IDUALAP_MODE) {
- bss_setbuf.tmp = 0xffffffff;
- bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
- bss_setbuf.val = htod32(0);
- wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);
- }
-
-#ifdef PROP_TXSTATUS_VSDB
-#if defined(BCMSDIO)
- if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) {
- bool enabled;
- dhd_wlfc_get_enable(dhd, &enabled);
- if (enabled) {
- dhd_wlfc_deinit(dhd);
- }
- }
-#endif
-#endif /* PROP_TXSTATUS_VSDB */
-
- cur_if->ifstate = IF_STATE_DISALBE;
- printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname);
-
- return 0;
-}
-
-static int
-wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
-{
- int ret = 0;
- s32 val = 0;
- char *pch, *pick_tmp, *param;
- s8 iovar_buf[WLC_IOCTL_SMLEN];
- wlc_ssid_t ssid = { 0, {0} };
- struct {
+ } bss_setbuf;
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ apstamode_t apstamode = apsta_params->apstamode;
+ char ifname[IFNAMSIZ+1];
+ struct wl_if_info *cur_if;
+ struct dhd_pub *dhd;
+
+ if (!apsta_params->init) {
+ ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+ return -1;
+ }
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+ dhd = dhd_get_pub(dev);
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ while (param != NULL) {
+ if (!strcmp(param, "ifname")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch)
+ strcpy(ifname, pch);
+ else {
+ ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ }
+ if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+ cur_if = &apsta_params->pif;
+ } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+ cur_if = &apsta_params->vif;
+ } else {
+ ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
+ return -1;
+ }
+ if (!cur_if->dev) {
+ ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
+ return -1;
+ }
+
+ if (cur_if->ifmode == ISTA_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
+ } else if (cur_if->ifmode == IAP_MODE) {
+ // deauthenticate all STA first
+ memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);
+ wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
+ }
+
+ if (apstamode == IAPONLY_MODE) {
+ wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+ wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid
+ wl_ext_iovar_setint(dev, "mpc", 1);
+ } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) &&
+ cur_if->ifmode == IAP_MODE) {
+ // vif is AP mode
+ bss_setbuf.tmp = 0xffffffff;
+ bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
+ bss_setbuf.val = htod32(0);
+ wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ wl_ext_iovar_setint(dev, "mpc", 1);
+#ifdef ARP_OFFLOAD_SUPPORT
+ /* IF SoftAP is disabled, enable arpoe back for STA mode. */
+ dhd_arp_offload_set(dhd, dhd_arp_mode);
+ dhd_arp_offload_enable(dhd, TRUE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ } else if (apstamode == IDUALAP_MODE) {
+ bss_setbuf.tmp = 0xffffffff;
+ bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
+ bss_setbuf.val = htod32(0);
+ wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(BCMSDIO)
+ if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) {
+ bool enabled;
+ dhd_wlfc_get_enable(dhd, &enabled);
+ if (enabled) {
+ dhd_wlfc_deinit(dhd);
+ }
+ }
+#endif
+#endif /* PROP_TXSTATUS_VSDB */
+
+ cur_if->ifstate = IF_STATE_DISALBE;
+ printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname);
+
+ return 0;
+}
+
+static int
+wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
+{
+ int ret = 0;
+ s32 val = 0;
+ char *pch, *pick_tmp, *param;
+ s8 iovar_buf[WLC_IOCTL_SMLEN];
+ wlc_ssid_t ssid = { 0, {0} };
+ struct {
s32 cfg;
s32 val;
- } bss_setbuf;
- struct wl_apsta_params *apsta_params = &g_apsta_params;
- apstamode_t apstamode = apsta_params->apstamode;
- char ifname[IFNAMSIZ+1];
- struct wl_if_info *cur_if;
- char cmd[128] = "iapsta_stop ifname ";
- struct dhd_pub *dhd;
-
- if (!apsta_params->init) {
- ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
- return -1;
- }
-
- ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
- dhd = dhd_get_pub(dev);
-
- pick_tmp = command;
- param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable
- param = bcmstrtok(&pick_tmp, " ", 0);
- while (param != NULL) {
- if (!strcmp(param, "ifname")) {
- pch = bcmstrtok(&pick_tmp, " ", 0);
- if (pch)
- strcpy(ifname, pch);
- else {
- ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
- return -1;
- }
- }
- param = bcmstrtok(&pick_tmp, " ", 0);
- }
- if (!strcmp(apsta_params->pif.dev->name, ifname)) {
- cur_if = &apsta_params->pif;
- } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
- cur_if = &apsta_params->vif;
- } else {
- ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
- return -1;
- }
- if (!cur_if->dev) {
- ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
- return -1;
- }
- ssid.SSID_len = strlen(cur_if->ssid);
- memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len);
- ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx));
-
- snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname);
- ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd));
- if (ret)
- goto exit;
-
- if (cur_if == &apsta_params->vif) {
- wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr,
- ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL);
- }
-
- // set ssid for AP
- if (cur_if->ifmode == IAP_MODE) {
- wl_ext_iovar_setint(dev, "mpc", 0);
- if (apstamode == IAPONLY_MODE) {
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) {
- wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid),
- iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL);
- }
- }
-
- if (cur_if->ifmode == IAP_MODE) {
- wl_ext_set_bgnmode(cur_if);
- wl_ext_set_chanspec(cur_if->dev, cur_if->channel);
- }
- wl_ext_set_amode(cur_if, apsta_params);
- wl_ext_set_emode(cur_if, apsta_params);
-
- if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {
- if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) {
- printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid);
- wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1);
- }
- val = 1;
- wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1);
- }
- if (cur_if->ifmode == IAP_MODE) {
- if (cur_if->maxassoc >= 0)
- wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc);
- printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON");
- // terence: fix me, hidden does not work in dualAP mode
- wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1);
- }
-
- if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
- } else if (apstamode == IAPONLY_MODE) {
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) {
- if (cur_if->ifmode == ISTA_MODE) {
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
- } else {
- if (FW_SUPPORTED(dhd, rsdb)) {
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
- } else {
- bss_setbuf.cfg = htod32(cur_if->bssidx);
- bss_setbuf.val = htod32(1);
- wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
- iovar_buf, WLC_IOCTL_SMLEN, NULL);
- }
+ } bss_setbuf;
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ apstamode_t apstamode = apsta_params->apstamode;
+ char ifname[IFNAMSIZ+1];
+ struct wl_if_info *cur_if;
+ char cmd[128] = "iapsta_stop ifname ";
+ struct dhd_pub *dhd;
+
+ if (!apsta_params->init) {
+ ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+ return -1;
+ }
+
+ ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+ dhd = dhd_get_pub(dev);
+
+ pick_tmp = command;
+ param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ while (param != NULL) {
+ if (!strcmp(param, "ifname")) {
+ pch = bcmstrtok(&pick_tmp, " ", 0);
+ if (pch)
+ strcpy(ifname, pch);
+ else {
+ ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+ return -1;
+ }
+ }
+ param = bcmstrtok(&pick_tmp, " ", 0);
+ }
+ if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+ cur_if = &apsta_params->pif;
+ } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+ cur_if = &apsta_params->vif;
+ } else {
+ ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
+ return -1;
+ }
+ if (!cur_if->dev) {
+ ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
+ return -1;
+ }
+ ssid.SSID_len = strlen(cur_if->ssid);
+ memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len);
+ ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx));
+
+ snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname);
+ ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd));
+ if (ret)
+ goto exit;
+
+ if (cur_if == &apsta_params->vif) {
+ wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr,
+ ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
+
+ // set ssid for AP
+ if (cur_if->ifmode == IAP_MODE) {
+ wl_ext_iovar_setint(dev, "mpc", 0);
+ if (apstamode == IAPONLY_MODE) {
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) {
+ wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid),
+ iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL);
+ }
+ }
+
+ if (cur_if->ifmode == IAP_MODE) {
+ wl_ext_set_bgnmode(cur_if);
+ wl_ext_set_chanspec(cur_if->dev, cur_if->channel);
+ }
+ wl_ext_set_amode(cur_if, apsta_params);
+ wl_ext_set_emode(cur_if, apsta_params);
+
+ if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {
+ if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) {
+ printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid);
+ wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1);
+ }
+ val = 1;
+ wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1);
+ }
+ if (cur_if->ifmode == IAP_MODE) {
+ if (cur_if->maxassoc >= 0)
+ wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc);
+ printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON");
+ // terence: fix me, hidden does not work in dualAP mode
+ wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1);
+ }
+
+ if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ } else if (apstamode == IAPONLY_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) {
+ if (cur_if->ifmode == ISTA_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ } else {
+ if (FW_SUPPORTED(dhd, rsdb)) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ } else {
+ bss_setbuf.cfg = htod32(cur_if->bssidx);
+ bss_setbuf.val = htod32(1);
+ wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+ iovar_buf, WLC_IOCTL_SMLEN, NULL);
+ }
#ifdef ARP_OFFLOAD_SUPPORT
- /* IF SoftAP is enabled, disable arpoe */
- dhd_arp_offload_set(dhd, 0);
- dhd_arp_offload_enable(dhd, FALSE);
-#endif /* ARP_OFFLOAD_SUPPORT */
- }
- }
- else if (apstamode == IDUALAP_MODE) {
- wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
- }
-
-#ifdef PROP_TXSTATUS_VSDB
-#if defined(BCMSDIO)
- if (cur_if==&apsta_params->vif && !disable_proptx) {
- bool enabled;
- dhd_wlfc_get_enable(dhd, &enabled);
- if (!enabled) {
- dhd_wlfc_init(dhd);
- wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
- }
- }
-#endif
-#endif /* PROP_TXSTATUS_VSDB */
-
- printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid);
-
- cur_if->ifstate = IF_STATE_ENABLE;
-
-exit:
- return ret;
-}
-
-void
-wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel)
-{
- struct wl_apsta_params *apsta_params = &g_apsta_params;
- struct wl_if_info *cur_if = &apsta_params->vif;
- scb_val_t scbval;
- int ret;
- channel_info_t ci;
- struct dhd_pub *dhd;
-
- if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) {
- dhd = dhd_get_pub(dev);
- if (!FW_SUPPORTED(dhd, vsdb)) {
- if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
- if (channel != ci.target_channel) {
- printf("%s: deauthenticate all STA on vif\n", __FUNCTION__);
- memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);
- wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
- }
- }
- }
- }
-}
-
-int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx)
-{
- g_apsta_params.vif.dev = net;
- g_apsta_params.vif.bssidx = bssidx;
- if (strlen(g_apsta_params.vif.ifname)) {
- memset(net->name, 0, sizeof(IFNAMSIZ));
- strcpy(net->name, g_apsta_params.vif.ifname);
- net->name[IFNAMSIZ - 1] = '\0';
- }
- if (g_apsta_params.pif.dev) {
- memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN);
- net->dev_addr[0] |= 0x02;
- }
-
- return 0;
-}
-
-int wl_android_ext_dettach_netdev(void)
-{
- struct wl_apsta_params *apsta_params = &g_apsta_params;
-
- ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));
- memset(apsta_params, 0, sizeof(struct wl_apsta_params));
-
- return 0;
-}
-#endif
-
-#ifdef IDHCP
-int wl_ext_ip_dump(int ip, char *buf)
-{
- unsigned char bytes[4];
- int bytes_written=-1;
-
- bytes[0] = ip & 0xFF;
- bytes[1] = (ip >> 8) & 0xFF;
- bytes[2] = (ip >> 16) & 0xFF;
- bytes[3] = (ip >> 24) & 0xFF;
- bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
-
- return bytes_written;
-}
-
-/*
-terence 20170215:
-dhd_priv dhcpc_dump ifname [wlan0|wlan1]
-dhd_priv dhcpc_enable [0|1]
-*/
-int
-wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len)
-{
- int enable = -1, ret = -1;
- int bytes_written = -1;
-
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
-
- sscanf(command, "%*s %d", &enable);
-
- if (enable >= 0)
- ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable);
- else {
- ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable);
- if (!ret) {
- bytes_written = snprintf(command, total_len, "%d", enable);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
- }
-
- return ret;
-}
-
-int
-wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len)
-{
-
- int ret = 0;
- int bytes_written = 0;
- uint32 ip_addr;
- char buf[20]="";
-
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr);
- if (!ret) {
- wl_ext_ip_dump(ip_addr, buf);
- bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf);
- }
-
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr);
- if (!ret) {
- wl_ext_ip_dump(ip_addr, buf);
- bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf);
- }
-
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr);
- if (!ret) {
- wl_ext_ip_dump(ip_addr, buf);
- bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf);
- }
-
- ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr);
- if (!ret) {
- wl_ext_ip_dump(ip_addr, buf);
- bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf);
- }
-
- if (!bytes_written)
- bytes_written = -1;
-
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
-
- return bytes_written;
-}
-#endif
-
-/*
-dhd_priv dhd [string] ==> Not ready
-1. Get dhd val:
- Ex: dhd_priv dhd bussleep
-2. Set dhd val:
- Ex: dhd_priv dhd bussleep 1
-
-dhd_priv wl [WLC_GET_PM] ==> Ready to get int val
-dhd_priv wl [WLC_SET_PM] [int] ==> Ready to set int val
-dhd_priv wl [string] ==> Ready to get int val
-dhd_priv wl [string] [int] ==> Ready to set int val
-Ex: get/set WLC_PM
- dhd_priv wl 85
- dhd_priv wl 86 1
-Ex: get/set mpc
- dhd_priv wl mpc
- dhd_priv wl mpc 1
-*/
-int
-wl_ext_iovar(struct net_device *dev, char *command, int total_len)
-{
- int ret = 0;
- char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0";
- int cmd=-1, val=0;
- int bytes_written=-1;
-
- ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
-
- sscanf(command, "%s %d %s", wl, &cmd, arg);
- if (cmd < 0)
- sscanf(command, "%s %s %s", wl, cmd_str, val_str);
-
- if (!strcmp(wl, "wl")) {
- if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) {
- ret = sscanf(arg, "%d", &val);
- if (ret > 0) { // set
- ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE);
- } else { // get
- ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE);
- if (!ret) {
- bytes_written = snprintf(command, total_len, "%d", val);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
- }
- } else if (strlen(cmd_str)) {
- ret = sscanf(val_str, "%d", &val);
- if (ret > 0) { // set
- ret = wl_ext_iovar_setint(dev, cmd_str, val);
- } else { // get
- ret = wl_ext_iovar_getint(dev, cmd_str, &val);
- if (!ret) {
- bytes_written = snprintf(command, total_len, "%d", val);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
- ret = bytes_written;
- }
- }
- }
- }
-
- return ret;
-}
-
-int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
- int *bytes_written)
-{
- int ret = 0;
-
- if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) {
- *bytes_written = wl_ext_channels(net, command, total_len);
- }
- else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) {
- *bytes_written = wl_ext_channel(net, command, total_len);
- }
- else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) {
- *bytes_written = wl_ext_roam_trigger(net, command, total_len);
- }
- else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {
- *bytes_written = wl_ext_keep_alive(net, command, total_len);
- }
- else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) {
- *bytes_written = wl_ext_pm(net, command, total_len);
- }
+ /* IF SoftAP is enabled, disable arpoe */
+ dhd_arp_offload_set(dhd, 0);
+ dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+ }
+ }
+ else if (apstamode == IDUALAP_MODE) {
+ wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+ }
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(BCMSDIO)
+ if (cur_if==&apsta_params->vif && !disable_proptx) {
+ bool enabled;
+ dhd_wlfc_get_enable(dhd, &enabled);
+ if (!enabled) {
+ dhd_wlfc_init(dhd);
+ wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+ }
+ }
+#endif
+#endif /* PROP_TXSTATUS_VSDB */
+
+ printf("%s: ifname=%s, SSID: \"%s\"\n", __FUNCTION__, ifname, cur_if->ssid);
+
+ cur_if->ifstate = IF_STATE_ENABLE;
+
+exit:
+ return ret;
+}
+
+void
+wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel)
+{
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+ struct wl_if_info *cur_if = &apsta_params->vif;
+ scb_val_t scbval;
+ int ret;
+ channel_info_t ci;
+ struct dhd_pub *dhd;
+
+ if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) {
+ dhd = dhd_get_pub(dev);
+ if (!FW_SUPPORTED(dhd, vsdb)) {
+ if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
+ if (channel != ci.target_channel) {
+ printf("%s: deauthenticate all STA on vif\n", __FUNCTION__);
+ memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);
+ wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
+ }
+ }
+ }
+ }
+}
+
+int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx)
+{
+ g_apsta_params.vif.dev = net;
+ g_apsta_params.vif.bssidx = bssidx;
+ if (strlen(g_apsta_params.vif.ifname)) {
+ memset(net->name, 0, sizeof(IFNAMSIZ));
+ strcpy(net->name, g_apsta_params.vif.ifname);
+ net->name[IFNAMSIZ - 1] = '\0';
+ }
+ if (g_apsta_params.pif.dev) {
+ memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN);
+ net->dev_addr[0] |= 0x02;
+ }
+
+ return 0;
+}
+
+int wl_android_ext_dettach_netdev(void)
+{
+ struct wl_apsta_params *apsta_params = &g_apsta_params;
+
+ ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));
+ memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+
+ return 0;
+}
+#endif
+
+#ifdef IDHCP
+int wl_ext_ip_dump(int ip, char *buf)
+{
+ unsigned char bytes[4];
+ int bytes_written=-1;
+
+ bytes[0] = ip & 0xFF;
+ bytes[1] = (ip >> 8) & 0xFF;
+ bytes[2] = (ip >> 16) & 0xFF;
+ bytes[3] = (ip >> 24) & 0xFF;
+ bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
+
+ return bytes_written;
+}
+
+/*
+terence 20170215:
+dhd_priv dhcpc_dump ifname [wlan0|wlan1]
+dhd_priv dhcpc_enable [0|1]
+*/
+int
+wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len)
+{
+ int enable = -1, ret = -1;
+ int bytes_written = -1;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%*s %d", &enable);
+
+ if (enable >= 0)
+ ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable);
+ else {
+ ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable);
+ if (!ret) {
+ bytes_written = snprintf(command, total_len, "%d", enable);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+
+ return ret;
+}
+
+int
+wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len)
+{
+
+ int ret = 0;
+ int bytes_written = 0;
+ uint32 ip_addr;
+ char buf[20]="";
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf);
+ }
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf);
+ }
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf);
+ }
+
+ ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr);
+ if (!ret) {
+ wl_ext_ip_dump(ip_addr, buf);
+ bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf);
+ }
+
+ if (!bytes_written)
+ bytes_written = -1;
+
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+
+ return bytes_written;
+}
+#endif
+
+/*
+dhd_priv dhd [string] ==> Not ready
+1. Get dhd val:
+ Ex: dhd_priv dhd bussleep
+2. Set dhd val:
+ Ex: dhd_priv dhd bussleep 1
+
+dhd_priv wl [WLC_GET_PM] ==> Ready to get int val
+dhd_priv wl [WLC_SET_PM] [int] ==> Ready to set int val
+dhd_priv wl [string] ==> Ready to get int val
+dhd_priv wl [string] [int] ==> Ready to set int val
+Ex: get/set WLC_PM
+ dhd_priv wl 85
+ dhd_priv wl 86 1
+Ex: get/set mpc
+ dhd_priv wl mpc
+ dhd_priv wl mpc 1
+*/
+int
+wl_ext_iovar(struct net_device *dev, char *command, int total_len)
+{
+ int ret = 0;
+ char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0";
+ int cmd=-1, val=0;
+ int bytes_written=-1;
+
+ ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+ sscanf(command, "%s %d %s", wl, &cmd, arg);
+ if (cmd < 0)
+ sscanf(command, "%s %s %s", wl, cmd_str, val_str);
+
+ if (!strcmp(wl, "wl")) {
+ if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) {
+ ret = sscanf(arg, "%d", &val);
+ if (ret > 0) { // set
+ ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE);
+ } else { // get
+ ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE);
+ if (!ret) {
+ bytes_written = snprintf(command, total_len, "%d", val);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+ } else if (strlen(cmd_str)) {
+ ret = sscanf(val_str, "%d", &val);
+ if (ret > 0) { // set
+ ret = wl_ext_iovar_setint(dev, cmd_str, val);
+ } else { // get
+ ret = wl_ext_iovar_getint(dev, cmd_str, &val);
+ if (!ret) {
+ bytes_written = snprintf(command, total_len, "%d", val);
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ret = bytes_written;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
+ int *bytes_written)
+{
+ int ret = 0;
+
+ if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) {
+ *bytes_written = wl_ext_channels(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) {
+ *bytes_written = wl_ext_channel(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) {
+ *bytes_written = wl_ext_roam_trigger(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {
+ *bytes_written = wl_ext_keep_alive(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) {
+ *bytes_written = wl_ext_pm(net, command, total_len);
+ }
else if (strnicmp(command, CMD_MONITOR, strlen(CMD_MONITOR)) == 0) {
- *bytes_written = wl_ext_monitor(net, command, total_len);
- }
- else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) {
- int bcn_li_dtim;
- bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10);
- *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim);
- }
-#ifdef WL_EXT_IAPSTA
- else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) {
- *bytes_written = wl_ext_iapsta_init(net, command, total_len);
- }
- else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) {
- *bytes_written = wl_ext_iapsta_config(net, command, total_len);
- }
- else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) {
- *bytes_written = wl_ext_iapsta_enable(net, command, total_len);
- }
- else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) {
- *bytes_written = wl_ext_iapsta_disable(net, command, total_len);
- }
-#endif
-#ifdef IDHCP
- else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) {
- *bytes_written = wl_ext_dhcpc_enable(net, command, total_len);
- }
- else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) {
- *bytes_written = wl_ext_dhcpc_dump(net, command, total_len);
- }
-#endif
- else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) {
- *bytes_written = wl_ext_iovar(net, command, total_len);
- }
- else
- ret = -1;
-
- return ret;
-}
-
-#if defined(RSSIAVG)
-void
-wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
-{
- wl_rssi_cache_t *node, *cur, **rssi_head;
- int i=0;
-
- rssi_head = &rssi_cache_ctrl->m_cache_head;
- node = *rssi_head;
-
- for (;node;) {
- ANDROID_INFO(("%s: Free %d with BSSID %pM\n",
- __FUNCTION__, i, &node->BSSID));
- cur = node;
- node = cur->next;
- kfree(cur);
- i++;
- }
- *rssi_head = NULL;
-}
-
-void
-wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
-{
- wl_rssi_cache_t *node, *prev, **rssi_head;
- int i = -1, tmp = 0;
- struct timeval now;
-
- do_gettimeofday(&now);
-
- rssi_head = &rssi_cache_ctrl->m_cache_head;
- node = *rssi_head;
- prev = node;
- for (;node;) {
- i++;
- if (now.tv_sec > node->tv.tv_sec) {
- if (node == *rssi_head) {
- tmp = 1;
- *rssi_head = node->next;
- } else {
- tmp = 0;
- prev->next = node->next;
- }
- ANDROID_INFO(("%s: Del %d with BSSID %pM\n",
- __FUNCTION__, i, &node->BSSID));
- kfree(node);
- if (tmp == 1) {
- node = *rssi_head;
- prev = node;
- } else {
- node = prev->next;
- }
- continue;
- }
- prev = node;
- node = node->next;
- }
-}
-
-void
-wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid)
-{
- wl_rssi_cache_t *node, *prev, **rssi_head;
- int i = -1, tmp = 0;
-
- rssi_head = &rssi_cache_ctrl->m_cache_head;
- node = *rssi_head;
- prev = node;
- for (;node;) {
- i++;
- if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) {
- if (node == *rssi_head) {
- tmp = 1;
- *rssi_head = node->next;
- } else {
- tmp = 0;
- prev->next = node->next;
- }
- ANDROID_INFO(("%s: Del %d with BSSID %pM\n",
- __FUNCTION__, i, &node->BSSID));
- kfree(node);
- if (tmp == 1) {
- node = *rssi_head;
- prev = node;
- } else {
- node = prev->next;
- }
- continue;
- }
- prev = node;
- node = node->next;
- }
-}
-
-void
-wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
-{
- wl_rssi_cache_t *node, **rssi_head;
-
- rssi_head = &rssi_cache_ctrl->m_cache_head;
-
- /* reset dirty */
- node = *rssi_head;
- for (;node;) {
- node->dirty += 1;
- node = node->next;
- }
-}
-
-int
-wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg)
-{
- wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
- int j, k=0;
- int rssi, error=0;
- struct ether_addr bssid;
- struct timeval now, timeout;
-
- if (!g_wifi_on)
- return 0;
-
- error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false);
- if (error == BCME_NOTASSOCIATED) {
- ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error));
- return 0;
- }
- if (error) {
- ANDROID_ERROR(("Could not get bssid (%d)\n", error));
- }
- error = wldev_get_rssi(net, &rssi);
- if (error) {
- ANDROID_ERROR(("Could not get rssi (%d)\n", error));
- return error;
- }
-
- do_gettimeofday(&now);
- timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;
- if (timeout.tv_sec < now.tv_sec) {
- /*
- * Integer overflow - assume long enough timeout to be assumed
- * to be infinite, i.e., the timeout would never happen.
- */
- ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
- __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
- }
-
- /* update RSSI */
- rssi_head = &rssi_cache_ctrl->m_cache_head;
- node = *rssi_head;
- prev = NULL;
- for (;node;) {
- if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) {
- ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n",
- __FUNCTION__, k, &bssid, rssi));
- for (j=0; j<RSSIAVG_LEN-1; j++)
- node->RSSI[j] = node->RSSI[j+1];
- node->RSSI[j] = rssi;
- node->dirty = 0;
- node->tv = timeout;
- goto exit;
- }
- prev = node;
- node = node->next;
- k++;
- }
-
- leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
- if (!leaf) {
- ANDROID_ERROR(("%s: Memory alloc failure %d\n",
- __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
- return 0;
- }
- ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n",
- __FUNCTION__, k, &bssid, rssi));
-
- leaf->next = NULL;
- leaf->dirty = 0;
- leaf->tv = timeout;
- memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN);
- for (j=0; j<RSSIAVG_LEN; j++)
- leaf->RSSI[j] = rssi;
-
- if (!prev)
- *rssi_head = leaf;
- else
- prev->next = leaf;
-
-exit:
- *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid);
-
- return error;
-}
-
-void
-wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list)
-{
- wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
- wl_bss_info_t *bi = NULL;
- int i, j, k;
- struct timeval now, timeout;
-
- if (!ss_list->count)
- return;
-
- do_gettimeofday(&now);
- timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;
- if (timeout.tv_sec < now.tv_sec) {
- /*
- * Integer overflow - assume long enough timeout to be assumed
- * to be infinite, i.e., the timeout would never happen.
- */
- ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
- __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
- }
-
- rssi_head = &rssi_cache_ctrl->m_cache_head;
-
- /* update RSSI */
- for (i = 0; i < ss_list->count; i++) {
- node = *rssi_head;
- prev = NULL;
- k = 0;
- 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=%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];
- node->RSSI[j] = dtoh16(bi->RSSI);
- node->dirty = 0;
- node->tv = timeout;
- break;
- }
- prev = node;
- node = node->next;
- k++;
- }
-
- if (node)
- continue;
-
- leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
- if (!leaf) {
- ANDROID_ERROR(("%s: Memory alloc failure %d\n",
- __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
- return;
- }
- 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;
- leaf->dirty = 0;
- leaf->tv = timeout;
- memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN);
- for (j=0; j<RSSIAVG_LEN; j++)
- leaf->RSSI[j] = dtoh16(bi->RSSI);
-
- if (!prev)
- *rssi_head = leaf;
- else
- prev->next = leaf;
- }
-}
-
-int16
-wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr)
-{
- wl_rssi_cache_t *node, **rssi_head;
- int j, rssi_sum, rssi=RSSI_MINVAL;
-
- rssi_head = &rssi_cache_ctrl->m_cache_head;
-
- node = *rssi_head;
- for (;node;) {
- if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) {
- rssi_sum = 0;
- rssi = 0;
- for (j=0; j<RSSIAVG_LEN; j++)
- rssi_sum += node->RSSI[RSSIAVG_LEN-j-1];
- rssi = rssi_sum / j;
- break;
- }
- node = node->next;
- }
- rssi = MIN(rssi, RSSI_MAXVAL);
- if (rssi == RSSI_MINVAL) {
- ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n",
- __FUNCTION__, addr));
- }
- return (int16)rssi;
-}
-#endif
-
-#if defined(RSSIOFFSET)
-int
-wl_update_rssi_offset(struct net_device *net, int rssi)
-{
-#if defined(RSSIOFFSET_NEW)
- int j;
-#endif
-
- if (!g_wifi_on)
- return rssi;
-
-#if defined(RSSIOFFSET_NEW)
- 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;
-#endif
- return MIN(rssi, RSSI_MAXVAL);
-}
-#endif
-
-#if defined(BSSCACHE)
-void
-wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
-{
- wl_bss_cache_t *node, *cur, **bss_head;
- int i=0;
-
- ANDROID_TRACE(("%s called\n", __FUNCTION__));
-
- bss_head = &bss_cache_ctrl->m_cache_head;
- node = *bss_head;
-
- for (;node;) {
- ANDROID_TRACE(("%s: Free %d with BSSID %pM\n",
- __FUNCTION__, i, &node->results.bss_info->BSSID));
- cur = node;
- node = cur->next;
- kfree(cur);
- i++;
- }
- *bss_head = NULL;
-}
-
-void
-wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
-{
- wl_bss_cache_t *node, *prev, **bss_head;
- int i = -1, tmp = 0;
- struct timeval now;
-
- do_gettimeofday(&now);
-
- bss_head = &bss_cache_ctrl->m_cache_head;
- node = *bss_head;
- prev = node;
- for (;node;) {
- i++;
- if (now.tv_sec > node->tv.tv_sec) {
- if (node == *bss_head) {
- tmp = 1;
- *bss_head = node->next;
- } else {
- tmp = 0;
- prev->next = node->next;
- }
- 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);
- if (tmp == 1) {
- node = *bss_head;
- prev = node;
- } else {
- node = prev->next;
- }
- continue;
- }
- prev = node;
- node = node->next;
- }
-}
-
-void
-wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid)
-{
- wl_bss_cache_t *node, *prev, **bss_head;
- int i = -1, tmp = 0;
-
- bss_head = &bss_cache_ctrl->m_cache_head;
- node = *bss_head;
- prev = node;
- for (;node;) {
- i++;
- if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) {
- if (node == *bss_head) {
- tmp = 1;
- *bss_head = node->next;
- } else {
- tmp = 0;
- prev->next = node->next;
- }
- 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);
- if (tmp == 1) {
- node = *bss_head;
- prev = node;
- } else {
- node = prev->next;
- }
- continue;
- }
- prev = node;
- node = node->next;
- }
-}
-
-void
-wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
-{
- wl_bss_cache_t *node, **bss_head;
-
- bss_head = &bss_cache_ctrl->m_cache_head;
-
- /* reset dirty */
- node = *bss_head;
- for (;node;) {
- node->dirty += 1;
- node = node->next;
- }
-}
-
-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,
-#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, **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)
- return;
-
- do_gettimeofday(&now);
- timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT;
- if (timeout.tv_sec < now.tv_sec) {
- /*
- * Integer overflow - assume long enough timeout to be assumed
- * to be infinite, i.e., the timeout would never happen.
- */
- ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
- __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
- }
-
- bss_head = &bss_cache_ctrl->m_cache_head;
-
- for (i=0; i < ss_list->count; i++) {
- node = *bss_head;
- prev = NULL;
- bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
-
- for (;node;) {
- if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
- if (node == *bss_head)
- *bss_head = node->next;
- else {
- prev->next = node->next;
- }
- break;
- }
- prev = node;
- node = node->next;
- }
-
- 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) + (int)sizeof(wl_bss_cache_t)));
- return;
- }
- 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->next = NULL;
- leaf->dirty = 0;
- leaf->tv = timeout;
- leaf->results.count = 1;
- leaf->results.version = ss_list->version;
- k++;
-
- if (*bss_head == NULL)
- *bss_head = 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
-wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)
-{
- ANDROID_TRACE(("%s:\n", __FUNCTION__));
- wl_free_bss_cache(bss_cache_ctrl);
-}
-#endif
-
-
+ *bytes_written = wl_ext_monitor(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) {
+ int bcn_li_dtim;
+ bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10);
+ *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim);
+ }
+#ifdef WL_EXT_IAPSTA
+ else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) {
+ *bytes_written = wl_ext_iapsta_init(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) {
+ *bytes_written = wl_ext_iapsta_config(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) {
+ *bytes_written = wl_ext_iapsta_enable(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) {
+ *bytes_written = wl_ext_iapsta_disable(net, command, total_len);
+ }
+#endif
+#ifdef IDHCP
+ else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) {
+ *bytes_written = wl_ext_dhcpc_enable(net, command, total_len);
+ }
+ else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) {
+ *bytes_written = wl_ext_dhcpc_dump(net, command, total_len);
+ }
+#endif
+ else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) {
+ *bytes_written = wl_ext_iovar(net, command, total_len);
+ }
+ else
+ ret = -1;
+
+ return ret;
+}
+
+#if defined(RSSIAVG)
+void
+wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, *cur, **rssi_head;
+ int i=0;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+
+ for (;node;) {
+ ANDROID_INFO(("%s: Free %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID));
+ cur = node;
+ node = cur->next;
+ kfree(cur);
+ i++;
+ }
+ *rssi_head = NULL;
+}
+
+void
+wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, *prev, **rssi_head;
+ int i = -1, tmp = 0;
+ struct timeval now;
+
+ do_gettimeofday(&now);
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (now.tv_sec > node->tv.tv_sec) {
+ if (node == *rssi_head) {
+ tmp = 1;
+ *rssi_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ ANDROID_INFO(("%s: Del %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID));
+ kfree(node);
+ if (tmp == 1) {
+ node = *rssi_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid)
+{
+ wl_rssi_cache_t *node, *prev, **rssi_head;
+ int i = -1, tmp = 0;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) {
+ if (node == *rssi_head) {
+ tmp = 1;
+ *rssi_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ ANDROID_INFO(("%s: Del %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->BSSID));
+ kfree(node);
+ if (tmp == 1) {
+ node = *rssi_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)
+{
+ wl_rssi_cache_t *node, **rssi_head;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *rssi_head;
+ for (;node;) {
+ node->dirty += 1;
+ node = node->next;
+ }
+}
+
+int
+wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg)
+{
+ wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
+ int j, k=0;
+ int rssi, error=0;
+ struct ether_addr bssid;
+ struct timeval now, timeout;
+
+ if (!g_wifi_on)
+ return 0;
+
+ error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false);
+ if (error == BCME_NOTASSOCIATED) {
+ ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error));
+ return 0;
+ }
+ if (error) {
+ ANDROID_ERROR(("Could not get bssid (%d)\n", error));
+ }
+ error = wldev_get_rssi(net, &rssi);
+ if (error) {
+ ANDROID_ERROR(("Could not get rssi (%d)\n", error));
+ return error;
+ }
+
+ do_gettimeofday(&now);
+ timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;
+ if (timeout.tv_sec < now.tv_sec) {
+ /*
+ * Integer overflow - assume long enough timeout to be assumed
+ * to be infinite, i.e., the timeout would never happen.
+ */
+ ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
+ __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
+ }
+
+ /* update RSSI */
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+ node = *rssi_head;
+ prev = NULL;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) {
+ ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n",
+ __FUNCTION__, k, &bssid, rssi));
+ for (j=0; j<RSSIAVG_LEN-1; j++)
+ node->RSSI[j] = node->RSSI[j+1];
+ node->RSSI[j] = rssi;
+ node->dirty = 0;
+ node->tv = timeout;
+ goto exit;
+ }
+ prev = node;
+ node = node->next;
+ k++;
+ }
+
+ leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
+ if (!leaf) {
+ ANDROID_ERROR(("%s: Memory alloc failure %d\n",
+ __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
+ return 0;
+ }
+ ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n",
+ __FUNCTION__, k, &bssid, rssi));
+
+ leaf->next = NULL;
+ leaf->dirty = 0;
+ leaf->tv = timeout;
+ memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN);
+ for (j=0; j<RSSIAVG_LEN; j++)
+ leaf->RSSI[j] = rssi;
+
+ if (!prev)
+ *rssi_head = leaf;
+ else
+ prev->next = leaf;
+
+exit:
+ *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid);
+
+ return error;
+}
+
+void
+wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list)
+{
+ wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;
+ wl_bss_info_t *bi = NULL;
+ int i, j, k;
+ struct timeval now, timeout;
+
+ if (!ss_list->count)
+ return;
+
+ do_gettimeofday(&now);
+ timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;
+ if (timeout.tv_sec < now.tv_sec) {
+ /*
+ * Integer overflow - assume long enough timeout to be assumed
+ * to be infinite, i.e., the timeout would never happen.
+ */
+ ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
+ __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
+ }
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ /* update RSSI */
+ for (i = 0; i < ss_list->count; i++) {
+ node = *rssi_head;
+ prev = NULL;
+ k = 0;
+ 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=%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];
+ node->RSSI[j] = dtoh16(bi->RSSI);
+ node->dirty = 0;
+ node->tv = timeout;
+ break;
+ }
+ prev = node;
+ node = node->next;
+ k++;
+ }
+
+ if (node)
+ continue;
+
+ leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);
+ if (!leaf) {
+ ANDROID_ERROR(("%s: Memory alloc failure %d\n",
+ __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));
+ return;
+ }
+ 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;
+ leaf->dirty = 0;
+ leaf->tv = timeout;
+ memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN);
+ for (j=0; j<RSSIAVG_LEN; j++)
+ leaf->RSSI[j] = dtoh16(bi->RSSI);
+
+ if (!prev)
+ *rssi_head = leaf;
+ else
+ prev->next = leaf;
+ }
+}
+
+int16
+wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr)
+{
+ wl_rssi_cache_t *node, **rssi_head;
+ int j, rssi_sum, rssi=RSSI_MINVAL;
+
+ rssi_head = &rssi_cache_ctrl->m_cache_head;
+
+ node = *rssi_head;
+ for (;node;) {
+ if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) {
+ rssi_sum = 0;
+ rssi = 0;
+ for (j=0; j<RSSIAVG_LEN; j++)
+ rssi_sum += node->RSSI[RSSIAVG_LEN-j-1];
+ rssi = rssi_sum / j;
+ break;
+ }
+ node = node->next;
+ }
+ rssi = MIN(rssi, RSSI_MAXVAL);
+ if (rssi == RSSI_MINVAL) {
+ ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n",
+ __FUNCTION__, addr));
+ }
+ return (int16)rssi;
+}
+#endif
+
+#if defined(RSSIOFFSET)
+int
+wl_update_rssi_offset(struct net_device *net, int rssi)
+{
+#if defined(RSSIOFFSET_NEW)
+ int j;
+#endif
+
+ if (!g_wifi_on)
+ return rssi;
+
+#if defined(RSSIOFFSET_NEW)
+ 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;
+#endif
+ return MIN(rssi, RSSI_MAXVAL);
+}
+#endif
+
+#if defined(BSSCACHE)
+void
+wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, *cur, **bss_head;
+ int i=0;
+
+ ANDROID_TRACE(("%s called\n", __FUNCTION__));
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+
+ for (;node;) {
+ ANDROID_TRACE(("%s: Free %d with BSSID %pM\n",
+ __FUNCTION__, i, &node->results.bss_info->BSSID));
+ cur = node;
+ node = cur->next;
+ kfree(cur);
+ i++;
+ }
+ *bss_head = NULL;
+}
+
+void
+wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, *prev, **bss_head;
+ int i = -1, tmp = 0;
+ struct timeval now;
+
+ do_gettimeofday(&now);
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (now.tv_sec > node->tv.tv_sec) {
+ if (node == *bss_head) {
+ tmp = 1;
+ *bss_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ 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);
+ if (tmp == 1) {
+ node = *bss_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid)
+{
+ wl_bss_cache_t *node, *prev, **bss_head;
+ int i = -1, tmp = 0;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+ node = *bss_head;
+ prev = node;
+ for (;node;) {
+ i++;
+ if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) {
+ if (node == *bss_head) {
+ tmp = 1;
+ *bss_head = node->next;
+ } else {
+ tmp = 0;
+ prev->next = node->next;
+ }
+ 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);
+ if (tmp == 1) {
+ node = *bss_head;
+ prev = node;
+ } else {
+ node = prev->next;
+ }
+ continue;
+ }
+ prev = node;
+ node = node->next;
+ }
+}
+
+void
+wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ wl_bss_cache_t *node, **bss_head;
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+
+ /* reset dirty */
+ node = *bss_head;
+ for (;node;) {
+ node->dirty += 1;
+ node = node->next;
+ }
+}
+
+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,
+#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, **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)
+ return;
+
+ do_gettimeofday(&now);
+ timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT;
+ if (timeout.tv_sec < now.tv_sec) {
+ /*
+ * Integer overflow - assume long enough timeout to be assumed
+ * to be infinite, i.e., the timeout would never happen.
+ */
+ ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",
+ __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));
+ }
+
+ bss_head = &bss_cache_ctrl->m_cache_head;
+
+ for (i=0; i < ss_list->count; i++) {
+ node = *bss_head;
+ prev = NULL;
+ bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;
+
+ for (;node;) {
+ if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {
+ if (node == *bss_head)
+ *bss_head = node->next;
+ else {
+ prev->next = node->next;
+ }
+ break;
+ }
+ prev = node;
+ node = node->next;
+ }
+
+ 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) + (int)sizeof(wl_bss_cache_t)));
+ return;
+ }
+ 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->next = NULL;
+ leaf->dirty = 0;
+ leaf->tv = timeout;
+ leaf->results.count = 1;
+ leaf->results.version = ss_list->version;
+ k++;
+
+ if (*bss_head == NULL)
+ *bss_head = 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
+wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)
+{
+ ANDROID_TRACE(("%s:\n", __FUNCTION__));
+ wl_free_bss_cache(bss_cache_ctrl);
+}
+#endif
+
+
diff --git a/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c b/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
index efadf25..5651601 100644
--- a/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
+++ b/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
@@ -3774,7 +3774,7 @@ wl_customer6_legacy_chip_check(struct bcm_cfg80211 *cfg,
dtoh32(revinfo.deviceid), dtoh32(revinfo.vendorid), dtoh32(revinfo.chipnum)));
chipnum = revinfo.chipnum;
if ((chipnum == BCM4350_CHIP_ID) || (chipnum == BCM4355_CHIP_ID) ||
- (chipnum == BCM4345_CHIP_ID)) {
+ (chipnum == BCM4345_CHIP_ID) || (chipnum == BCM43430_CHIP_ID)) {
/* WAR required */
return true;
}
@@ -11203,6 +11203,9 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
printf("%s: ** AP/GO Link up event **\n", __FUNCTION__);
wl_set_drv_status(cfg, AP_CREATED, ndev);
wake_up_interruptible(&cfg->netif_change_event);
+ if (!memcmp(ndev->name, WL_P2P_INTERFACE_PREFIX, strlen(WL_P2P_INTERFACE_PREFIX))) {
+ dhd_conf_set_mchan_bw(cfg->pub, WL_P2P_IF_GO, -1);
+ }
return 0;
}
}
@@ -11857,6 +11860,9 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
wl_update_prof(cfg, ndev, e, &act, WL_PROF_ACT);
wl_update_prof(cfg, ndev, NULL, (const void *)&e->addr, WL_PROF_BSSID);
dhd_conf_set_wme(cfg->pub, 0);
+ if (!memcmp(ndev->name, WL_P2P_INTERFACE_PREFIX, strlen(WL_P2P_INTERFACE_PREFIX))) {
+ dhd_conf_set_mchan_bw(cfg->pub, WL_P2P_IF_CLIENT, -1);
+ }
} else if (WL_IS_LINKDOWN(cfg, e, data) ||
((event == WLC_E_SET_SSID) &&
(ntoh32(e->status) != WLC_E_STATUS_SUCCESS) &&
diff --git a/bcmdhd.1.579.77.41.1.cn/wldev_common.c b/bcmdhd.1.579.77.41.1.cn/wldev_common.c
index 1b985b0..ebe656f 100644
--- a/bcmdhd.1.579.77.41.1.cn/wldev_common.c
+++ b/bcmdhd.1.579.77.41.1.cn/wldev_common.c
@@ -495,7 +495,7 @@ int wldev_set_country(
cspec.rev = revinfo;
memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
- error = dhd_conf_get_country_from_config(dhd_get_pub(dev), &cspec);
+ error = dhd_conf_map_country_list(dhd_get_pub(dev), &cspec, 0);
if (error)
dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);