wifi: update bcm 1.57 wifi driver to fix ap6255 country code issue
authorRongjun Chen <rongjun.chen@amlogic.com>
Mon, 25 Dec 2017 05:24:00 +0000 (13:24 +0800)
committerRongjun Chen <rongjun.chen@amlogic.com>
Mon, 25 Dec 2017 05:24:00 +0000 (13:24 +0800)
PD# 157312

update wifi driver

Change-Id: I6a98921411f990dce92a2de5a6eb0d37da33fd4f

20 files changed:
bcmdhd.1.579.77.41.1.cn/Kconfig [changed mode: 0644->0755]
bcmdhd.1.579.77.41.1.cn/Makefile [changed mode: 0644->0755]
bcmdhd.1.579.77.41.1.cn/bcmsdh_sdmmc.c
bcmdhd.1.579.77.41.1.cn/dhd.h
bcmdhd.1.579.77.41.1.cn/dhd_config.c
bcmdhd.1.579.77.41.1.cn/dhd_config.h
bcmdhd.1.579.77.41.1.cn/dhd_gpio.c
bcmdhd.1.579.77.41.1.cn/dhd_linux.c
bcmdhd.1.579.77.41.1.cn/dhd_msgbuf.c
bcmdhd.1.579.77.41.1.cn/dhd_pcie.c
bcmdhd.1.579.77.41.1.cn/dhd_pcie.h
bcmdhd.1.579.77.41.1.cn/dhd_pcie_linux.c
bcmdhd.1.579.77.41.1.cn/dhd_pno.c
bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
bcmdhd.1.579.77.41.1.cn/dhd_static_buf.c
bcmdhd.1.579.77.41.1.cn/include/epivers.h
bcmdhd.1.579.77.41.1.cn/include/wlioctl.h
bcmdhd.1.579.77.41.1.cn/wl_android_ext.c
bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
bcmdhd.1.579.77.41.1.cn/wldev_common.c

old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 5788bb3..0e7e33d
@@ -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),)
index d98411f36509024cde71fa5b96f15f79ad9b8b2e..0921a6cc7cf85559d15e3e06d5558aa34d4369f1 100644 (file)
@@ -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>
index 0c46434c5d7a65894a5f572d174c91774f28ef47..bccc5bf76dea2e3daf0e3f03a7943b74bb3356ab 100644 (file)
@@ -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);
index 700573ffaa1f7c42ac41f9922f3b4f6b051fb9b9..5fddc377e60fb27283af7615fc0e4b44dc88f018 100644 (file)
@@ -59,6 +59,7 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
 #define CONFIG_BCM43341B0 "config_43341b0.txt"\r
 #define CONFIG_BCM43241B4 "config_43241b4.txt"\r
 #define CONFIG_BCM4339A0 "config_4339a0.txt"\r
+#define CONFIG_BCM43454C0 "config_43454c0.txt"\r
 #define CONFIG_BCM43455C0 "config_43455c0.txt"\r
 #define CONFIG_BCM43456C5 "config_43456c5.txt"\r
 #define CONFIG_BCM4354A1 "config_4354a1.txt"\r
@@ -80,7 +81,7 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
 #define FW_BCM43438A0 "fw_bcm43438a0"\r
 #define FW_BCM43438A1 "fw_bcm43438a1"\r
 #define FW_BCM43436B0 "fw_bcm43436b0"\r
-#define FW_BCM43012B0 "fw_bcm43012b0"\r
+#define FW_BCM43013B0 "fw_bcm43013b0"\r
 #define FW_BCM43341B1 "fw_bcm43341b0_ag"\r
 #define FW_BCM43241B4 "fw_bcm43241b4_ag"\r
 #define FW_BCM4339A0 "fw_bcm4339a0_ag"\r
@@ -92,10 +93,11 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
 #define FW_BCM4359B1 "fw_bcm4359b1_ag"\r
 #define FW_BCM4359C0 "fw_bcm4359c0_ag"\r
 \r
-#define CLM_BCM43012B0 "clm_bcm43012b0"\r
+#define CLM_BCM43013B0 "clm_bcm43013b0"\r
 #endif\r
 #ifdef BCMPCIE\r
 #define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"\r
+#define FW_BCM4359C0 "fw_bcm4359c0_pcie_ag"\r
 #endif\r
 \r
 #define htod32(i) i\r
@@ -389,6 +391,21 @@ dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)
 }\r
 #endif\r
 \r
+void\r
+dhd_conf_free_country_list(conf_country_list_t *country_list)\r
+{\r
+       int i;\r
+\r
+       CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
+       for (i=0; i<country_list->count; i++) {\r
+               if (country_list->cspec[i]) {\r
+                       CONFIG_TRACE(("%s Free cspec %p\n", __FUNCTION__, country_list->cspec[i]));\r
+                       kfree(country_list->cspec[i]);\r
+               }\r
+       }\r
+       country_list->count = 0;\r
+}\r
+\r
 void\r
 dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)\r
 {\r
@@ -417,7 +434,10 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
        /* find out the last '/' */\r
        i = strlen(fw_path);\r
        while (i > 0) {\r
-               if (fw_path[i] == '/') break;\r
+               if (fw_path[i] == '/') {\r
+                       i++;\r
+                       break;\r
+               }\r
                i--;\r
        }\r
 #ifdef BAND_AG\r
@@ -447,92 +467,93 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
                case BCM4330_CHIP_ID:\r
                        if (ag_type == FW_TYPE_G) {\r
                                if (chiprev == BCM4330B2_CHIP_REV)\r
-                                       strcpy(&fw_path[i+1], FW_BCM4330B2);\r
+                                       strcpy(&fw_path[i], FW_BCM4330B2);\r
                        } else {\r
                                if (chiprev == BCM4330B2_CHIP_REV)\r
-                                       strcpy(&fw_path[i+1], FW_BCM4330B2_AG);\r
+                                       strcpy(&fw_path[i], FW_BCM4330B2_AG);\r
                        }\r
                        break;\r
                case BCM43362_CHIP_ID:\r
                        if (chiprev == BCM43362A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43362A0);\r
+                               strcpy(&fw_path[i], FW_BCM43362A0);\r
                        else\r
-                               strcpy(&fw_path[i+1], FW_BCM43362A2);\r
+                               strcpy(&fw_path[i], FW_BCM43362A2);\r
                        break;\r
                case BCM43430_CHIP_ID:\r
                        if (chiprev == BCM43430A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43438A0);\r
+                               strcpy(&fw_path[i], FW_BCM43438A0);\r
                        else if (chiprev == BCM43430A1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43438A1);\r
+                               strcpy(&fw_path[i], FW_BCM43438A1);\r
                        else if (chiprev == BCM43430A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43436B0);\r
+                               strcpy(&fw_path[i], FW_BCM43436B0);\r
                        break;\r
                case BCM43012_CHIP_ID:\r
-                       if (chiprev == BCM43012B0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43012B0);\r
+                       if (chiprev == BCM43013B0_CHIP_REV)\r
+                               strcpy(&fw_path[i], FW_BCM43013B0);\r
                        break;\r
                case BCM4334_CHIP_ID:\r
                        if (chiprev == BCM4334B1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4334B1);\r
+                               strcpy(&fw_path[i], FW_BCM4334B1);\r
                        break;\r
                case BCM43340_CHIP_ID:\r
                case BCM43341_CHIP_ID:\r
                        if (chiprev == BCM43341B0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43341B1);\r
+                               strcpy(&fw_path[i], FW_BCM43341B1);\r
                        break;\r
                case BCM4324_CHIP_ID:\r
                        if (chiprev == BCM43241B4_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43241B4);\r
+                               strcpy(&fw_path[i], FW_BCM43241B4);\r
                        break;\r
                case BCM4335_CHIP_ID:\r
                        if (chiprev == BCM4335A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4339A0);\r
+                               strcpy(&fw_path[i], FW_BCM4339A0);\r
                        break;\r
                case BCM4339_CHIP_ID:\r
                        if (chiprev == BCM4339A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4339A0);\r
-                       break;\r
-               case BCM43454_CHIP_ID:\r
-                       if (chiprev == BCM43455C0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43455C0);\r
+                               strcpy(&fw_path[i], FW_BCM4339A0);\r
                        break;\r
                case BCM4345_CHIP_ID:\r
+               case BCM43454_CHIP_ID:\r
                        if (chiprev == BCM43455C0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43455C0);\r
-                       else if (chiprev == BCM43455C5_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43456C5);\r
+                               strcpy(&fw_path[i], FW_BCM43455C0);\r
+                       else if (chiprev == BCM43456C5_CHIP_REV)\r
+                               strcpy(&fw_path[i], FW_BCM43456C5);\r
                        break;\r
                case BCM4354_CHIP_ID:\r
                        if (chiprev == BCM4354A1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4354A1);\r
+                               strcpy(&fw_path[i], FW_BCM4354A1);\r
                        else if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4356A2);\r
+                               strcpy(&fw_path[i], FW_BCM4356A2);\r
                        break;\r
                case BCM4356_CHIP_ID:\r
                case BCM4371_CHIP_ID:\r
                        if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4356A2);\r
+                               strcpy(&fw_path[i], FW_BCM4356A2);\r
                        break;\r
                case BCM43569_CHIP_ID:\r
                        if (chiprev == BCM4358A3_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4358A3);\r
+                               strcpy(&fw_path[i], FW_BCM4358A3);\r
                        break;\r
                case BCM4359_CHIP_ID:\r
                        if (chiprev == BCM4359B1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4359B1);\r
+                               strcpy(&fw_path[i], FW_BCM4359B1);\r
                        else if (chiprev == BCM4359C0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4359C0);\r
+                               strcpy(&fw_path[i], FW_BCM4359C0);\r
                        break;\r
 #endif\r
 #ifdef BCMPCIE\r
                case BCM4354_CHIP_ID:\r
                case BCM4356_CHIP_ID:\r
                        if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4356A2);\r
+                               strcpy(&fw_path[i], FW_BCM4356A2);\r
+                       break;\r
+               case BCM4359_CHIP_ID:\r
+                       if (chiprev == BCM4359C0_CHIP_REV)\r
+                               strcpy(&fw_path[i], FW_BCM4359C0);\r
                        break;\r
 #endif\r
                default:\r
-                       strcpy(&fw_path[i+1], "fw_bcmdhd");\r
+                       strcpy(&fw_path[i], "fw_bcmdhd");\r
        }\r
        strcat(fw_path, fw_tail);\r
 \r
@@ -557,7 +578,10 @@ dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
        /* find out the last '/' */\r
        i = strlen(clm_path);\r
        while (i > 0) {\r
-               if (clm_path[i] == '/') break;\r
+               if (clm_path[i] == '/') {\r
+                       i++;\r
+                       break;\r
+               }\r
                i--;\r
        }\r
 \r
@@ -566,12 +590,12 @@ dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
        switch (chip) {\r
 #ifdef BCMSDIO\r
                case BCM43012_CHIP_ID:\r
-                       if (chiprev == BCM43012B0_CHIP_REV)\r
-                               strcpy(&clm_path[i+1], CLM_BCM43012B0);\r
+                       if (chiprev == BCM43013B0_CHIP_REV)\r
+                               strcpy(&clm_path[i], CLM_BCM43013B0);\r
                        break;\r
 #endif\r
                default:\r
-                       strcpy(&clm_path[i+1], "clm_bcmdhd");\r
+                       strcpy(&clm_path[i], "clm_bcmdhd");\r
        }\r
        strcat(clm_path, fw_tail);\r
 \r
@@ -612,11 +636,14 @@ dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
        /* find out the last '/' */\r
        i = strlen(nv_path);\r
        while (i > 0) {\r
-               if (nv_path[i] == '/') break;\r
+               if (nv_path[i] == '/') {\r
+                       i++;\r
+                       break;\r
+               }\r
                i--;\r
        }\r
 \r
-       strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);\r
+       strcpy(&nv_path[i], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);\r
 \r
        CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path));\r
 }\r
@@ -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 '/' */\r
        i = strlen(dst_path);\r
        while (i > 0) {\r
-               if (dst_path[i] == '/') break;\r
+               if (dst_path[i] == '/') {\r
+                       i++;\r
+                       break;\r
+               }\r
                i--;\r
        }\r
-       strcpy(&dst_path[i+1], dst_name);\r
+       strcpy(&dst_path[i], dst_name);\r
 \r
        CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));\r
 }\r
@@ -661,7 +691,10 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
        /* find out the last '/' */\r
        i = strlen(conf_path);\r
        while (i > 0) {\r
-               if (conf_path[i] == '/') break;\r
+               if (conf_path[i] == '/') {\r
+                       i++;\r
+                       break;\r
+               }\r
                i--;\r
        }\r
 \r
@@ -669,77 +702,84 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
 #ifdef BCMSDIO\r
                case BCM4330_CHIP_ID:\r
                        if (chiprev == BCM4330B2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4330B2);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4330B2);\r
                        break;\r
                case BCM43362_CHIP_ID:\r
                        if (chiprev == BCM43362A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43362A0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43362A0);\r
                        else\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43362A2);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43362A2);\r
                        break;\r
                case BCM43430_CHIP_ID:\r
                        if (chiprev == BCM43430A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43438A0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43438A0);\r
                        else if (chiprev == BCM43430A1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43438A1);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43438A1);\r
                        else if (chiprev == BCM43430A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43436B0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43436B0);\r
                        break;\r
                case BCM4334_CHIP_ID:\r
                        if (chiprev == BCM4334B1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4334B1);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4334B1);\r
                        break;\r
                case BCM43340_CHIP_ID:\r
                case BCM43341_CHIP_ID:\r
                        if (chiprev == BCM43341B0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43341B0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43341B0);\r
                        break;\r
                case BCM4324_CHIP_ID:\r
                        if (chiprev == BCM43241B4_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43241B4);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43241B4);\r
                        break;\r
                case BCM4335_CHIP_ID:\r
                        if (chiprev == BCM4335A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4339A0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4339A0);\r
                        break;\r
-               case BCM4345_CHIP_ID:\r
                case BCM43454_CHIP_ID:\r
                        if (chiprev == BCM43455C0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43455C0);\r
