diff options
author | Rongjun Chen <rongjun.chen@amlogic.com> | 2017-12-25 13:24:00 +0800 |
---|---|---|
committer | Rongjun Chen <rongjun.chen@amlogic.com> | 2017-12-25 13:24:00 +0800 |
commit | 91a2c11741597ad535bd522a5151ebb8076da262 (patch) | |
tree | 6eb56ac267e5e57e0174d9cd252498d3ed756b5a | |
parent | 5b98d48eda3cbc408c361b4aa81a3c8575e4ba69 (diff) | |
download | dhd-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/Kconfig | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | bcmdhd.1.579.77.41.1.cn/Makefile | 35 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c | 12 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd.h | 6 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_config.c | 494 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_config.h | 37 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_gpio.c | 25 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_linux.c | 34 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c | 23 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_pcie.c | 42 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_pcie.h | 1 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c | 15 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_pno.c | 4 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_sdio.c | 33 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c | 2 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/include/epivers.h | 2 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/include/wlioctl.h | 7 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/wl_android_ext.c | 4236 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c | 8 | ||||
-rw-r--r-- | bcmdhd.1.579.77.41.1.cn/wldev_common.c | 2 |
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", ¶m, 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, ðer_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, ðer_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, ðer_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, ðer_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); |