-                       else if (chiprev == BCM43455C5_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43456C5);\r
+                               strcpy(&conf_path[i], CONFIG_BCM43454C0);\r
+                       break;\r
+               case BCM4345_CHIP_ID:\r
+                       if (chiprev == BCM43455C0_CHIP_REV)\r
+                               strcpy(&conf_path[i], CONFIG_BCM43455C0);\r
+                       else if (chiprev == BCM43456C5_CHIP_REV)\r
+                               strcpy(&conf_path[i], CONFIG_BCM43456C5);\r
                        break;\r
                case BCM4339_CHIP_ID:\r
                        if (chiprev == BCM4339A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4339A0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4339A0);\r
                        break;\r
                case BCM4354_CHIP_ID:\r
                        if (chiprev == BCM4354A1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4354A1);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4354A1);\r
                        else if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4356A2);\r
                        break;\r
                case BCM4356_CHIP_ID:\r
                case BCM4371_CHIP_ID:\r
                        if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4356A2);\r
                        break;\r
                case BCM43569_CHIP_ID:\r
                        if (chiprev == BCM4358A3_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4358A3);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4358A3);\r
                        break;\r
                case BCM4359_CHIP_ID:\r
                        if (chiprev == BCM4359B1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4359B1);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4359B1);\r
                        else if (chiprev == BCM4359C0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4359C0);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4359C0);\r
                        break;\r
 #endif\r
 #ifdef BCMPCIE\r
                case BCM4354_CHIP_ID:\r
                case BCM4356_CHIP_ID:\r
                        if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
+                               strcpy(&conf_path[i], CONFIG_BCM4356A2);\r
+                       break;\r
+               case BCM4359_CHIP_ID:\r
+                       if (chiprev == BCM4359C0_CHIP_REV)\r
+                               strcpy(&conf_path[i], CONFIG_BCM4359C0);\r
                        break;\r
 #endif\r
        }\r
@@ -838,19 +878,6 @@ dhd_conf_get_band(dhd_pub_t *dhd)
        return band;\r
 }\r
 \r
-int\r
-dhd_conf_set_country(dhd_pub_t *dhd)\r
-{\r
-       int bcmerror = -1;\r
-\r
-       memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));\r
-       printf("%s: set country %s, revision %d\n", __FUNCTION__,\r
-               dhd->conf->cspec.ccode, dhd->conf->cspec.rev);\r
-       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);\r
-\r
-       return bcmerror;\r
-}\r
-\r
 int\r
 dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)\r
 {\r
@@ -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));\r
        if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)\r
                CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));\r
-       else\r
-               printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);\r
 \r
        return bcmerror;\r
 }\r
 \r
 int\r
-dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)\r
+dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec, int nodfs)\r
 {\r
        int bcmerror = -1, i;\r
        struct dhd_conf *conf = dhd->conf;\r
+       conf_country_list_t *country_list;\r
+\r
+       if ((nodfs > 0 || dhd->op_mode & DHD_FLAG_HOSTAP_MODE) &&\r
+                       conf->country_list_nodfs.count > 0) {\r
+               country_list = &conf->country_list_nodfs;\r
+       } else {\r
+               country_list = &conf->country_list;\r
+       }\r
 \r
-       for (i = 0; i < conf->country_list.count; i++) {\r
-               if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) {\r
-                       memcpy(cspec->ccode,\r
-                               conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);\r
-                       cspec->rev = conf->country_list.cspec[i].rev;\r
+       for (i = 0; i < country_list->count; i++) {\r
+               if (!strncmp(cspec->country_abbrev, country_list->cspec[i]->country_abbrev, 2)) {\r
+                       memcpy(cspec->ccode, country_list->cspec[i]->ccode, WLC_CNTRY_BUF_SZ);\r
+                       cspec->rev = country_list->cspec[i]->rev;\r
                        printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
                        return 0;\r
                }\r
@@ -885,6 +917,21 @@ dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
        return bcmerror;\r
 }\r
 \r
+int\r
+dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec)\r
+{\r
+       int bcmerror = -1;\r
+\r
+       memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));\r
+\r
+       printf("%s: set country %s, revision %d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
+       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec, sizeof(wl_country_t), FALSE);\r
+       dhd_conf_get_country(dhd, cspec);\r
+       printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);\r
+\r
+       return bcmerror;\r
+}\r
+\r
 int\r
 dhd_conf_fix_country(dhd_pub_t *dhd)\r
 {\r
@@ -892,6 +939,7 @@ dhd_conf_fix_country(dhd_pub_t *dhd)
        uint band;\r
        wl_uint32_list_t *list;\r
        u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
+       wl_country_t cspec;\r
 \r
        if (!(dhd && dhd->conf)) {\r
                return bcmerror;\r
@@ -910,11 +958,13 @@ dhd_conf_fix_country(dhd_pub_t *dhd)
                        dtoh32(list->count)<11)) {\r
                CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",\r
                        __FUNCTION__, bcmerror, dtoh32(list->count)));\r
-               if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {\r
-                       strcpy(dhd->conf->cspec.country_abbrev, "US");\r
-                       dhd->conf->cspec.rev = 0;\r
-                       strcpy(dhd->conf->cspec.ccode, "US");\r
-                       dhd_conf_set_country(dhd);\r
+               dhd_conf_map_country_list(dhd, &dhd->conf->cspec, 0);\r
+               if ((bcmerror = dhd_conf_set_country(dhd, &dhd->conf->cspec)) < 0) {\r
+                       strcpy(cspec.country_abbrev, "US");\r
+                       cspec.rev = 0;\r
+                       strcpy(cspec.ccode, "US");\r
+                       dhd_conf_map_country_list(dhd, &cspec, 0);\r
+                       dhd_conf_set_country(dhd, &cspec);\r
                }\r
        }\r
 \r
@@ -1131,12 +1181,32 @@ dhd_conf_set_wme(dhd_pub_t *dhd, int mode)
        return;\r
 }\r
 \r
+void\r
+dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int p2p_mode, int miracast_mode)\r
+{\r
+       int i;\r
+       struct dhd_conf *conf = dhd->conf;\r
+       bool set = true;\r
+\r
+       for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+               set = true;\r
+               set &= (conf->mchan[i].bw >= 0);\r
+               set &= ((conf->mchan[i].p2p_mode == -1) | (conf->mchan[i].p2p_mode == p2p_mode));\r
+               set &= ((conf->mchan[i].miracast_mode == -1) | (conf->mchan[i].miracast_mode == miracast_mode));\r
+               if (set) {\r
+                       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mchan_bw", conf->mchan[i].bw, 0, FALSE);\r
+               }\r
+       }\r
+\r
+       return;\r
+}\r
+\r
 #ifdef PKT_FILTER_SUPPORT\r
 void\r
 dhd_conf_add_pkt_filter(dhd_pub_t *dhd)\r
 {\r
        int i, j;\r
-       char str[12];\r
+       char str[16];\r
 #define MACS "%02x%02x%02x%02x%02x%02x"\r
 \r
        /*\r
@@ -1157,17 +1227,17 @@ dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
        }\r
        dhd->pktfilter_count += i;\r
 \r
-       for(i=0; i<dhd->conf->magic_pkt_filter_add.count; i++) {\r
-               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");\r
-               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");\r
+       if (dhd->conf->magic_pkt_filter_add) {\r
+               strcat(dhd->conf->magic_pkt_filter_add, " 0x");\r
+               strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");\r
                for (j=0; j<16; j++)\r
-                       strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");\r
-               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");\r
-               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");\r
+                       strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");\r
+               strcat(dhd->conf->magic_pkt_filter_add, " 0x");\r
+               strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");\r
                sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));\r
                for (j=0; j<16; j++)\r
-                       strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str);\r
-               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i];\r
+                       strncat(dhd->conf->magic_pkt_filter_add, str, 12);\r
+               dhd->pktfilter[dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add;\r
                dhd->pktfilter_count += 1;\r
        }\r
 }\r
@@ -1730,6 +1800,7 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
        char *pch, *pick_tmp;\r
        struct dhd_conf *conf = dhd->conf;\r
        char *data = full_param+len_param;\r
+       wl_country_t *cspec;\r
 \r
        /* Process country_list:\r
         * country_list=[country1]:[ccode1]/[regrev1],\r
@@ -1743,23 +1814,125 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
                        pch = bcmstrtok(&pick_tmp, ":", 0);\r
                        if (!pch)\r
                                break;\r
-                       strcpy(conf->country_list.cspec[i].country_abbrev, pch);\r
+                       cspec = NULL;\r
+                       if (!(cspec = kmalloc(sizeof(wl_country_t), GFP_KERNEL))) {\r
+                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+                               break;\r
+                       }\r
+                       conf->country_list.count++;\r
+                       memset(cspec, 0, sizeof(wl_country_t));\r
+                       conf->country_list.cspec[i] = cspec;\r
+\r
+                       strcpy(cspec->country_abbrev, pch);\r
                        pch = bcmstrtok(&pick_tmp, "/", 0);\r
                        if (!pch)\r
                                break;\r
-                       memcpy(conf->country_list.cspec[i].ccode, pch, 2);\r
+                       memcpy(cspec->ccode, pch, 2);\r
                        pch = bcmstrtok(&pick_tmp, ", ", 0);\r
                        if (!pch)\r
                                break;\r
-                       conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);\r
-                       conf->country_list.count ++;\r
+                       cspec->rev = (int32)simple_strtol(pch, NULL, 10);\r
                        CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,\r
-                               conf->country_list.cspec[i].country_abbrev,\r
-                               conf->country_list.cspec[i].ccode,\r
-                               conf->country_list.cspec[i].rev));\r
+                               cspec->country_abbrev, cspec->ccode, cspec->rev));\r
                }\r
                printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);\r
        }\r
+       else if (!strncmp("country_list_nodfs=", full_param, len_param)) {\r
+               pick_tmp = data;\r
+               for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {\r
+                       /* Process country code */\r
+                       pch = bcmstrtok(&pick_tmp, ":", 0);\r
+                       if (!pch)\r
+                               break;\r
+                       cspec = NULL;\r
+                       if (!(cspec = kmalloc(sizeof(wl_country_t), GFP_KERNEL))) {\r
+                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+                               break;\r
+                       }\r
+                       conf->country_list_nodfs.count++;\r
+                       memset(cspec, 0, sizeof(wl_country_t));\r
+                       conf->country_list_nodfs.cspec[i] = cspec;\r
+\r
+                       strcpy(cspec->country_abbrev, pch);\r
+                       pch = bcmstrtok(&pick_tmp, "/", 0);\r
+                       if (!pch)\r
+                               break;\r
+                       memcpy(cspec->ccode, pch, 2);\r
+                       pch = bcmstrtok(&pick_tmp, ", ", 0);\r
+                       if (!pch)\r
+                               break;\r
+                       cspec->rev = (int32)simple_strtol(pch, NULL, 10);\r
+                       CONFIG_TRACE(("%s: country_list_nodfs abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,\r
+                               cspec->country_abbrev, cspec->ccode, cspec->rev));\r
+               }\r
+               printf("%s: %d nodfs country in list\n", __FUNCTION__, conf->country_list_nodfs.count);\r
+       }\r
+       else\r
+               return false;\r
+\r
+       return true;\r
+}\r
+\r
+bool\r
+dhd_conf_read_mchan_params(dhd_pub_t *dhd, char *full_param, uint len_param)\r
+{\r
+       int i;\r
+       char *pch, *pick_tmp, *pick_tmp2;\r
+       struct dhd_conf *conf = dhd->conf;\r
+       char *data = full_param+len_param;\r
+\r
+       /* Process mchan_bw and btc_params_mgmt:\r
+        * mchan_bw=[val]/[any/go/gc]/[any/source/sink]\r
+        * Ex: mchan_bw=80/go/source, 30/gc/sink\r
+        */\r
+       if (!strncmp("mchan_bw=", full_param, len_param)) {\r
+               pick_tmp = data;\r
+               for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+                       pick_tmp2 = bcmstrtok(&pick_tmp, ", ", 0);\r
+                       if (!pick_tmp2)\r
+                               break;\r
+                       pch = bcmstrtok(&pick_tmp2, "/", 0);\r
+                       if (!pch) {\r
+                               break;\r
+                       } else {\r
+                               conf->mchan[i].bw = (int)simple_strtol(pch, NULL, 0);\r
+                               if (conf->mchan[i].bw < 0 || conf->mchan[i].bw > 100) {\r
+                                       CONFIG_ERROR(("%s: wrong bw %d\n", __FUNCTION__, conf->mchan[i].bw));\r
+                                       conf->mchan[i].bw = 0;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       pch = bcmstrtok(&pick_tmp2, "/", 0);\r
+                       if (!pch) {\r
+                               break;\r
+                       } else {\r
+                               if (bcmstrstr(pch, "any")) {\r
+                                       conf->mchan[i].p2p_mode = -1;\r
+                               } else if (bcmstrstr(pch, "go")) {\r
+                                       conf->mchan[i].p2p_mode = WL_P2P_IF_GO;\r
+                               } else if (bcmstrstr(pch, "gc")) {\r
+                                       conf->mchan[i].p2p_mode = WL_P2P_IF_CLIENT;\r
+                               }\r
+                       }\r
+                       pch = bcmstrtok(&pick_tmp2, "/", 0);\r
+                       if (!pch) {\r
+                               break;\r
+                       } else {\r
+                               if (bcmstrstr(pch, "any")) {\r
+                                       conf->mchan[i].miracast_mode = -1;\r
+                               } else if (bcmstrstr(pch, "source")) {\r
+                                       conf->mchan[i].miracast_mode = MIRACAST_SOURCE;\r
+                               } else if (bcmstrstr(pch, "sink")) {\r
+                                       conf->mchan[i].miracast_mode = MIRACAST_SINK;\r
+                               }\r
+                       }\r
+               }\r
+               for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+                       if (conf->mchan[i].bw >= 0)\r
+                               printf("%s: mchan_bw=%d/%d/%d\n", __FUNCTION__,\r
+                                       conf->mchan[i].bw, conf->mchan[i].p2p_mode, conf->mchan[i].miracast_mode);\r
+               }\r
+       }\r
        else\r
                return false;\r
 \r
@@ -1815,16 +1988,13 @@ dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param)
                printf("\n");\r
        }\r
        else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {\r
-               pick_tmp = data;\r
-               pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
-               i=0;\r
-               while (pch != NULL && i<DHD_CONF_FILTER_MAX) {\r
-                       strcpy(&conf->magic_pkt_filter_add.filter[i][0], pch);\r
-                       printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]);\r
-                       pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
-                       i++;\r
+               if (!(conf->magic_pkt_filter_add = kmalloc(MAGIC_PKT_FILTER_LEN, GFP_KERNEL))) {\r
+                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+               } else {\r
+                       memset(conf->magic_pkt_filter_add, 0, MAGIC_PKT_FILTER_LEN);\r
+                       strcpy(conf->magic_pkt_filter_add, data);\r
+                       printf("%s: magic_pkt_filter_add = %s\n", __FUNCTION__, conf->magic_pkt_filter_add);\r
                }\r
-               conf->magic_pkt_filter_add.count = i;\r
        }\r
        else\r
                return false;\r
@@ -2007,13 +2177,6 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
                        conf->bus_rxglom = TRUE;\r
                printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);\r
        }\r
-       else if (!strncmp("dhd_poll=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->dhd_poll = 0;\r
-               else\r
-                       conf->dhd_poll = 1;\r
-               printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);\r
-       }\r
        else if (!strncmp("deferred_tx_len=", full_param, len_param)) {\r
                conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);\r
                printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);\r
@@ -2048,6 +2211,27 @@ dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
 }\r
 #endif\r
 \r
+#ifdef BCMPCIE\r
+bool\r
+dhd_conf_read_pcie_params(dhd_pub_t *dhd, char *full_param, uint len_param)\r
+{\r
+       struct dhd_conf *conf = dhd->conf;\r
+       char *data = full_param+len_param;\r
+\r
+       if (!strncmp("bus:deepsleep_disable=", full_param, len_param)) {\r
+               if (!strncmp(data, "0", 1))\r
+                       conf->bus_deepsleep_disable = 0;\r
+               else\r
+                       conf->bus_deepsleep_disable = 1;\r
+               printf("%s: bus:deepsleep_disable = %d\n", __FUNCTION__, conf->bus_deepsleep_disable);\r
+       }\r
+       else\r
+               return false;\r
+\r
+       return true;\r
+}\r
+#endif\r
+\r
 bool\r
 dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)\r
 {\r
@@ -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);\r
                printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);\r
        }\r
+#ifdef SUSPEND_EVENT\r
+       else if (!strncmp("suspend_eventmask_enable=", full_param, len_param)) {\r
+               if (!strncmp(data, "1", 1))\r
+                       conf->suspend_eventmask_enable = TRUE;\r
+               else\r
+                       conf->suspend_eventmask_enable = FALSE;\r
+               printf("%s: suspend_eventmask_enable = %d\n", __FUNCTION__, conf->suspend_eventmask_enable);\r
+       }\r
+#endif\r
        else\r
                return false;\r
 \r
@@ -2103,7 +2296,18 @@ dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
        char *pch, *pick_tmp;\r
        int i;\r
 \r
-       if (!strncmp("band=", full_param, len_param)) {\r
+       if (!strncmp("dhd_poll=", full_param, len_param)) {\r
+               if (!strncmp(data, "0", 1))\r
+                       conf->dhd_poll = 0;\r
+               else\r
+                       conf->dhd_poll = 1;\r
+               printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);\r
+       }\r
+       else if (!strncmp("dhd_watchdog_ms=", full_param, len_param)) {\r
+               dhd_watchdog_ms = (int)simple_strtol(data, NULL, 10);\r
+               printf("%s: dhd_watchdog_ms = %d\n", __FUNCTION__, dhd_watchdog_ms);\r
+       }\r
+       else if (!strncmp("band=", full_param, len_param)) {\r
                /* Process band:\r
                 * band=a for 5GHz only and band=b for 2.4GHz only\r
                 */\r
@@ -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);\r
                printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);\r
        }\r
+       else if (!strncmp("ctrl_resched=", full_param, len_param)) {\r
+               conf->ctrl_resched = (int)simple_strtol(data, NULL, 10);\r
+               printf("%s: ctrl_resched = %d\n", __FUNCTION__, conf->ctrl_resched);\r
+       }\r
+       else if (!strncmp("dhd_ioctl_timeout_msec=", full_param, len_param)) {\r
+               conf->dhd_ioctl_timeout_msec = (int)simple_strtol(data, NULL, 10);\r
+               printf("%s: dhd_ioctl_timeout_msec = %d\n", __FUNCTION__, conf->dhd_ioctl_timeout_msec);\r
+       }\r
        else\r
                return false;\r
 \r
@@ -2324,6 +2536,8 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                                continue;\r
                        else if (dhd_conf_read_country_list(dhd, pick, len_param))\r
                                continue;\r
+                       else if (dhd_conf_read_mchan_params(dhd, pick, len_param))\r
+                               continue;\r
 #ifdef PKT_FILTER_SUPPORT\r
                        else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))\r
                                continue;\r
@@ -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))\r
                                continue;\r
 #endif /* BCMSDIO */\r
+#ifdef BCMPCIE\r
+                       else if (dhd_conf_read_pcie_params(dhd, pick, len_param))\r
+                               continue;\r
+#endif /* BCMPCIE */\r
                        else if (dhd_conf_read_pm_params(dhd, pick, len_param))\r
                                continue;\r
                        else if (dhd_conf_read_others(dhd, pick, len_param))\r
@@ -2435,6 +2653,7 @@ int
 dhd_conf_preinit(dhd_pub_t *dhd)\r
 {\r
        struct dhd_conf *conf = dhd->conf;\r
+       int i;\r
 \r
        CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
 \r
@@ -2443,6 +2662,10 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        dhd_conf_free_mac_list(&conf->nv_by_mac);\r
        dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);\r
 #endif\r
+       dhd_conf_free_country_list(&conf->country_list);\r
+       dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);\r
+       if (conf->magic_pkt_filter_add)\r
+               kfree(conf->magic_pkt_filter_add);\r
        memset(&conf->country_list, 0, sizeof(conf_country_list_t));\r
        conf->band = -1;\r
        conf->mimo_bw_cap = -1;\r
@@ -2499,7 +2722,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
 #ifdef PKT_FILTER_SUPPORT\r
        memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));\r
        memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));\r
-       memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t));\r
 #endif\r
        conf->srl = -1;\r
        conf->lrl = -1;\r
@@ -2508,6 +2730,7 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->txbf = -1;\r
        conf->lpc = -1;\r
        conf->disable_proptx = -1;\r
+       conf->dhd_poll = -1;\r
 #ifdef BCMSDIO\r
        conf->bus_txglom = -1;\r
        conf->use_rxchain = 0;\r
@@ -2515,7 +2738,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->txglom_ext = FALSE;\r
        conf->tx_max_offset = 0;\r
        conf->txglomsize = SDPCM_DEFGLOM_SIZE;\r
-       conf->dhd_poll = -1;\r
        conf->txctl_tmo_fix = 5;\r
        conf->tx_in_rx = TRUE;\r
        conf->txglom_mode = SDPCM_TXGLOM_MDESC;\r
@@ -2524,6 +2746,9 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->txinrx_thres = -1;\r
        conf->sd_f2_blocksize = 0;\r
        conf->oob_enabled_later = FALSE;\r
+#endif\r
+#ifdef BCMPCIE\r
+       conf->bus_deepsleep_disable = 1;\r
 #endif\r
        conf->ampdu_ba_wsize = 0;\r
        conf->ampdu_hostreorder = -1;\r
@@ -2537,6 +2762,11 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->num_different_channels = -1;\r
        conf->xmit_in_suspend = TRUE;\r
        conf->ap_in_suspend = 0;\r
+#ifdef SUSPEND_EVENT\r
+       conf->suspend_eventmask_enable = FALSE;\r
+       memset(&conf->suspend_eventmask, 0, sizeof(conf->suspend_eventmask));\r
+       memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));\r
+#endif\r
 #ifdef IDHCP\r
        conf->dhcpc_enable = -1;\r
        conf->dhcpd_enable = -1;\r
@@ -2553,19 +2783,27 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->rsdb_mode = -2;\r
        conf->vhtmode = -1;\r
        conf->autocountry = -1;\r
+       conf->ctrl_resched = 2;\r
+       conf->dhd_ioctl_timeout_msec = 0;\r
 #ifdef IAPSTA_PREINIT\r
        memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init));\r
        memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config));\r
        memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable));\r
 #endif\r
+       for (i=0; i<MCHAN_MAX_NUM; i++) {\r
+               memset(&conf->mchan[i], -1, sizeof(mchan_params_t));\r
+       }\r
 #ifdef CUSTOMER_HW_AMLOGIC\r
        dhd_slpauto = FALSE;\r
+       conf->txglom_mode = SDPCM_TXGLOM_CPY;\r
 #endif\r
        if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||\r
                        conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||\r
                        conf->chip == BCM4359_CHIP_ID) {\r
 #ifdef DHDTCPACK_SUPPRESS\r
+#ifdef BCMSDIO\r
                conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;\r
+#endif\r
 #endif\r
                dhd_rxbound = 128;\r
                dhd_txbound = 64;\r
@@ -2620,6 +2858,10 @@ dhd_conf_reset(dhd_pub_t *dhd)
        dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);\r
        dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);\r
 #endif\r
+       dhd_conf_free_country_list(&dhd->conf->country_list);\r
+       dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);\r
+       if (dhd->conf->magic_pkt_filter_add)\r
+               kfree(dhd->conf->magic_pkt_filter_add);\r
        memset(dhd->conf, 0, sizeof(dhd_conf_t));\r
        return 0;\r
 }\r
@@ -2663,6 +2905,10 @@ dhd_conf_detach(dhd_pub_t *dhd)
                dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);\r
                dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);\r
 #endif\r
+               dhd_conf_free_country_list(&dhd->conf->country_list);\r
+               dhd_conf_free_country_list(&dhd->conf->country_list_nodfs);\r
+               if (dhd->conf->magic_pkt_filter_add)\r
+                       kfree(dhd->conf->magic_pkt_filter_add);\r
                MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));\r
        }\r
        dhd->conf = NULL;\r
index 5fdd538a0b8b65cf403e1da83b134e9bd525ed8e..ca295f1d5e8c69671f75dfb216b752ceaf01b33f 100644 (file)
@@ -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;
@@ -162,6 +174,9 @@ typedef struct dhd_conf {
        int dhd_txminmax; // -1=DATABUFCNT(bus)
        uint sd_f2_blocksize;
        bool oob_enabled_later;
+#endif
+#ifdef BCMPCIE
+       int bus_deepsleep_disable;
 #endif
        int ampdu_ba_wsize;
        int ampdu_hostreorder;
@@ -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);
index 78537c88252e83a1765aae1b9dce7549a43303ae..1d2ce75b5f5038389c892047cdd634d88afcd03e 100644 (file)
@@ -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,
 };
index 3bf901c8ec76b1718783c7342f98994c205214cd..70944f592abd79fbdc404fe23e41f2a2371f6d29 100644 (file)
@@ -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);
 }
index e602d24f2e6afc6ced4e5b4ce977896c0c9d3e3b..455f125a9687fa181108d5eb4a13a125f0a026d6 100644 (file)
@@ -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;
 
index 77995b585d2755ef85223427fe7b2a1e5aa73f73..48e3d19b1d96cb59651cf0375acaee1fb63ffebd 100644 (file)
@@ -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!! */
        }
index eb8de62956bf3ffaf1b2b873419a8868b7042994..92b07c6e4bc742df886703d3426d0012691acc6a 100644 (file)
@@ -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 */
index 51664a7e217b0a34faf7d39afe8c99f91fbde99f..5c9561a615d50e788393e21e0b4c40a53dcb7842 100644 (file)
@@ -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__));
                }
index c553733f682e411704d3cfc75b1a20b5d2a75d75..c20ed7b33996ba769411f21b442fc504511ad91a 100644 (file)
@@ -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;
index 1dcdd281afc219c06bb6580f71332756b2c9807b..fe2e874bffdbef61e37038969ebf83f948f2a56c 100644 (file)
@@ -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));
index 50573e406de1797fc2ad75b6cba56d103724bcd6..33997cd8b78435a31f2aadf97cfdc0370ad916fc 100644 (file)
@@ -73,7 +73,7 @@ enum dhd_prealloc_index {
 #define DHD_PREALLOC_OSL_BUF_SIZE      (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)\r
 #define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)\r
 #define DHD_PREALLOC_DHD_INFO_SIZE     (30 * 1024)\r
-#define DHD_PREALLOC_MEMDUMP_RAM_SIZE  (770 * 1024)\r
+#define DHD_PREALLOC_MEMDUMP_RAM_SIZE  (810 * 1024)\r
 #define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE      (73 * 1024)\r
 #define DHD_PREALLOC_WL_ESCAN_INFO_SIZE        (66 * 1024)\r
 #ifdef CONFIG_64BIT\r
index 4cf4c70348c8d45e398a89d1d1ac9021b8ed1182..a2dc35e68b98f18c2ab5a02ace6ed56706c992a2 100644 (file)
@@ -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_ */
index 82c4b4feb04d2834ed8dd035da507f68b69b6b1d..1e6a3a280e0819a86320571366b11cfbfc50ae20 100644 (file)
@@ -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 */
index 507edc16cd16812467be5647b40b0ae27d0edded..62653380f9f271fb8fa3ecebad1f11c3137fa3d0 100644 (file)
-\r
-\r
-#include <linux/module.h>\r
-#include <linux/netdevice.h>\r
-#include <net/netlink.h>\r
-\r
-#include <wl_android.h>\r
-#include <wldev_common.h>\r
-#include <wlioctl.h>\r
-#include <bcmutils.h>\r
-#include <linux_osl.h>\r
-#include <dhd_dbg.h>\r
-#include <dngl_stats.h>\r
-#include <dhd.h>\r
-#include <dhd_config.h>\r
-\r
-#define htod32(i) i\r
-#define htod16(i) i\r
-#define dtoh32(i) i\r
-#define dtoh16(i) i\r
-#define htodchanspec(i) i\r
-#define dtohchanspec(i) i\r
-#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))\r
-\r
-#define CMD_CHANNEL                            "CHANNEL"\r
-#define CMD_CHANNELS                   "CHANNELS"\r
-#define CMD_ROAM_TRIGGER               "ROAM_TRIGGER"\r
-#define CMD_KEEP_ALIVE                 "KEEP_ALIVE"\r
-#define CMD_PM                                 "PM"\r
-#define CMD_MONITOR                            "MONITOR"\r
-#define CMD_SET_SUSPEND_BCN_LI_DTIM            "SET_SUSPEND_BCN_LI_DTIM"\r
-\r
-#ifdef WL_EXT_IAPSTA\r
-#define CMD_IAPSTA_INIT                        "IAPSTA_INIT"\r
-#define CMD_IAPSTA_CONFIG              "IAPSTA_CONFIG"\r
-#define CMD_IAPSTA_ENABLE              "IAPSTA_ENABLE"\r
-#define CMD_IAPSTA_DISABLE             "IAPSTA_DISABLE"\r
-#ifdef PROP_TXSTATUS\r
-#ifdef PROP_TXSTATUS_VSDB\r
-#include <dhd_wlfc.h>\r
+
+
+#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 */\r
-#endif\r
-#endif\r
-#ifdef IDHCP\r
-#define CMD_DHCPC_ENABLE       "DHCPC_ENABLE"\r
-#define CMD_DHCPC_DUMP         "DHCPC_DUMP"\r
-#endif\r
-#define CMD_WL         "WL"\r
-\r
-#define IEEE80211_BAND_2GHZ 0\r
-#define IEEE80211_BAND_5GHZ 1\r
-\r
-int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)\r
-{\r
-       int ret;\r
-\r
-       ret = wldev_ioctl(dev, cmd, arg, len, set);\r
-       if (ret)\r
-               ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret));\r
-       return ret;\r
-}\r
-\r
-int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val)\r
-{\r
-       int ret;\r
-\r
-       ret = wldev_iovar_getint(dev, iovar, val);\r
-       if (ret)\r
-               ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));\r
-\r
-       return ret;\r
-}\r
-\r
-int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val)\r
-{\r
-       int ret;\r
-\r
-       ret = wldev_iovar_setint(dev, iovar, val);\r
-       if (ret)\r
-               ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret));\r
-\r
-       return ret;\r
-}\r
-\r
-int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name,\r
-       void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)\r
-{\r
-       int ret;\r
-\r
-       ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);\r
-       if (ret != 0)\r
-               ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
-       return ret;\r
-}\r
-\r
-int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name,\r
-       void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)\r
-{\r
-       int ret;\r
-\r
-       ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync);\r
-       if (ret != 0)\r
-               ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
-       return ret;\r
-}\r
-\r
-#ifdef WL_EXT_IAPSTA\r
-int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name,\r
-       void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)\r
-{\r
-       int ret;\r
-       \r
-       ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen,\r
-               buf, buflen, bsscfg_idx, buf_sync);\r
-       if (ret < 0)\r
-               ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
-       return ret;\r
-}\r
-\r
-int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name,\r
-       void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)\r
-{\r
-       int ret;\r
-       \r
-       ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen,\r
-               buf, buflen, bsscfg_idx, buf_sync);\r
-       if (ret < 0)\r
-               ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret));\r
-\r
-       return ret;\r
-}\r
-#endif\r
+#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)\r
+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",\r
+               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((\r
-                       "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "\r
+               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;
-}\r
+}
 
 /* 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)\r
+wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec)
 {
-       if (ioctl_ver == 1) {\r
-               chanspec = wl_ext_chspec_to_legacy(chanspec);\r
+       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;
-}\r
-\r
-static int\r
-wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver)\r
-{\r
-       int ret = 0;\r
-       s32 val = 0;\r
-\r
-       val = 1;\r
-       ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0);\r
-       if (ret) {\r
-               ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret));\r
-               return ret;\r
-       }\r
-       val = dtoh32(val);\r
-       if (val != WLC_IOCTL_VERSION && val != 1) {\r
-               ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",\r
-                       val, WLC_IOCTL_VERSION));\r
-               return BCME_VERSION;\r
-       }\r
-       *ioctl_ver = val;\r
-\r
-       return ret;\r
-}\r
-\r
-static int\r
-wl_ext_set_chanspec(struct net_device *dev, uint16 channel)\r
-{\r
-       s32 _chan = channel;\r
+}
+
+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;\r
-       u32 bw = WL_CHANSPEC_BW_20;\r
+       chanspec_t fw_chspec = 0;
+       u32 bw = WL_CHANSPEC_BW_20;
        s32 err = BCME_OK;
-       s32 bw_cap = 0;\r
-       s8 iovar_buf[WLC_IOCTL_SMLEN];\r
+       s32 bw_cap = 0;
+       s8 iovar_buf[WLC_IOCTL_SMLEN];
        struct {
                u32 band;
                u32 bw_cap;
-       } param = {0, 0};\r
-       uint band;\r
-       int ioctl_ver = 0;\r
-\r
-       if (_chan <= CH_MAX_2G_CHANNEL)\r
-               band = IEEE80211_BAND_2GHZ;\r
-       else\r
-               band = IEEE80211_BAND_5GHZ;\r
-       wl_ext_get_ioctl_ver(dev, &ioctl_ver);\r
-\r
-       if (band == IEEE80211_BAND_5GHZ) {\r
+       } param = {0, 0};
+       uint band;
+       int ioctl_ver = 0;
+
+       if (_chan <= CH_MAX_2G_CHANNEL)
+               band = IEEE80211_BAND_2GHZ;
+       else
+               band = IEEE80211_BAND_5GHZ;
+       wl_ext_get_ioctl_ver(dev, &ioctl_ver);
+
+       if (band == IEEE80211_BAND_5GHZ) {
                param.band = WLC_BAND_5G;
                err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
-                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
+                       iovar_buf, WLC_IOCTL_SMLEN, NULL);
                if (err) {
                        if (err != BCME_UNSUPPORTED) {
-                               ANDROID_ERROR(("bw_cap failed, %d\n", err));\r
+                               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));\r
+                                       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]))\r
+                       if (WL_BW_CAP_80MHZ(iovar_buf[0]))
                                bw = WL_CHANSPEC_BW_80;
-                       else if (WL_BW_CAP_40MHZ(iovar_buf[0]))\r
+                       else if (WL_BW_CAP_40MHZ(iovar_buf[0]))
                                bw = WL_CHANSPEC_BW_40;
                        else
                                bw = WL_CHANSPEC_BW_20;
 
-               }\r
-       }\r
-       else if (band == IEEE80211_BAND_2GHZ)\r
-               bw = WL_CHANSPEC_BW_20;\r
-\r
+               }
+       }
+       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);\r
+               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) {\r
+                       if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) {
                                if (bw == WL_CHANSPEC_BW_80)
-                                       goto change_bw;\r
-                               wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);\r
-                               printf("%s: channel %d\n", __FUNCTION__, _chan);\r
+                                       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));\r
-                       } else\r
-                               printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec);\r
+                               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__));\r
+                       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));\r
+               ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec));
                err = BCME_ERROR;
-       }\r
-\r
-       return err;\r
-}\r
-\r
-int\r
-wl_ext_channel(struct net_device *dev, char* command, int total_len)\r
-{\r
-       int ret;\r
-       int channel=0;\r
-       channel_info_t ci;\r
-       int bytes_written = 0;\r
-\r
-       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
-       sscanf(command, "%*s %d", &channel);\r
-\r
-       if (channel > 0) {\r
-               ret = wl_ext_set_chanspec(dev, channel);\r
-       } else {\r
-               if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {\r
-                       ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel));\r
-                       ANDROID_TRACE(("target_channel %d\n", ci.target_channel));\r
-                       ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel));\r
-                       bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel);\r
-                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-                       ret = bytes_written;\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-wl_ext_channels(struct net_device *dev, char* command, int total_len)\r
-{\r
-       int ret, i;\r
-       int bytes_written = -1;\r
-       u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
-       wl_uint32_list_t *list;\r
-\r
-       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
-       memset(valid_chan_list, 0, sizeof(valid_chan_list));\r
-       list = (wl_uint32_list_t *)(void *) valid_chan_list;\r
-       list->count = htod32(WL_NUMCHANNELS);\r
-       ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0);\r
-       if (ret<0) {\r
-               ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret));\r
-       } else {\r
-               bytes_written = snprintf(command, total_len, "channels");\r
-               for (i = 0; i < dtoh32(list->count); i++) {\r
-                       bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i]));\r
-                       printf("%d ", dtoh32(list->element[i]));\r
-               }\r
-               printf("\n");\r
-               ret = bytes_written;\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len)\r
-{\r
-       int ret = 0;\r
-       int roam_trigger[2] = {0, 0};\r
-       int trigger[2]= {0, 0};\r
-       int bytes_written=-1;\r
-\r
-       sscanf(command, "%*s %10d", &roam_trigger[0]);\r
-\r
-       if (roam_trigger[0]) {\r
-               roam_trigger[1] = WLC_BAND_ALL;\r
-               ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1);\r
-               if (ret)\r
-                       ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));\r
-       } else {\r
-               roam_trigger[1] = WLC_BAND_2G;\r
-               ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);\r
-               if (!ret)\r
-                       trigger[0] = roam_trigger[0];\r
-               else\r
-                       ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));\r
-\r
-               roam_trigger[1] = WLC_BAND_5G;\r
-               ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0);\r
-               if (!ret)\r
-                       trigger[1] = roam_trigger[0];\r
-               else\r
-                       ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret));\r
-\r
-               ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1]));\r
-               bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]);\r
-               ret = bytes_written;\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-static int\r
-wl_ext_pattern_atoh(char *src, char *dst)\r
-{\r
-       int i;\r
-       if (strncmp(src, "0x", 2) != 0 &&\r
-           strncmp(src, "0X", 2) != 0) {\r
-               ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n"));\r
-               return -1;\r
-       }\r
-       src = src + 2; /* Skip past 0x */\r
-       if (strlen(src) % 2 != 0) {\r
-               DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));\r
-               return -1;\r
-       }\r
-       for (i = 0; *src != '\0'; i++) {\r
-               char num[3];\r
-               bcm_strncpy_s(num, sizeof(num), src, 2);\r
-               num[2] = '\0';\r
-               dst[i] = (uint8)strtoul(num, NULL, 16);\r
-               src += 2;\r
-       }\r
-       return i;\r
-}\r
-\r
-int\r
-wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)\r
-{\r
-       wl_mkeep_alive_pkt_t *mkeep_alive_pktp;\r
-       int ret = -1, i;\r
-       int     id, period=-1, len_bytes=0, buf_len=0;\r
-       char data[200]="\0";\r
-       char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0";\r
-       int bytes_written = -1;\r
-\r
-       ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command));\r
-       sscanf(command, "%*s %d %d %s", &id, &period, data);\r
-       ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data));\r
-\r
-       if (period >= 0) {\r
-               mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf;\r
-               mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION);\r
-               mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);\r
-               mkeep_alive_pktp->keep_alive_id = id;\r
-               buf_len += WL_MKEEP_ALIVE_FIXED_LEN;\r
-               mkeep_alive_pktp->period_msec = period;\r
-               if (strlen(data)) {\r
-                       len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data);\r
-                       buf_len += len_bytes;\r
-               }\r
-               mkeep_alive_pktp->len_bytes = htod16(len_bytes);\r
-\r
-               ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len,\r
-                       iovar_buf, sizeof(iovar_buf), NULL);\r
-       } else {\r
-               if (id < 0)\r
-                       id = 0;\r
-               ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL);\r
-               if (ret) {\r
-                       goto exit;\r
-               } else {\r
-                       mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;\r
-                       printf("Id            :%d\n"\r
-                                  "Period (msec) :%d\n"\r
-                                  "Length        :%d\n"\r
-                                  "Packet        :0x",\r
-                                  mkeep_alive_pktp->keep_alive_id,\r
-                                  dtoh32(mkeep_alive_pktp->period_msec),\r
-                                  dtoh16(mkeep_alive_pktp->len_bytes));\r
-                       for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {\r
-                               printf("%02x", mkeep_alive_pktp->data[i]);\r
-                       }\r
-                       printf("\n");\r
-               }\r
-               bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec));\r
-               bytes_written += snprintf(command+bytes_written, total_len, "0x");\r
-               for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {\r
-                       bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]);\r
-               }\r
-               ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-               ret = bytes_written;\r
-       }\r
-       \r
-exit:\r
-       return ret;\r
-}\r
-\r
-int\r
-wl_ext_pm(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int pm=-1, ret = -1;\r
-       char *pm_local;\r
-       int bytes_written=-1;\r
-\r
-       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
-       sscanf(command, "%*s %d", &pm);\r
-\r
-       if (pm >= 0) {\r
-               ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE);\r
-               if (ret)\r
-                       ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret));\r
-       } else {\r
-               ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE);\r
-               if (!ret) {\r
-                       ANDROID_TRACE(("%s: PM = %d\n", __func__, pm));\r
-                       if (pm == PM_OFF)\r
-                               pm_local = "PM_OFF";\r
-                       else if(pm == PM_MAX)\r
-                               pm_local = "PM_MAX";\r
-                       else if(pm == PM_FAST)\r
-                               pm_local = "PM_FAST";\r
-                       else {\r
-                               pm = 0;\r
-                               pm_local = "Invalid";\r
-                       }\r
-                       bytes_written = snprintf(command, total_len, "PM %s", pm_local);\r
-                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-                       ret = bytes_written;\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-static int\r
-wl_ext_monitor(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int val, ret = -1;\r
-       int bytes_written=-1;\r
-\r
-       sscanf(command, "%*s %d", &val);\r
-\r
-       if (val >=0) {\r
-               ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1);\r
-               if (ret)\r
-                       ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret));\r
-       } else {\r
-               ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE);\r
-               if (!ret) {\r
-                       ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val));\r
-                       bytes_written = snprintf(command, total_len, "monitor %d", val);\r
-                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-                       ret = bytes_written;\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-#ifdef WL_EXT_IAPSTA\r
-struct wl_apsta_params g_apsta_params;\r
-static int\r
-wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)\r
-{\r
-       char hex[] = "XX";\r
-       unsigned char *data = wsec_key->data;\r
-       char *keystr = key;\r
-\r
-       switch (strlen(keystr)) {\r
-       case 5:\r
-       case 13:\r
-       case 16:\r
-               wsec_key->len = strlen(keystr);\r
-               memcpy(data, keystr, wsec_key->len + 1);\r
-               break;\r
-       case 12:\r
-       case 28:\r
-       case 34:\r
-       case 66:\r
-               /* strip leading 0x */\r
-               if (!strnicmp(keystr, "0x", 2))\r
-                       keystr += 2;\r
-               else\r
-                       return -1;\r
-               /* fall through */\r
-       case 10:\r
-       case 26:\r
-       case 32:\r
-       case 64:\r
-               wsec_key->len = strlen(keystr) / 2;\r
-               while (*keystr) {\r
-                       strncpy(hex, keystr, 2);\r
-                       *data++ = (char) strtoul(hex, NULL, 16);\r
-                       keystr += 2;\r
-               }\r
-               break;\r
-       default:\r
-               return -1;\r
-       }\r
-\r
-       switch (wsec_key->len) {\r
-       case 5:\r
-               wsec_key->algo = CRYPTO_ALGO_WEP1;\r
-               break;\r
-       case 13:\r
-               wsec_key->algo = CRYPTO_ALGO_WEP128;\r
-               break;\r
-       case 16:\r
-               /* default to AES-CCM */\r
-               wsec_key->algo = CRYPTO_ALGO_AES_CCM;\r
-               break;\r
-       case 32:\r
-               wsec_key->algo = CRYPTO_ALGO_TKIP;\r
-               break;\r
-       default:\r
-               return -1;\r
-       }\r
-\r
-       /* Set as primary wsec_key by default */\r
-       wsec_key->flags |= WL_PRIMARY_KEY;\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_set_bgnmode(struct wl_if_info *cur_if)\r
-{\r
-       struct net_device *dev = cur_if->dev;\r
-       bgnmode_t bgnmode = cur_if->bgnmode;\r
-       int val;\r
-\r
-       if (bgnmode == 0)\r
-               return 0;\r
-\r
-       wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-       if (bgnmode == IEEE80211B) {\r
-               wl_ext_iovar_setint(dev, "nmode", 0);\r
-               val = 0;\r
-               wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
-               ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__));\r
-       } else if (bgnmode == IEEE80211G) {\r
-               wl_ext_iovar_setint(dev, "nmode", 0);\r
-               val = 2;\r
-               wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
-               ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__));\r
-       } else if (bgnmode == IEEE80211BG) {\r
-               wl_ext_iovar_setint(dev, "nmode", 0);\r
-               val = 1;\r
-               wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
-               ANDROID_TRACE(("%s: Network mode: : B/G mixed\n", __FUNCTION__));\r
-       } else if (bgnmode == IEEE80211BGN) {\r
-               wl_ext_iovar_setint(dev, "nmode", 0);\r
-               wl_ext_iovar_setint(dev, "nmode", 1);\r
-               wl_ext_iovar_setint(dev, "vhtmode", 0);\r
-               val = 1;\r
-               wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
-               ANDROID_TRACE(("%s: Network mode: : B/G/N mixed\n", __FUNCTION__));\r
-       } else if (bgnmode == IEEE80211BGNAC) {\r
-               wl_ext_iovar_setint(dev, "nmode", 0);\r
-               wl_ext_iovar_setint(dev, "nmode", 1);\r
-               wl_ext_iovar_setint(dev, "vhtmode", 1);\r
-               val = 1;\r
-               wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1);\r
-               ANDROID_TRACE(("%s: Network mode: : B/G/N/AC mixed\n", __FUNCTION__));\r
-       }\r
-       wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)\r
-{\r
-       struct net_device *dev = cur_if->dev;\r
-       authmode_t amode = cur_if->amode;\r
-       int auth=0, wpa_auth=0;\r
-\r
-       if (amode == AUTH_OPEN) {\r
-               auth = 0;\r
-               wpa_auth = 0;\r
-               ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__));\r
-       } else if (amode == AUTH_SHARED) {\r
-               auth = 1;\r
-               wpa_auth = 0;\r
-               ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__));\r
-       } else if (amode == AUTH_WPAPSK) {\r
-               auth = 0;\r
-               wpa_auth = 4;\r
-               ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__));\r
-       } else if (amode == AUTH_WPA2PSK) {\r
-               auth = 0;\r
-               wpa_auth = 128;\r
-               ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__));\r
-       } else if (amode == AUTH_WPAWPA2PSK) {\r
-               auth = 0;\r
-               wpa_auth = 132;\r
-               ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__));\r
-       }\r
-       wl_ext_iovar_setint(dev, "auth", auth);\r
-\r
-       wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params)\r
-{\r
-       struct net_device *dev = cur_if->dev;\r
-       int wsec=0;\r
-       struct wl_wsec_key wsec_key;\r
-       wsec_pmk_t psk;\r
-       encmode_t emode = cur_if->emode;\r
-       char *key = cur_if->key;\r
-\r
-       memset(&wsec_key, 0, sizeof(wsec_key));\r
-       memset(&psk, 0, sizeof(psk));\r
-       if (emode == ENC_NONE) {\r
-               wsec = 0;\r
-               ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__));\r
-       } else if (emode == ENC_WEP) {\r
-               wsec = 1;\r
-               wl_ext_parse_wep(key, &wsec_key);\r
-               ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__));\r
-               ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, wsec_key.data));\r
-       } else if (emode == ENC_TKIP) {\r
-               wsec = 2;\r
-               psk.key_len = strlen(key);\r
-               psk.flags = WSEC_PASSPHRASE;\r
-               memcpy(psk.key, key, strlen(key));\r
-               ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__));\r
-               ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));\r
-       } else if (emode == ENC_AES) {\r
-               wsec = 4;\r
-               psk.key_len = strlen(key);\r
-               psk.flags = WSEC_PASSPHRASE;\r
-               memcpy(psk.key, key, strlen(key));\r
-               ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__));\r
-               ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));\r
-       } else if (emode == ENC_TKIPAES) {\r
-               wsec = 6;\r
-               psk.key_len = strlen(key);\r
-               psk.flags = WSEC_PASSPHRASE;\r
-               memcpy(psk.key, key, strlen(key));\r
-               ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__));\r
-               ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key));\r
-       }\r
-\r
-       wl_ext_iovar_setint(dev, "wsec", wsec);\r
-\r
-       if (wsec == 1) {\r
-               wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1);\r
-       } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) {\r
-               if (dev) {\r
-                       if (cur_if->ifmode == ISTA_MODE)\r
-                               wl_ext_iovar_setint(dev, "sup_wpa", 1);\r
-                       wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1);\r
-               } else {\r
-                       ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__));\r
-               }\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len)\r
-{\r
-       s32 val = 0;\r
-       char *pch, *pick_tmp, *param;\r
-       wlc_ssid_t ssid = { 0, {0} };\r
-       s8 iovar_buf[WLC_IOCTL_SMLEN];\r
-       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-       wl_interface_create_t iface;\r
-       struct dhd_pub *dhd;\r
-       wl_p2p_if_t ifreq;\r
-\r
-       if (apsta_params->init) {\r
-               ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));\r
-               return -1;\r
-       }\r
-\r
-       dhd = dhd_get_pub(dev);\r
-       memset(apsta_params, 0, sizeof(struct wl_apsta_params));\r
-\r
-       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
-\r
-       pick_tmp = command;\r
-       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init\r
-       param = bcmstrtok(&pick_tmp, " ", 0);\r
-       while (param != NULL) {\r
-               if (!strcmp(param, "mode")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch) {\r
-                               if (!strcmp(pch, "sta")) {\r
-                                       apsta_params->apstamode = ISTAONLY_MODE;\r
-                               } else if (!strcmp(pch, "ap")) {\r
-                                       apsta_params->apstamode = IAPONLY_MODE;\r
-                               } else if (!strcmp(pch, "apsta")) {\r
-                                       apsta_params->apstamode = IAPSTA_MODE;\r
-                               } else if (!strcmp(pch, "dualap")) {\r
-                                       apsta_params->apstamode = IDUALAP_MODE;\r
-                               } else if (!strcmp(pch, "gosta")) {\r
-                                       if (!FW_SUPPORTED(dhd, p2p)) {\r
-                                               return -1;\r
-                                       }\r
-                                       apsta_params->apstamode = IGOSTA_MODE;\r
-                               } else if (!strcmp(pch, "gcsta")) {\r
-                                       if (!FW_SUPPORTED(dhd, p2p)) {\r
-                                               return -1;\r
-                                       }\r
-                                       apsta_params->apstamode = IGCSTA_MODE;\r
-                               } else {\r
-                                       ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));\r
-                                       return -1;\r
-                               }\r
-                       }\r
-               } else if (!strcmp(param, "vifname")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               strcpy(apsta_params->vif.ifname, pch);\r
-                       else {\r
-                               ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__));\r
-                               return -1;\r
-                       }\r
-               }\r
-               param = bcmstrtok(&pick_tmp, " ", 0);\r
-       }\r
-\r
-       if (apsta_params->apstamode == 0) {\r
-               ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));\r
-               return -1;\r
-       }\r
-\r
-       apsta_params->pif.dev = dev;\r
-       apsta_params->pif.bssidx = 0;\r
-       strcpy(apsta_params->pif.ifname, dev->name);\r
-       strcpy(apsta_params->pif.ssid, "tttp");\r
-       apsta_params->pif.maxassoc = -1;\r
-       apsta_params->pif.channel = 1;\r
-\r
-       if (!strlen(apsta_params->vif.ifname))\r
-               strcpy(apsta_params->vif.ifname, "wlan1");\r
-       strcpy(apsta_params->vif.ssid, "tttv");\r
-       apsta_params->vif.maxassoc = -1;\r
-       apsta_params->vif.channel = 1;\r
-\r
-       if (apsta_params->apstamode == ISTAONLY_MODE) {\r
-               apsta_params->pif.ifmode = ISTA_MODE;\r
-               apsta_params->pif.ifstate = IF_STATE_INIT;\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls\r
-               // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off\r
-               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-       } else if (apsta_params->apstamode == IAPONLY_MODE) {\r
-               apsta_params->pif.ifmode = IAP_MODE;\r
-               apsta_params->pif.ifstate = IF_STATE_INIT;\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
+       }
+
+       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 */\r
-               dhd_arp_offload_set(dhd, 0);\r
-               dhd_arp_offload_enable(dhd, FALSE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
-               wl_ext_iovar_setint(dev, "mpc", 0);\r
-               wl_ext_iovar_setint(dev, "apsta", 0);\r
-               val = 1;\r
-               wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);\r
-       } else if (apsta_params->apstamode == IAPSTA_MODE) {\r
-               apsta_params->pif.ifmode = ISTA_MODE;\r
-               apsta_params->pif.ifstate = IF_STATE_INIT;\r
-               apsta_params->vif.ifmode = IAP_MODE;\r
-               apsta_params->vif.ifstate = IF_STATE_INIT;\r
-               wl_ext_iovar_setint(dev, "mpc", 0);\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_iovar_setint(dev, "apsta", 1);\r
-               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-               if (FW_SUPPORTED(dhd, rsdb)) {\r
-                       bzero(&iface, sizeof(wl_interface_create_t));\r
-                       iface.ver = WL_INTERFACE_CREATE_VER;\r
-                       iface.flags = WL_INTERFACE_CREATE_AP;\r
-                       wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,\r
-                               WLC_IOCTL_SMLEN, 1, NULL);\r
-               } else {\r
-                       wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,\r
-                               WLC_IOCTL_SMLEN, 1, NULL);\r
-               }\r
-       }\r
-       else if (apsta_params->apstamode == IDUALAP_MODE) {\r
-               apsta_params->pif.ifmode = IAP_MODE;\r
-               apsta_params->pif.ifstate = IF_STATE_INIT;\r
-               apsta_params->vif.ifmode = IAP_MODE;\r
-               apsta_params->vif.ifstate = IF_STATE_INIT;\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_iovar_setint(dev, "apsta", 0);\r
-               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-               val = 1;\r
-               wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);\r
-               /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */\r
+               /* 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 */\r
-               dhd_arp_offload_set(dhd, 0);\r
-               dhd_arp_offload_enable(dhd, FALSE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
-               bzero(&iface, sizeof(wl_interface_create_t));\r
-               iface.ver = WL_INTERFACE_CREATE_VER;\r
-               iface.flags = WL_INTERFACE_CREATE_AP;\r
-               wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,\r
-                       WLC_IOCTL_SMLEN, 1, NULL);\r
-       }\r
-       else if (apsta_params->apstamode == IGOSTA_MODE) {\r
-               apsta_params->pif.ifmode = ISTA_MODE;\r
-               apsta_params->pif.ifstate = IF_STATE_INIT;\r
-               apsta_params->vif.ifmode = IAP_MODE;\r
-               apsta_params->vif.ifstate = IF_STATE_INIT;\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_iovar_setint(dev, "apsta", 1);\r
-               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-               bzero(&ifreq, sizeof(wl_p2p_if_t));\r
-               ifreq.type = htod32(WL_P2P_IF_GO);\r
-               wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),\r
-                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-       }\r
-       else if (apsta_params->apstamode == IGCSTA_MODE) {\r
-               apsta_params->pif.ifmode = ISTA_MODE;\r
-               apsta_params->pif.ifstate = IF_STATE_INIT;\r
-               apsta_params->vif.ifmode = ISTA_MODE;\r
-               apsta_params->vif.ifstate = IF_STATE_INIT;\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_iovar_setint(dev, "apsta", 1);\r
-               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-               bzero(&ifreq, sizeof(wl_p2p_if_t));\r
-               ifreq.type = htod32(WL_P2P_IF_CLIENT);\r
-               wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq),\r
-                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-       }\r
-\r
-       wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);\r
-       printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);\r
-\r
-       apsta_params->init = TRUE;\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int i;\r
-       char *pch, *pick_tmp, *param;\r
-       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-       char ifname[IFNAMSIZ+1];\r
-       struct wl_if_info *cur_if = &apsta_params->pif;\r
-\r
-       if (!apsta_params->init) {\r
-               ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
-               return -1;\r
-       }\r
-\r
-       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
-\r
-       pick_tmp = command;\r
-       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config\r
-       param = bcmstrtok(&pick_tmp, " ", 0);\r
-\r
-       if (param != NULL) {\r
-               if (strcmp(param, "ifname")) {\r
-                       ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__));\r
-                       return -1;\r
-               }\r
-       }\r
-\r
-       while (param != NULL) {\r
-               if (!strcmp(param, "ifname")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               strcpy(ifname, pch);\r
-                       else {\r
-                               ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));\r
-                               return -1;\r
-                       }\r
-                       if (!strcmp(apsta_params->pif.dev->name, ifname)) {\r
-                               cur_if = &apsta_params->pif;\r
-                       } else if (!strcmp(apsta_params->vif.ifname, ifname)) {\r
-                               cur_if = &apsta_params->vif;\r
-                       } else {\r
-                               ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__,\r
-                                       ifname, apsta_params->apstamode));\r
-                               return -1;\r
-                       }\r
-               } else if (!strcmp(param, "ssid")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               strcpy(cur_if->ssid, pch);\r
-               } else if (!strcmp(param, "bssid")) {\r
-                       pch = bcmstrtok(&pick_tmp, ": ", 0);\r
-                       for (i=0; i<6 && pch; i++) {\r
-                               ((u8 *)&cur_if->bssid)[i] = (int)simple_strtol(pch, NULL, 16);\r
-                               pch = bcmstrtok(&pick_tmp, ": ", 0);\r
-                       }\r
-               } else if (!strcmp(param, "bgnmode")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch) {\r
-                               if (!strcmp(pch, "b"))\r
-                                       cur_if->bgnmode = IEEE80211B;\r
-                               else if (!strcmp(pch, "g"))\r
-                                       cur_if->bgnmode = IEEE80211G;\r
-                               else if (!strcmp(pch, "bg"))\r
-                                       cur_if->bgnmode = IEEE80211BG;\r
-                               else if (!strcmp(pch, "bgn"))\r
-                                       cur_if->bgnmode = IEEE80211BGN;\r
-                               else if (!strcmp(pch, "bgnac"))\r
-                                       cur_if->bgnmode = IEEE80211BGNAC;\r
-                               else {\r
-                                       ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__));\r
-                                       return -1;\r
-                               }\r
-                       }\r
-               } else if (!strcmp(param, "hidden")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch) {\r
-                               if (!strcmp(pch, "n"))\r
-                                       cur_if->hidden = 0;\r
-                               else if (!strcmp(pch, "y"))\r
-                                       cur_if->hidden = 1;\r
-                               else {\r
-                                       ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__));\r
-                                       return -1;\r
-                               }\r
-                       }\r
-               } else if (!strcmp(param, "maxassoc")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               cur_if->maxassoc = (int)simple_strtol(pch, NULL, 10);\r
-               } else if (!strcmp(param, "chan")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               cur_if->channel = (int)simple_strtol(pch, NULL, 10);\r
-               } else if (!strcmp(param, "amode")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch) {\r
-                               if (!strcmp(pch, "open"))\r
-                                       cur_if->amode = AUTH_OPEN;\r
-                               else if (!strcmp(pch, "shared"))\r
-                                       cur_if->amode = AUTH_SHARED;\r
-                               else if (!strcmp(pch, "wpapsk"))\r
-                                       cur_if->amode = AUTH_WPAPSK;\r
-                               else if (!strcmp(pch, "wpa2psk"))\r
-                                       cur_if->amode = AUTH_WPA2PSK;\r
-                               else if (!strcmp(pch, "wpawpa2psk")) \r
-                                       cur_if->amode = AUTH_WPAWPA2PSK;\r
-                               else {\r
-                                       ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n",\r
-                                               __FUNCTION__));\r
-                                       return -1;\r
-                               }\r
-                       }\r
-               } else if (!strcmp(param, "emode")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch) {\r
-                               if (!strcmp(pch, "none"))\r
-                                       cur_if->emode = ENC_NONE;\r
-                               else if (!strcmp(pch, "wep"))\r
-                                       cur_if->emode = ENC_WEP;\r
-                               else if (!strcmp(pch, "tkip"))\r
-                                       cur_if->emode = ENC_TKIP;\r
-                               else if (!strcmp(pch, "aes"))\r
-                                       cur_if->emode = ENC_AES;\r
-                               else if (!strcmp(pch, "tkipaes")) \r
-                                       cur_if->emode = ENC_TKIPAES;\r
-                               else {\r
-                                       ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n",\r
-                                               __FUNCTION__));\r
-                                       return -1;\r
-                               }\r
-                       }\r
-               } else if (!strcmp(param, "key")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch) {\r
-                               strcpy(cur_if->key, pch);\r
-                       }\r
-               }\r
-               param = bcmstrtok(&pick_tmp, " ", 0);\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)\r
-{\r
-       char *pch, *pick_tmp, *param;\r
-       s8 iovar_buf[WLC_IOCTL_SMLEN];\r
-       wlc_ssid_t ssid = { 0, {0} };\r
-       scb_val_t scbval;\r
-       struct {\r
-               s32 tmp;\r
+               /* 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;\r
-       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-       apstamode_t apstamode = apsta_params->apstamode;\r
-       char ifname[IFNAMSIZ+1];\r
-       struct wl_if_info *cur_if;\r
-       struct dhd_pub *dhd;\r
-\r
-       if (!apsta_params->init) {\r
-               ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
-               return -1;\r
-       }\r
-\r
-       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
-       dhd = dhd_get_pub(dev);\r
-\r
-       pick_tmp = command;\r
-       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable\r
-       param = bcmstrtok(&pick_tmp, " ", 0);\r
-       while (param != NULL) {\r
-               if (!strcmp(param, "ifname")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               strcpy(ifname, pch);\r
-                       else {\r
-                               ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));\r
-                               return -1;\r
-                       }\r
-               }\r
-               param = bcmstrtok(&pick_tmp, " ", 0);\r
-       }\r
-       if (!strcmp(apsta_params->pif.dev->name, ifname)) {\r
-               cur_if = &apsta_params->pif;\r
-       } else if (!strcmp(apsta_params->vif.ifname, ifname)) {\r
-               cur_if = &apsta_params->vif;\r
-       } else {\r
-               ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));\r
-               return -1;\r
-       }\r
-       if (!cur_if->dev) {\r
-               ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));\r
-               return -1;\r
-       }\r
-\r
-       if (cur_if->ifmode == ISTA_MODE) {\r
-               wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);\r
-       } else if (cur_if->ifmode == IAP_MODE) {\r
-               // deauthenticate all STA first\r
-               memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);\r
-               wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);\r
-       }\r
-\r
-       if (apstamode == IAPONLY_MODE) {\r
-               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
-               wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid\r
-               wl_ext_iovar_setint(dev, "mpc", 1);\r
-       } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) &&\r
-                       cur_if->ifmode == IAP_MODE) {\r
-               // vif is AP mode\r
-               bss_setbuf.tmp = 0xffffffff;\r
-               bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down\r
-               bss_setbuf.val = htod32(0);\r
-               wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
-                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-               wl_ext_iovar_setint(dev, "mpc", 1);\r
-#ifdef ARP_OFFLOAD_SUPPORT\r
-               /* IF SoftAP is disabled, enable arpoe back for STA mode. */\r
-               dhd_arp_offload_set(dhd, dhd_arp_mode);\r
-               dhd_arp_offload_enable(dhd, TRUE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
-       } else if (apstamode == IDUALAP_MODE) {\r
-               bss_setbuf.tmp = 0xffffffff;\r
-               bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down\r
-               bss_setbuf.val = htod32(0);\r
-               wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
-                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-       }\r
-\r
-#ifdef PROP_TXSTATUS_VSDB\r
-#if defined(BCMSDIO)\r
-       if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) {\r
-               bool enabled;\r
-               dhd_wlfc_get_enable(dhd, &enabled);\r
-               if (enabled) {\r
-                       dhd_wlfc_deinit(dhd);\r
-               }\r
-       }\r
-#endif \r
-#endif /* PROP_TXSTATUS_VSDB */\r
-\r
-       cur_if->ifstate = IF_STATE_DISALBE;\r
-       printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname);\r
-\r
-       return 0;\r
-}\r
-\r
-static int\r
-wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int ret = 0;\r
-       s32 val = 0;\r
-       char *pch, *pick_tmp, *param;\r
-       s8 iovar_buf[WLC_IOCTL_SMLEN];\r
-       wlc_ssid_t ssid = { 0, {0} };\r
-       struct {\r
+       } bss_setbuf;
+       struct wl_apsta_params *apsta_params = &g_apsta_params;
+       apstamode_t apstamode = apsta_params->apstamode;
+       char ifname[IFNAMSIZ+1];
+       struct wl_if_info *cur_if;
+       struct dhd_pub *dhd;
+
+       if (!apsta_params->init) {
+               ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+               return -1;
+       }
+
+       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+       dhd = dhd_get_pub(dev);
+
+       pick_tmp = command;
+       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable
+       param = bcmstrtok(&pick_tmp, " ", 0);
+       while (param != NULL) {
+               if (!strcmp(param, "ifname")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch)
+                               strcpy(ifname, pch);
+                       else {
+                               ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+                               return -1;
+                       }
+               }
+               param = bcmstrtok(&pick_tmp, " ", 0);
+       }
+       if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+               cur_if = &apsta_params->pif;
+       } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+               cur_if = &apsta_params->vif;
+       } else {
+               ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));
+               return -1;
+       }
+       if (!cur_if->dev) {
+               ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));
+               return -1;
+       }
+
+       if (cur_if->ifmode == ISTA_MODE) {
+               wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
+       } else if (cur_if->ifmode == IAP_MODE) {
+               // deauthenticate all STA first
+               memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);
+               wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
+       }
+
+       if (apstamode == IAPONLY_MODE) {
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+               wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid
+               wl_ext_iovar_setint(dev, "mpc", 1);
+       } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) &&
+                       cur_if->ifmode == IAP_MODE) {
+               // vif is AP mode
+               bss_setbuf.tmp = 0xffffffff;
+               bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
+               bss_setbuf.val = htod32(0);
+               wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+                       iovar_buf, WLC_IOCTL_SMLEN, NULL);
+               wl_ext_iovar_setint(dev, "mpc", 1);
+#ifdef ARP_OFFLOAD_SUPPORT
+               /* IF SoftAP is disabled, enable arpoe back for STA mode. */
+               dhd_arp_offload_set(dhd, dhd_arp_mode);
+               dhd_arp_offload_enable(dhd, TRUE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+       } else if (apstamode == IDUALAP_MODE) {
+               bss_setbuf.tmp = 0xffffffff;
+               bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down
+               bss_setbuf.val = htod32(0);
+               wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),
+                       iovar_buf, WLC_IOCTL_SMLEN, NULL);
+       }
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(BCMSDIO)
+       if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) {
+               bool enabled;
+               dhd_wlfc_get_enable(dhd, &enabled);
+               if (enabled) {
+                       dhd_wlfc_deinit(dhd);
+               }
+       }
+#endif 
+#endif /* PROP_TXSTATUS_VSDB */
+
+       cur_if->ifstate = IF_STATE_DISALBE;
+       printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname);
+
+       return 0;
+}
+
+static int
+wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len)
+{
+       int ret = 0;
+       s32 val = 0;
+       char *pch, *pick_tmp, *param;
+       s8 iovar_buf[WLC_IOCTL_SMLEN];
+       wlc_ssid_t ssid = { 0, {0} };
+       struct {
                s32 cfg;
                s32 val;
-       } bss_setbuf;\r
-       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-       apstamode_t apstamode = apsta_params->apstamode;\r
-       char ifname[IFNAMSIZ+1];\r
-       struct wl_if_info *cur_if;\r
-       char cmd[128] = "iapsta_stop ifname ";\r
-       struct dhd_pub *dhd;\r
-\r
-       if (!apsta_params->init) {\r
-               ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));\r
-               return -1;\r
-       }\r
-\r
-       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));\r
-       dhd = dhd_get_pub(dev);\r
-\r
-       pick_tmp = command;\r
-       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable\r
-       param = bcmstrtok(&pick_tmp, " ", 0);\r
-       while (param != NULL) {\r
-               if (!strcmp(param, "ifname")) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       if (pch)\r
-                               strcpy(ifname, pch);\r
-                       else {\r
-                               ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));\r
-                               return -1;\r
-                       }\r
-               }\r
-               param = bcmstrtok(&pick_tmp, " ", 0);\r
-       }\r
-       if (!strcmp(apsta_params->pif.dev->name, ifname)) {\r
-               cur_if = &apsta_params->pif;\r
-       } else if (!strcmp(apsta_params->vif.ifname, ifname)) {\r
-               cur_if = &apsta_params->vif;\r
-       } else {\r
-               ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname));\r
-               return -1;\r
-       }\r
-       if (!cur_if->dev) {\r
-               ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname));\r
-               return -1;\r
-       }\r
-       ssid.SSID_len = strlen(cur_if->ssid);\r
-       memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len);\r
-       ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx));\r
-\r
-       snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname);\r
-       ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd));\r
-       if (ret)\r
-               goto exit;\r
-\r
-       if (cur_if == &apsta_params->vif) {\r
-               wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr,\r
-                       ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-       }\r
-\r
-       // set ssid for AP\r
-       if (cur_if->ifmode == IAP_MODE) {\r
-               wl_ext_iovar_setint(dev, "mpc", 0);\r
-               if (apstamode == IAPONLY_MODE) {\r
-                       wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-               } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) {\r
-                       wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid),\r
-                               iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL);\r
-               }\r
-       }\r
-\r
-       if (cur_if->ifmode == IAP_MODE) {\r
-               wl_ext_set_bgnmode(cur_if);\r
-               wl_ext_set_chanspec(cur_if->dev, cur_if->channel);\r
-       }\r
-       wl_ext_set_amode(cur_if, apsta_params);\r
-       wl_ext_set_emode(cur_if, apsta_params);\r
-\r
-       if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {\r
-               if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) {\r
-                       printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid);\r
-                       wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1);\r
-               }\r
-               val = 1;\r
-               wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1);\r
-       }\r
-       if (cur_if->ifmode == IAP_MODE) {\r
-               if (cur_if->maxassoc >= 0)\r
-                       wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc);\r
-               printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON");\r
-               // terence: fix me, hidden does not work in dualAP mode\r
-               wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1);\r
-       }\r
-\r
-       if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) {\r
-               wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
-       } else if (apstamode == IAPONLY_MODE) {\r
-               wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
-               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-       } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) {\r
-               if (cur_if->ifmode == ISTA_MODE) {\r
-                       wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
-               } else {\r
-                       if (FW_SUPPORTED(dhd, rsdb)) {\r
-                               wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
-                       } else {\r
-                               bss_setbuf.cfg = htod32(cur_if->bssidx);\r
-                               bss_setbuf.val = htod32(1);\r
-                               wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf),\r
-                                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
-                       }\r
+       } 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 */\r
-                       dhd_arp_offload_set(dhd, 0);\r
-                       dhd_arp_offload_enable(dhd, FALSE);\r
-#endif /* ARP_OFFLOAD_SUPPORT */\r
-               }\r
-       }\r
-       else if (apstamode == IDUALAP_MODE) {\r
-               wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
-       }\r
-\r
-#ifdef PROP_TXSTATUS_VSDB\r
-#if defined(BCMSDIO)\r
-       if (cur_if==&apsta_params->vif && !disable_proptx) {\r
-               bool enabled;\r
-               dhd_wlfc_get_enable(dhd, &enabled);\r
-               if (!enabled) {\r
-                       dhd_wlfc_init(dhd);\r
-                       wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
-               }\r
-       }\r
-#endif 
-#endif /* PROP_TXSTATUS_VSDB */\r
-\r
-       printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid);\r
-\r
-       cur_if->ifstate = IF_STATE_ENABLE;\r
-\r
-exit:\r
-       return ret;\r
-}\r
-
-void\r
-wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel)\r
-{\r
-       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-       struct wl_if_info *cur_if = &apsta_params->vif;\r
-       scb_val_t scbval;\r
-       int ret;\r
-       channel_info_t ci;\r
-       struct dhd_pub *dhd;\r
-\r
-       if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) {\r
-               dhd = dhd_get_pub(dev);\r
-               if (!FW_SUPPORTED(dhd, vsdb)) {\r
-                       if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {\r
-                               if (channel != ci.target_channel) {\r
-                                       printf("%s: deauthenticate all STA on vif\n", __FUNCTION__);\r
-                                       memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);\r
-                                       wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-
-int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx)\r
-{\r
-       g_apsta_params.vif.dev = net;\r
-       g_apsta_params.vif.bssidx = bssidx;\r
-       if (strlen(g_apsta_params.vif.ifname)) {\r
-               memset(net->name, 0, sizeof(IFNAMSIZ));\r
-               strcpy(net->name, g_apsta_params.vif.ifname);\r
-               net->name[IFNAMSIZ - 1] = '\0';\r
-       }\r
-       if (g_apsta_params.pif.dev) {\r
-               memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN);\r
-               net->dev_addr[0] |= 0x02;\r
-       }\r
-\r
-       return 0;\r
-}\r
-
-int wl_android_ext_dettach_netdev(void)\r
-{\r
-       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
-\r
-       ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));\r
-       memset(apsta_params, 0, sizeof(struct wl_apsta_params));\r
-\r
-       return 0;\r
-}\r
-#endif\r
-\r
-#ifdef IDHCP\r
-int wl_ext_ip_dump(int ip, char *buf)\r
-{\r
-       unsigned char bytes[4];\r
-       int bytes_written=-1;\r
-\r
-       bytes[0] = ip & 0xFF;\r
-       bytes[1] = (ip >> 8) & 0xFF;\r
-       bytes[2] = (ip >> 16) & 0xFF;\r
-       bytes[3] = (ip >> 24) & 0xFF;   \r
-       bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);\r
-\r
-       return bytes_written;\r
-}\r
-\r
-/*\r
-terence 20170215:\r
-dhd_priv dhcpc_dump ifname [wlan0|wlan1]\r
-dhd_priv dhcpc_enable [0|1]\r
-*/\r
-int\r
-wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int enable = -1, ret = -1;\r
-       int bytes_written = -1;\r
-\r
-       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
-       sscanf(command, "%*s %d", &enable);\r
-\r
-       if (enable >= 0)\r
-               ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable);\r
-       else {\r
-               ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable);\r
-               if (!ret) {\r
-                       bytes_written = snprintf(command, total_len, "%d", enable);\r
-                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-                       ret = bytes_written;\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len)\r
-{\r
-\r
-       int ret = 0;\r
-       int bytes_written = 0;\r
-       uint32 ip_addr;\r
-       char buf[20]="";\r
-\r
-       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr);\r
-       if (!ret) {\r
-               wl_ext_ip_dump(ip_addr, buf);\r
-               bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf);\r
-       }\r
-\r
-       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr);\r
-       if (!ret) {\r
-               wl_ext_ip_dump(ip_addr, buf);\r
-               bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf);\r
-       }\r
-\r
-       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr);\r
-       if (!ret) {\r
-               wl_ext_ip_dump(ip_addr, buf);\r
-               bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf);\r
-       }\r
-\r
-       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr);\r
-       if (!ret) {\r
-               wl_ext_ip_dump(ip_addr, buf);\r
-               bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf);\r
-       }\r
-\r
-       if (!bytes_written)\r
-               bytes_written = -1;\r
-       \r
-       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-\r
-       return bytes_written;\r
-}\r
-#endif\r
-\r
-/*\r
-dhd_priv dhd [string] ==> Not ready\r
-1. Get dhd val:\r
-  Ex: dhd_priv dhd bussleep\r
-2. Set dhd val:\r
-  Ex: dhd_priv dhd bussleep 1\r
-\r
-dhd_priv wl [WLC_GET_PM]  ==> Ready to get int val\r
-dhd_priv wl [WLC_SET_PM] [int]  ==> Ready to set int val\r
-dhd_priv wl [string]  ==> Ready to get int val\r
-dhd_priv wl [string] [int]  ==> Ready to set int val\r
-Ex: get/set WLC_PM\r
-  dhd_priv wl 85\r
-  dhd_priv wl 86 1\r
-Ex: get/set mpc\r
-  dhd_priv wl mpc\r
-  dhd_priv wl mpc 1\r
-*/\r
-int\r
-wl_ext_iovar(struct net_device *dev, char *command, int total_len)\r
-{\r
-       int ret = 0;\r
-       char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0";\r
-       int cmd=-1, val=0;\r
-       int bytes_written=-1;\r
-\r
-       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));\r
-\r
-       sscanf(command, "%s %d %s", wl, &cmd, arg);\r
-       if (cmd < 0)\r
-               sscanf(command, "%s %s %s", wl, cmd_str, val_str);\r
-\r
-       if (!strcmp(wl, "wl")) {\r
-               if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) {\r
-                       ret = sscanf(arg, "%d", &val);\r
-                       if (ret > 0) { // set\r
-                               ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE);\r
-                       } else { // get\r
-                               ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE);\r
-                               if (!ret) {\r
-                                       bytes_written = snprintf(command, total_len, "%d", val);\r
-                                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-                                       ret = bytes_written;\r
-                               }\r
-                       }\r
-               } else if (strlen(cmd_str)) {\r
-                       ret = sscanf(val_str, "%d", &val);\r
-                       if (ret > 0) { // set\r
-                               ret = wl_ext_iovar_setint(dev, cmd_str, val);\r
-                       } else { // get\r
-                               ret = wl_ext_iovar_getint(dev, cmd_str, &val);\r
-                               if (!ret) {\r
-                                       bytes_written = snprintf(command, total_len, "%d", val);\r
-                                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));\r
-                                       ret = bytes_written;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,\r
-               int *bytes_written)\r
-{\r
-       int ret = 0;\r
-\r
-       if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) {\r
-               *bytes_written = wl_ext_channels(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) {\r
-               *bytes_written = wl_ext_channel(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) {\r
-               *bytes_written = wl_ext_roam_trigger(net, command, total_len);\r
-       }
-       else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {\r
-               *bytes_written = wl_ext_keep_alive(net, command, total_len);\r
-       }
-       else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) {\r
-               *bytes_written = wl_ext_pm(net, command, total_len);\r
-       }\r
+                       /* IF SoftAP is enabled, disable arpoe */
+                       dhd_arp_offload_set(dhd, 0);
+                       dhd_arp_offload_enable(dhd, FALSE);
+#endif /* ARP_OFFLOAD_SUPPORT */
+               }
+       }
+       else if (apstamode == IDUALAP_MODE) {
+               wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
+       }
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(BCMSDIO)
+       if (cur_if==&apsta_params->vif && !disable_proptx) {
+               bool enabled;
+               dhd_wlfc_get_enable(dhd, &enabled);
+               if (!enabled) {
+                       dhd_wlfc_init(dhd);
+                       wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+               }
+       }
+#endif
+#endif /* PROP_TXSTATUS_VSDB */
+
+       printf("%s: ifname=%s, SSID: \"%s\"\n", __FUNCTION__, ifname, cur_if->ssid);
+
+       cur_if->ifstate = IF_STATE_ENABLE;
+
+exit:
+       return ret;
+}
+
+void
+wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel)
+{
+       struct wl_apsta_params *apsta_params = &g_apsta_params;
+       struct wl_if_info *cur_if = &apsta_params->vif;
+       scb_val_t scbval;
+       int ret;
+       channel_info_t ci;
+       struct dhd_pub *dhd;
+
+       if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) {
+               dhd = dhd_get_pub(dev);
+               if (!FW_SUPPORTED(dhd, vsdb)) {
+                       if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) {
+                               if (channel != ci.target_channel) {
+                                       printf("%s: deauthenticate all STA on vif\n", __FUNCTION__);
+                                       memcpy(scbval.ea.octet, &ether_bcast, ETHER_ADDR_LEN);
+                                       wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1);
+                               }
+                       }
+               }
+       }
+}
+
+int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx)
+{
+       g_apsta_params.vif.dev = net;
+       g_apsta_params.vif.bssidx = bssidx;
+       if (strlen(g_apsta_params.vif.ifname)) {
+               memset(net->name, 0, sizeof(IFNAMSIZ));
+               strcpy(net->name, g_apsta_params.vif.ifname);
+               net->name[IFNAMSIZ - 1] = '\0';
+       }
+       if (g_apsta_params.pif.dev) {
+               memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN);
+               net->dev_addr[0] |= 0x02;
+       }
+
+       return 0;
+}
+
+int wl_android_ext_dettach_netdev(void)
+{
+       struct wl_apsta_params *apsta_params = &g_apsta_params;
+
+       ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));
+       memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+
+       return 0;
+}
+#endif
+
+#ifdef IDHCP
+int wl_ext_ip_dump(int ip, char *buf)
+{
+       unsigned char bytes[4];
+       int bytes_written=-1;
+
+       bytes[0] = ip & 0xFF;
+       bytes[1] = (ip >> 8) & 0xFF;
+       bytes[2] = (ip >> 16) & 0xFF;
+       bytes[3] = (ip >> 24) & 0xFF;
+       bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
+
+       return bytes_written;
+}
+
+/*
+terence 20170215:
+dhd_priv dhcpc_dump ifname [wlan0|wlan1]
+dhd_priv dhcpc_enable [0|1]
+*/
+int
+wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len)
+{
+       int enable = -1, ret = -1;
+       int bytes_written = -1;
+
+       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+       sscanf(command, "%*s %d", &enable);
+
+       if (enable >= 0)
+               ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable);
+       else {
+               ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable);
+               if (!ret) {
+                       bytes_written = snprintf(command, total_len, "%d", enable);
+                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+                       ret = bytes_written;
+               }
+       }
+
+       return ret;
+}
+
+int
+wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len)
+{
+
+       int ret = 0;
+       int bytes_written = 0;
+       uint32 ip_addr;
+       char buf[20]="";
+
+       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr);
+       if (!ret) {
+               wl_ext_ip_dump(ip_addr, buf);
+               bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf);
+       }
+
+       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr);
+       if (!ret) {
+               wl_ext_ip_dump(ip_addr, buf);
+               bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf);
+       }
+
+       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr);
+       if (!ret) {
+               wl_ext_ip_dump(ip_addr, buf);
+               bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf);
+       }
+
+       ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr);
+       if (!ret) {
+               wl_ext_ip_dump(ip_addr, buf);
+               bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf);
+       }
+
+       if (!bytes_written)
+               bytes_written = -1;
+
+       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+
+       return bytes_written;
+}
+#endif
+
+/*
+dhd_priv dhd [string] ==> Not ready
+1. Get dhd val:
+  Ex: dhd_priv dhd bussleep
+2. Set dhd val:
+  Ex: dhd_priv dhd bussleep 1
+
+dhd_priv wl [WLC_GET_PM]  ==> Ready to get int val
+dhd_priv wl [WLC_SET_PM] [int]  ==> Ready to set int val
+dhd_priv wl [string]  ==> Ready to get int val
+dhd_priv wl [string] [int]  ==> Ready to set int val
+Ex: get/set WLC_PM
+  dhd_priv wl 85
+  dhd_priv wl 86 1
+Ex: get/set mpc
+  dhd_priv wl mpc
+  dhd_priv wl mpc 1
+*/
+int
+wl_ext_iovar(struct net_device *dev, char *command, int total_len)
+{
+       int ret = 0;
+       char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0";
+       int cmd=-1, val=0;
+       int bytes_written=-1;
+
+       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
+
+       sscanf(command, "%s %d %s", wl, &cmd, arg);
+       if (cmd < 0)
+               sscanf(command, "%s %s %s", wl, cmd_str, val_str);
+
+       if (!strcmp(wl, "wl")) {
+               if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) {
+                       ret = sscanf(arg, "%d", &val);
+                       if (ret > 0) { // set
+                               ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE);
+                       } else { // get
+                               ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE);
+                               if (!ret) {
+                                       bytes_written = snprintf(command, total_len, "%d", val);
+                                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+                                       ret = bytes_written;
+                               }
+                       }
+               } else if (strlen(cmd_str)) {
+                       ret = sscanf(val_str, "%d", &val);
+                       if (ret > 0) { // set
+                               ret = wl_ext_iovar_setint(dev, cmd_str, val);
+                       } else { // get
+                               ret = wl_ext_iovar_getint(dev, cmd_str, &val);
+                               if (!ret) {
+                                       bytes_written = snprintf(command, total_len, "%d", val);
+                                       ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+                                       ret = bytes_written;
+                               }
+                       }
+               }
+       }
+
+       return ret;
+}
+
+int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
+               int *bytes_written)
+{
+       int ret = 0;
+
+       if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) {
+               *bytes_written = wl_ext_channels(net, command, total_len);
+       }
+       else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) {
+               *bytes_written = wl_ext_channel(net, command, total_len);
+       }
+       else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) {
+               *bytes_written = wl_ext_roam_trigger(net, command, total_len);
+       }
+       else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) {
+               *bytes_written = wl_ext_keep_alive(net, command, total_len);
+       }
+       else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) {
+               *bytes_written = wl_ext_pm(net, command, total_len);
+       }
        else if (strnicmp(command, CMD_MONITOR, strlen(CMD_MONITOR)) == 0) {
-               *bytes_written = wl_ext_monitor(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) {\r
-               int bcn_li_dtim;\r
-               bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10);\r
-               *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim);\r
-       }\r
-#ifdef WL_EXT_IAPSTA\r
-       else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) {\r
-               *bytes_written = wl_ext_iapsta_init(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) {\r
-               *bytes_written = wl_ext_iapsta_config(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) {\r
-               *bytes_written = wl_ext_iapsta_enable(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) {\r
-               *bytes_written = wl_ext_iapsta_disable(net, command, total_len);\r
-       }\r
-#endif\r
-#ifdef IDHCP\r
-       else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) {\r
-               *bytes_written = wl_ext_dhcpc_enable(net, command, total_len);\r
-       }\r
-       else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) {\r
-               *bytes_written = wl_ext_dhcpc_dump(net, command, total_len);\r
-       }\r
-#endif\r
-       else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) {\r
-               *bytes_written = wl_ext_iovar(net, command, total_len);\r
-       }\r
-       else\r
-               ret = -1;\r
-
-       return ret;\r
-}\r
-\r
-#if defined(RSSIAVG)\r
-void\r
-wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)\r
-{\r
-       wl_rssi_cache_t *node, *cur, **rssi_head;\r
-       int i=0;\r
-\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-       node = *rssi_head;\r
-\r
-       for (;node;) {\r
-               ANDROID_INFO(("%s: Free %d with BSSID %pM\n",\r
-                       __FUNCTION__, i, &node->BSSID));\r
-               cur = node;\r
-               node = cur->next;\r
-               kfree(cur);\r
-               i++;\r
-       }\r
-       *rssi_head = NULL;\r
-}\r
-\r
-void\r
-wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)\r
-{\r
-       wl_rssi_cache_t *node, *prev, **rssi_head;\r
-       int i = -1, tmp = 0;\r
-       struct timeval now;\r
-\r
-       do_gettimeofday(&now);\r
-\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-       node = *rssi_head;\r
-       prev = node;\r
-       for (;node;) {\r
-               i++;\r
-               if (now.tv_sec > node->tv.tv_sec) {\r
-                       if (node == *rssi_head) {\r
-                               tmp = 1;\r
-                               *rssi_head = node->next;\r
-                       } else {\r
-                               tmp = 0;\r
-                               prev->next = node->next;\r
-                       }\r
-                       ANDROID_INFO(("%s: Del %d with BSSID %pM\n",\r
-                               __FUNCTION__, i, &node->BSSID));\r
-                       kfree(node);\r
-                       if (tmp == 1) {\r
-                               node = *rssi_head;\r
-                               prev = node;\r
-                       } else {\r
-                               node = prev->next;\r
-                       }\r
-                       continue;\r
-               }\r
-               prev = node;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-void\r
-wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid)\r
-{\r
-       wl_rssi_cache_t *node, *prev, **rssi_head;\r
-       int i = -1, tmp = 0;\r
-\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-       node = *rssi_head;\r
-       prev = node;\r
-       for (;node;) {\r
-               i++;\r
-               if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) {\r
-                       if (node == *rssi_head) {\r
-                               tmp = 1;\r
-                               *rssi_head = node->next;\r
-                       } else {\r
-                               tmp = 0;\r
-                               prev->next = node->next;\r
-                       }\r
-                       ANDROID_INFO(("%s: Del %d with BSSID %pM\n",\r
-                               __FUNCTION__, i, &node->BSSID));\r
-                       kfree(node);\r
-                       if (tmp == 1) {\r
-                               node = *rssi_head;\r
-                               prev = node;\r
-                       } else {\r
-                               node = prev->next;\r
-                       }\r
-                       continue;\r
-               }\r
-               prev = node;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-void\r
-wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl)\r
-{\r
-       wl_rssi_cache_t *node, **rssi_head;\r
-\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-\r
-       /* reset dirty */\r
-       node = *rssi_head;\r
-       for (;node;) {\r
-               node->dirty += 1;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-int\r
-wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg)\r
-{\r
-       wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;\r
-       int j, k=0;\r
-       int rssi, error=0;\r
-       struct ether_addr bssid;\r
-       struct timeval now, timeout;\r
-\r
-       if (!g_wifi_on)\r
-               return 0;\r
-\r
-       error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false);\r
-       if (error == BCME_NOTASSOCIATED) {\r
-               ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error));\r
-               return 0;\r
-       }\r
-       if (error) {\r
-               ANDROID_ERROR(("Could not get bssid (%d)\n", error));\r
-       }\r
-       error = wldev_get_rssi(net, &rssi);\r
-       if (error) {\r
-               ANDROID_ERROR(("Could not get rssi (%d)\n", error));\r
-               return error;\r
-       }\r
-\r
-       do_gettimeofday(&now);\r
-       timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;\r
-       if (timeout.tv_sec < now.tv_sec) {\r
-               /*\r
-                * Integer overflow - assume long enough timeout to be assumed\r
-                * to be infinite, i.e., the timeout would never happen.\r
-                */\r
-               ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",\r
-                       __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));\r
-       }\r
-\r
-       /* update RSSI */\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-       node = *rssi_head;\r
-       prev = NULL;\r
-       for (;node;) {\r
-               if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) {\r
-                       ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n",\r
-                               __FUNCTION__, k, &bssid, rssi));\r
-                       for (j=0; j<RSSIAVG_LEN-1; j++)\r
-                               node->RSSI[j] = node->RSSI[j+1];\r
-                       node->RSSI[j] = rssi;\r
-                       node->dirty = 0;\r
-                       node->tv = timeout;\r
-                       goto exit;\r
-               }\r
-               prev = node;\r
-               node = node->next;\r
-               k++;\r
-       }\r
-\r
-       leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);\r
-       if (!leaf) {\r
-               ANDROID_ERROR(("%s: Memory alloc failure %d\n",\r
-                       __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));\r
-               return 0;\r
-       }\r
-       ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n",\r
-                       __FUNCTION__, k, &bssid, rssi));\r
-\r
-       leaf->next = NULL;\r
-       leaf->dirty = 0;\r
-       leaf->tv = timeout;\r
-       memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN);\r
-       for (j=0; j<RSSIAVG_LEN; j++)\r
-               leaf->RSSI[j] = rssi;\r
-\r
-       if (!prev)\r
-               *rssi_head = leaf;\r
-       else\r
-               prev->next = leaf;\r
-\r
-exit:\r
-       *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid);\r
-\r
-       return error;\r
-}\r
-\r
-void\r
-wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list)\r
-{\r
-       wl_rssi_cache_t *node, *prev, *leaf, **rssi_head;\r
-       wl_bss_info_t *bi = NULL;\r
-       int i, j, k;\r
-       struct timeval now, timeout;\r
-\r
-       if (!ss_list->count)\r
-               return;\r
-\r
-       do_gettimeofday(&now);\r
-       timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT;\r
-       if (timeout.tv_sec < now.tv_sec) {\r
-               /*\r
-                * Integer overflow - assume long enough timeout to be assumed\r
-                * to be infinite, i.e., the timeout would never happen.\r
-                */\r
-               ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",\r
-                       __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));\r
-       }\r
-\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-\r
-       /* update RSSI */\r
-       for (i = 0; i < ss_list->count; i++) {\r
-               node = *rssi_head;\r
-               prev = NULL;\r
-               k = 0;\r
-               bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;\r
-               for (;node;) {\r
-                       if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {\r
-                               ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
-                                       __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
-                               for (j=0; j<RSSIAVG_LEN-1; j++)\r
-                                       node->RSSI[j] = node->RSSI[j+1];\r
-                               node->RSSI[j] = dtoh16(bi->RSSI);\r
-                               node->dirty = 0;\r
-                               node->tv = timeout;\r
-                               break;\r
-                       }\r
-                       prev = node;\r
-                       node = node->next;\r
-                       k++;\r
-               }\r
-\r
-               if (node)\r
-                       continue;\r
-\r
-               leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL);\r
-               if (!leaf) {\r
-                       ANDROID_ERROR(("%s: Memory alloc failure %d\n",\r
-                               __FUNCTION__, (int)sizeof(wl_rssi_cache_t)));\r
-                       return;\r
-               }\r
-               ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\" in the leaf\n",\r
-                               __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
-\r
-               leaf->next = NULL;\r
-               leaf->dirty = 0;\r
-               leaf->tv = timeout;\r
-               memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN);\r
-               for (j=0; j<RSSIAVG_LEN; j++)\r
-                       leaf->RSSI[j] = dtoh16(bi->RSSI);\r
-\r
-               if (!prev)\r
-                       *rssi_head = leaf;\r
-               else\r
-                       prev->next = leaf;\r
-       }\r
-}\r
-\r
-int16\r
-wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr)\r
-{\r
-       wl_rssi_cache_t *node, **rssi_head;\r
-       int j, rssi_sum, rssi=RSSI_MINVAL;\r
-\r
-       rssi_head = &rssi_cache_ctrl->m_cache_head;\r
-\r
-       node = *rssi_head;\r
-       for (;node;) {\r
-               if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) {\r
-                       rssi_sum = 0;\r
-                       rssi = 0;\r
-                       for (j=0; j<RSSIAVG_LEN; j++)\r
-                               rssi_sum += node->RSSI[RSSIAVG_LEN-j-1];\r
-                       rssi = rssi_sum / j;\r
-                       break;\r
-               }\r
-               node = node->next;\r
-       }\r
-       rssi = MIN(rssi, RSSI_MAXVAL);\r
-       if (rssi == RSSI_MINVAL) {\r
-               ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n",\r
-               __FUNCTION__, addr));\r
-       }\r
-       return (int16)rssi;\r
-}\r
-#endif\r
-\r
-#if defined(RSSIOFFSET)\r
-int\r
-wl_update_rssi_offset(struct net_device *net, int rssi)\r
-{\r
-#if defined(RSSIOFFSET_NEW)\r
-       int j;\r
-#endif\r
-\r
-       if (!g_wifi_on)\r
-               return rssi;\r
-\r
-#if defined(RSSIOFFSET_NEW)\r
-       for (j=0; j<RSSI_OFFSET; j++) {\r
-               if (rssi - (RSSI_OFFSET_MINVAL+RSSI_OFFSET_INTVAL*(j+1)) < 0)\r
-                       break;\r
-       }\r
-       rssi += j;\r
-#else\r
-       rssi += RSSI_OFFSET;\r
-#endif\r
-       return MIN(rssi, RSSI_MAXVAL);\r
-}\r
-#endif\r
-\r
-#if defined(BSSCACHE)\r
-void\r
-wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
-       wl_bss_cache_t *node, *cur, **bss_head;\r
-       int i=0;\r
-\r
-       ANDROID_TRACE(("%s called\n", __FUNCTION__));\r
-\r
-       bss_head = &bss_cache_ctrl->m_cache_head;\r
-       node = *bss_head;\r
-\r
-       for (;node;) {\r
-               ANDROID_TRACE(("%s: Free %d with BSSID %pM\n",\r
-                       __FUNCTION__, i, &node->results.bss_info->BSSID));\r
-               cur = node;\r
-               node = cur->next;\r
-               kfree(cur);\r
-               i++;\r
-       }\r
-       *bss_head = NULL;\r
-}\r
-\r
-void\r
-wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
-       wl_bss_cache_t *node, *prev, **bss_head;\r
-       int i = -1, tmp = 0;\r
-       struct timeval now;\r
-\r
-       do_gettimeofday(&now);\r
-\r
-       bss_head = &bss_cache_ctrl->m_cache_head;\r
-       node = *bss_head;\r
-       prev = node;\r
-       for (;node;) {\r
-               i++;\r
-               if (now.tv_sec > node->tv.tv_sec) {\r
-                       if (node == *bss_head) {\r
-                               tmp = 1;\r
-                               *bss_head = node->next;\r
-                       } else {\r
-                               tmp = 0;\r
-                               prev->next = node->next;\r
-                       }\r
-                       ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
-                               __FUNCTION__, i, &node->results.bss_info->BSSID,\r
-                               dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));\r
-                       kfree(node);\r
-                       if (tmp == 1) {\r
-                               node = *bss_head;\r
-                               prev = node;\r
-                       } else {\r
-                               node = prev->next;\r
-                       }\r
-                       continue;\r
-               }\r
-               prev = node;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-void\r
-wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid)\r
-{\r
-       wl_bss_cache_t *node, *prev, **bss_head;\r
-       int i = -1, tmp = 0;\r
-\r
-       bss_head = &bss_cache_ctrl->m_cache_head;\r
-       node = *bss_head;\r
-       prev = node;\r
-       for (;node;) {\r
-               i++;\r
-               if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) {\r
-                       if (node == *bss_head) {\r
-                               tmp = 1;\r
-                               *bss_head = node->next;\r
-                       } else {\r
-                               tmp = 0;\r
-                               prev->next = node->next;\r
-                       }\r
-                       ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
-                               __FUNCTION__, i, &node->results.bss_info->BSSID,\r
-                               dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID));\r
-                       kfree(node);\r
-                       if (tmp == 1) {\r
-                               node = *bss_head;\r
-                               prev = node;\r
-                       } else {\r
-                               node = prev->next;\r
-                       }\r
-                       continue;\r
-               }\r
-               prev = node;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-void\r
-wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
-       wl_bss_cache_t *node, **bss_head;\r
-\r
-       bss_head = &bss_cache_ctrl->m_cache_head;\r
-\r
-       /* reset dirty */\r
-       node = *bss_head;\r
-       for (;node;) {\r
-               node->dirty += 1;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-void dump_bss_cache(\r
-#if defined(RSSIAVG)\r
-       wl_rssi_cache_ctrl_t *rssi_cache_ctrl,\r
-#endif\r
-       wl_bss_cache_t *node)\r
-{\r
-       int k = 0;\r
-       int16 rssi;\r
-\r
-       for (;node;) {\r
-#if defined(RSSIAVG)\r
-               rssi = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);\r
-#else\r
-               rssi = dtoh16(node->results.bss_info->RSSI);\r
-#endif\r
-               ANDROID_TRACE(("%s: dump %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
-                       __FUNCTION__, k, &node->results.bss_info->BSSID, rssi, node->results.bss_info->SSID));\r
-               k++;\r
-               node = node->next;\r
-       }\r
-}\r
-\r
-void\r
-wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl,\r
-#if defined(RSSIAVG)\r
-       wl_rssi_cache_ctrl_t *rssi_cache_ctrl,\r
-#endif\r
-       wl_scan_results_t *ss_list)\r
-{\r
-       wl_bss_cache_t *node, *prev, *leaf, **bss_head;\r
-       wl_bss_info_t *bi = NULL;\r
-       int i, k=0;\r
-#if defined(SORT_BSS_BY_RSSI)\r
-       int16 rssi, rssi_node;\r
-#endif\r
-       struct timeval now, timeout;\r
-\r
-       if (!ss_list->count)\r
-               return;\r
-\r
-       do_gettimeofday(&now);\r
-       timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT;\r
-       if (timeout.tv_sec < now.tv_sec) {\r
-               /*\r
-                * Integer overflow - assume long enough timeout to be assumed\r
-                * to be infinite, i.e., the timeout would never happen.\r
-                */\r
-               ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu",\r
-                       __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec));\r
-       }\r
-\r
-       bss_head = &bss_cache_ctrl->m_cache_head;\r
-\r
-       for (i=0; i < ss_list->count; i++) {\r
-               node = *bss_head;\r
-               prev = NULL;\r
-               bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info;\r
-\r
-               for (;node;) {\r
-                       if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) {\r
-                               if (node == *bss_head)\r
-                                       *bss_head = node->next;\r
-                               else {\r
-                                       prev->next = node->next;\r
-                               }\r
-                               break;\r
-                       }\r
-                       prev = node;\r
-                       node = node->next;\r
-               }\r
-\r
-               leaf = kmalloc(dtoh32(bi->length) + sizeof(wl_bss_cache_t), GFP_KERNEL);\r
-               if (!leaf) {\r
-                       ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__,\r
-                               dtoh32(bi->length) + (int)sizeof(wl_bss_cache_t)));\r
-                       return;\r
-               }\r
-               if (node) {\r
-                       kfree(node);\r
-                       node = NULL;\r
-                       ANDROID_TRACE(("%s: Update %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
-                               __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
-               } else\r
-                       ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n",\r
-                               __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID));\r
-\r
-               memcpy(leaf->results.bss_info, bi, dtoh32(bi->length));\r
-               leaf->next = NULL;\r
-               leaf->dirty = 0;\r
-               leaf->tv = timeout;\r
-               leaf->results.count = 1;\r
-               leaf->results.version = ss_list->version;\r
-               k++;\r
-\r
-               if (*bss_head == NULL)\r
-                       *bss_head = leaf;\r
-               else {\r
-#if defined(SORT_BSS_BY_RSSI)\r
-                       node = *bss_head;\r
-#if defined(RSSIAVG)\r
-                       rssi = wl_get_avg_rssi(rssi_cache_ctrl, &leaf->results.bss_info->BSSID);\r
-#else\r
-                       rssi = dtoh16(leaf->results.bss_info->RSSI);\r
-#endif\r
-                       for (;node;) {\r
-#if defined(RSSIAVG)\r
-                               rssi_node = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID);\r
-#else\r
-                               rssi_node = dtoh16(node->results.bss_info->RSSI);\r
-#endif\r
-                               if (rssi > rssi_node) {\r
-                                       leaf->next = node;\r
-                                       if (node == *bss_head)\r
-                                               *bss_head = leaf;\r
-                                       else\r
-                                               prev->next = leaf;\r
-                                       break;\r
-                               }\r
-                               prev = node;\r
-                               node = node->next;\r
-                       }\r
-                       if (node == NULL)\r
-                               prev->next = leaf;\r
-#else\r
-                       leaf->next = *bss_head;\r
-                       *bss_head = leaf;\r
-#endif\r
-               }\r
-       }\r
-       dump_bss_cache(\r
-#if defined(RSSIAVG)\r
-               rssi_cache_ctrl,\r
-#endif\r
-               *bss_head);\r
-}\r
-\r
-void\r
-wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl)\r
-{\r
-       ANDROID_TRACE(("%s:\n", __FUNCTION__));\r
-       wl_free_bss_cache(bss_cache_ctrl);\r
-}\r
-#endif\r
-\r
-\r
+               *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
+
+
index efadf25123fe3e1fc27549ddefb7751163c94371..5651601a9dbb9a5087419116106acd99f92c7fc8 100644 (file)
@@ -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) &&
index 1b985b0908804d3954d11d329125941773f6af62..ebe656ff35482ea2ac45b104cbd9bf107b00ba1c 100644 (file)
@@ -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);