wifi: broadcom sta + ap mode use hostapd [1/3]
authorWeiguang Ruan <Weiguang.ruan@amlogic.com>
Thu, 19 Oct 2017 06:54:42 +0000 (14:54 +0800)
committerWeiguang Ruan <Weiguang.ruan@amlogic.com>
Thu, 19 Oct 2017 07:05:37 +0000 (15:05 +0800)
PD#151669

1. add sta + ap with hostapd mode support
2. fix unload driver kernel panic(wowlan_config->nd_config)

Change-Id: Ie72b70a22c1f3c5c0bedb3ee1de912b64d228018

21 files changed:
bcmdhd.1.363.59.144.x.cn/Makefile
bcmdhd.1.363.59.144.x.cn/bcmsdh_linux.c
bcmdhd.1.363.59.144.x.cn/bcmsdh_sdmmc.c
bcmdhd.1.363.59.144.x.cn/bcmutils.c
bcmdhd.1.363.59.144.x.cn/dhd.h
bcmdhd.1.363.59.144.x.cn/dhd_config.c
bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej [deleted file]
bcmdhd.1.363.59.144.x.cn/dhd_config.h
bcmdhd.1.363.59.144.x.cn/dhd_gpio.c
bcmdhd.1.363.59.144.x.cn/dhd_linux.c
bcmdhd.1.363.59.144.x.cn/dhd_sdio.c
bcmdhd.1.363.59.144.x.cn/dhd_static_buf.c
bcmdhd.1.363.59.144.x.cn/dhd_wlfc.c
bcmdhd.1.363.59.144.x.cn/include/epivers.h
bcmdhd.1.363.59.144.x.cn/include/linux_osl.h
bcmdhd.1.363.59.144.x.cn/include/wlioctl.h
bcmdhd.1.363.59.144.x.cn/linux_osl.c
bcmdhd.1.363.59.144.x.cn/wl_android.c
bcmdhd.1.363.59.144.x.cn/wl_android_ext.c
bcmdhd.1.363.59.144.x.cn/wl_cfg80211.c
bcmdhd.1.363.59.144.x.cn/wl_cfgvendor.c

index d8b76862ec18a9b8a5bb484b68a0b64e6f939995..c0dadf72a2447c68e1c3d92d4e9fc6248212af2f 100644 (file)
@@ -6,7 +6,7 @@
 ifeq ($(CONFIG_BCMDHD_PCIE),)
 $(info bcm SDIO driver configured)
 CONFIG_BCMDHD_SDIO := y
-CONFIG_DHD_USE_STATIC_BUF :=y
+CONFIG_DHD_USE_STATIC_BUF := y
 endif
 CONFIG_BCMDHD_PROPTXSTATUS := y
 
@@ -36,8 +36,6 @@ DHDCFLAGS += \
        -DBDC -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM                           \
        -DCUSTOM_SDIO_F2_BLKSIZE=256
 
-DHDCFLAGS += -DDCUSTOM_DPC_PRIO_SETTING=-1
-DHDCFLAGS += -DCUSTOM_RXF_CPUCORE=2
 DHDCFLAGS += -DDHD_FIRSTREAD=256 -DMAX_HDR_READ=256
 
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \
@@ -111,6 +109,7 @@ DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
 DHDCFLAGS += -DESCAN_RESULT_PATCH
 DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
 DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8
+DHDCFLAGS += -DWL_VIRTUAL_APSTA
 endif
 EXTRA_CFLAGS = $(DHDCFLAGS)
 ifeq ($(CONFIG_BCMDHD),m)
index 5087eb4eccf607b0f58824fe6a99d0f02c5686f9..9c93279dcbf2188b8e6b38a5b397947a1297257b 100644 (file)
@@ -52,8 +52,6 @@ extern void dhdsdio_isr(void * args);
 #endif /* defined(CONFIG_ARCH_ODIN) */
 #include <dhd_linux.h>
 
-#include <linux/interrupt.h>
-
 /* driver info, initialized when bcmsdh_register is called */
 static bcmsdh_driver_t drvinfo = {NULL, NULL, NULL, NULL};
 
@@ -349,11 +347,6 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl
 #endif
        SDLX_MSG(("%s OOB irq=%d flags=0x%X\n", __FUNCTION__,
                (int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
-       // anthony: test begin
-       bcmsdh_osinfo->oob_irq_flags &= IRQF_TRIGGER_MASK;
-       printf("%s change flags to 0x%X\n", __FUNCTION__, (int)bcmsdh_osinfo->oob_irq_flags);
-       // anthony: test end    
-
        bcmsdh_osinfo->oob_irq_handler = oob_irq_handler;
        bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context;
        bcmsdh_osinfo->oob_irq_enabled = TRUE;
@@ -372,10 +365,6 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl
                return err;
        }
 
-#ifdef CUSTOM_DPC_CPUCORE
-       irq_set_affinity(bcmsdh_osinfo->oob_irq_num, cpumask_of(CUSTOM_DPC_CPUCORE));
-#endif
-
 #if defined(DISABLE_WOWLAN)
        SDLX_MSG(("%s: disable_irq_wake\n", __FUNCTION__));
        bcmsdh_osinfo->oob_irq_wake_enabled = FALSE;
index 58be7ff6aa76d9aed10425cfc921dfe99017683f..9c576475f289f1b6d0b2b0516ea2caa3ee007430 100644 (file)
@@ -919,8 +919,8 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
 
        if (sd_msglevel & SDH_COST_VAL) {
                getnstimeofday(&now);
-//     sd_cost(("%s: rw=%d len=1 cost=%lds %luus\n", __FUNCTION__,
-//             rw, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000));
+               sd_cost(("%s: rw=%d len=1 cost=%lds %luus\n", __FUNCTION__,
+                       rw, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000));
        }
 
        return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
@@ -1396,8 +1396,8 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add
 
        if (sd_msglevel & SDH_COST_VAL) {
                getnstimeofday(&now);
-//     sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__,
-//             rw, nbytes, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000));
+               sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__,
+                       rw, nbytes, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000));
        }
 
        return (((err_ret == 0)&&(err_ret2 == 0)) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
@@ -1475,7 +1475,7 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
                         * a restriction on max tx/glom count (based on host->max_segs).
                         */
                        if (sg_count >= ARRAYSIZE(sd->sg_list)) {
-//                             sd_err(("%s: sg list entries exceed limit, sg_count=%d(%lu)\n", __FUNCTION__, sg_count, ARRAYSIZE(sd->sg_list)));
+                               sd_err(("%s: sg list entries exceed limit %d\n", __FUNCTION__, sg_count));
                                return (SDIOH_API_RC_FAIL);
                        }
                        pdata += pkt_offset;
@@ -1613,8 +1613,8 @@ txglomfail:
 
        if (sd_msglevel & SDH_COST_VAL) {
                getnstimeofday(&now);
-//     sd_cost(("%s: rw=%d, cost=%lds %luus\n", __FUNCTION__,
-//             write, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000));
+               sd_cost(("%s: rw=%d, cost=%lds %luus\n", __FUNCTION__,
+                       write, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000));
        }
 
        sd_trace(("%s: Exit\n", __FUNCTION__));
@@ -1668,8 +1668,8 @@ sdioh_buffer_tofrom_bus(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
 
        if (sd_msglevel & SDH_COST_VAL) {
                getnstimeofday(&now);
-//     sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__,
-//             write, len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000));
+               sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__,
+                       write, len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000));
        }
 
        return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
@@ -1745,8 +1745,8 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
 
        if (sd_msglevel & SDH_COST_VAL) {
                getnstimeofday(&now);
-//     sd_cost(("%s: len=%d cost=%lds %luus\n", __FUNCTION__,
-//             buf_len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000));
+               sd_cost(("%s: len=%d cost=%lds %luus\n", __FUNCTION__,
+                       buf_len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000));
        }
 
        return status;
index badb2237545223c8816b554b4def03b1c04bb3e4..32ddc1f43bf563f720d0b661e1d759aa2c45a189 100644 (file)
@@ -2469,6 +2469,7 @@ process_nvram_vars(char *varbuf, unsigned int len)
        int column;
        unsigned int buf_len, n;
        unsigned int pad = 0;
+       char nv_ver[128];
 
        dp = varbuf;
 
@@ -2477,13 +2478,13 @@ process_nvram_vars(char *varbuf, unsigned int len)
 
        // terence 20130914: print out NVRAM version
        if (varbuf[0] == '#') {
-               printf("NVRAM version: ");
-               for (n=1; n<len; n++) {
+               memset(nv_ver, 0x00, sizeof(nv_ver));
+               for (n=1; n<len && n<(sizeof(nv_ver)-1); n++) {
                        if (varbuf[n] == '\n')
                                break;
-                       printk("%c", varbuf[n]);
+                       nv_ver[n-1] = varbuf[n];
                }
-               printk("\n");
+               printk("NVRAM version: %s\n", nv_ver);
        }
 
        for (n = 0; n < len; n++) {
index 4cbbbb338fc0c93c18b5bd21aa81fc83dc35fe01..135c92f8d536de0bfebc9f36a96ae97a91b545d7 100644 (file)
@@ -215,6 +215,7 @@ enum dhd_prealloc_index {
        DHD_PREALLOC_RXBUF,
        DHD_PREALLOC_DATABUF,
        DHD_PREALLOC_OSL_BUF,
+       DHD_PREALLOC_SKB_BUF,
 #if defined(STATIC_WL_PRIV_STRUCT)
        DHD_PREALLOC_WIPHY_ESCAN0 = 5,
 #endif /* STATIC_WL_PRIV_STRUCT */
index a6508328f57e6825fa2b13b02efa90ec26e633de..842d9cbb52e4a3465775a6f5d3bbabd972da6135 100644 (file)
-\r
-#include <typedefs.h>\r
-#include <osl.h>\r
-\r
-#include <bcmutils.h>\r
-#include <hndsoc.h>\r
-#include <bcmsdbus.h>\r
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <hndsoc.h>
+#include <bcmsdbus.h>
 #if defined(HW_OOB) || defined(FORCE_WOWLAN)
-#include <bcmdefs.h>\r
-#include <bcmsdh.h>\r
-#include <sdio.h>\r
-#include <sbchipc.h>\r
-#endif\r
-\r
-#include <dhd_config.h>\r
-#include <dhd_dbg.h>\r
-\r
+#include <bcmdefs.h>
+#include <bcmsdh.h>
+#include <sdio.h>
+#include <sbchipc.h>
+#endif
+
+#include <dhd_config.h>
+#include <dhd_dbg.h>
+
 /* message levels */
-#define CONFIG_ERROR_LEVEL     0x0001\r
-#define CONFIG_TRACE_LEVEL     0x0002\r
+#define CONFIG_ERROR_LEVEL     0x0001
+#define CONFIG_TRACE_LEVEL     0x0002
 
-uint config_msg_level = CONFIG_ERROR_LEVEL;\r
+uint config_msg_level = CONFIG_ERROR_LEVEL;
 
-#define CONFIG_ERROR(x) \\r
+#define CONFIG_ERROR(x) \
        do { \
-               if (config_msg_level & CONFIG_ERROR_LEVEL) { \\r
-                       printk(KERN_ERR "CONFIG-ERROR) ");      \\r
+               if (config_msg_level & CONFIG_ERROR_LEVEL) { \
+                       printk(KERN_ERR "CONFIG-ERROR) ");      \
                        printk x; \
                } \
        } while (0)
-#define CONFIG_TRACE(x) \\r
+#define CONFIG_TRACE(x) \
        do { \
-               if (config_msg_level & CONFIG_TRACE_LEVEL) { \\r
-                       printk(KERN_ERR "CONFIG-TRACE) ");      \\r
+               if (config_msg_level & CONFIG_TRACE_LEVEL) { \
+                       printk(KERN_ERR "CONFIG-TRACE) ");      \
                        printk x; \
                } \
-       } while (0)\r
-\r
-#define MAXSZ_BUF              1000\r
-#define        MAXSZ_CONFIG    4096\r
-\r
-#define FW_TYPE_STA     0\r
-#define FW_TYPE_APSTA   1\r
-#define FW_TYPE_P2P     2\r
-#define FW_TYPE_ES      3\r
-#define FW_TYPE_MFG     4\r
-#define FW_TYPE_G       0\r
-#define FW_TYPE_AG      1\r
-\r
-#ifdef CONFIG_PATH_AUTO_SELECT\r
-#ifdef BCMSDIO\r
-#define CONFIG_BCM4330B2 "config_40183b2.txt"\r
-#define CONFIG_BCM43362A0 "config_40181a0.txt"\r
-#define CONFIG_BCM43362A2 "config_40181a2.txt"\r
-#define CONFIG_BCM43438A0 "config_43438a0.txt"\r
-#define CONFIG_BCM43438A1 "config_43438a1.txt"\r
-#define CONFIG_BCM43436B0 "config_43436b0.txt"\r
-#define CONFIG_BCM4334B1 "config_4334b1.txt"\r
-#define CONFIG_BCM43341B0 "config_43341b0.txt"\r
-#define CONFIG_BCM43241B4 "config_43241b4.txt"\r
-#define CONFIG_BCM4339A0 "config_4339a0.txt"\r
-#define CONFIG_BCM43455C0 "config_43455c0.txt"\r
-#define CONFIG_BCM43456C5 "config_43456c5.txt"\r
-#define CONFIG_BCM4354A1 "config_4354a1.txt"\r
-#endif\r
-#define CONFIG_BCM4356A2 "config_4356a2.txt"\r
-#define CONFIG_BCM4358A3 "config_4358.txt"\r
-#define CONFIG_BCM4359B1 "config_4359b1.txt"\r
-#define CONFIG_BCM4359C0 "config_4359c0.txt"\r
-#endif\r
-\r
-#ifdef BCMSDIO\r
-#define SBSDIO_CIS_SIZE_LIMIT          0x200           /* maximum bytes in one CIS */\r
-\r
-#define FW_BCM4330B2 "fw_bcm40183b2"\r
-#define FW_BCM4330B2_AG "fw_bcm40183b2_ag"\r
-#define FW_BCM43362A0 "fw_bcm40181a0"\r
-#define FW_BCM43362A2 "fw_bcm40181a2"\r
-#define FW_BCM4334B1 "fw_bcm4334b1_ag"\r
-#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_BCM43341B1 "fw_bcm43341b0_ag"\r
-#define FW_BCM43241B4 "fw_bcm43241b4_ag"\r
-#define FW_BCM4339A0 "fw_bcm4339a0_ag"\r
-#define FW_BCM43455C0 "fw_bcm43455c0_ag"\r
-#define FW_BCM43456C5 "fw_bcm43456c5_ag"\r
-#define FW_BCM4354A1 "fw_bcm4354a1_ag"\r
-#define FW_BCM4356A2 "fw_bcm4356a2_ag"\r
-#define FW_BCM4358A3 "fw_bcm4358_ag"\r
-#define FW_BCM4359B1 "fw_bcm4359b1_ag"\r
-#define FW_BCM4359C0 "fw_bcm4359c0_ag"\r
-\r
-#define CLM_BCM43012B0 "clm_bcm43012b0"\r
-#endif\r
-#ifdef BCMPCIE\r
-#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"\r
-#endif\r
-\r
+       } while (0)
+
+#define MAXSZ_BUF              1000
+#define        MAXSZ_CONFIG    4096
+
+#define FW_TYPE_STA     0
+#define FW_TYPE_APSTA   1
+#define FW_TYPE_P2P     2
+#define FW_TYPE_ES      3
+#define FW_TYPE_MFG     4
+#define FW_TYPE_G       0
+#define FW_TYPE_AG      1
+
+#ifdef CONFIG_PATH_AUTO_SELECT
+#ifdef BCMSDIO
+#define CONFIG_BCM4330B2 "config_40183b2.txt"
+#define CONFIG_BCM43362A0 "config_40181a0.txt"
+#define CONFIG_BCM43362A2 "config_40181a2.txt"
+#define CONFIG_BCM43438A0 "config_43438a0.txt"
+#define CONFIG_BCM43438A1 "config_43438a1.txt"
+#define CONFIG_BCM43436B0 "config_43436b0.txt"
+#define CONFIG_BCM4334B1 "config_4334b1.txt"
+#define CONFIG_BCM43341B0 "config_43341b0.txt"
+#define CONFIG_BCM43241B4 "config_43241b4.txt"
+#define CONFIG_BCM4339A0 "config_4339a0.txt"
+#define CONFIG_BCM43454C0 "config_43454c0.txt"
+#define CONFIG_BCM43455C0 "config_43455c0.txt"
+#define CONFIG_BCM43456C5 "config_43456c5.txt"
+#define CONFIG_BCM4354A1 "config_4354a1.txt"
+#endif
+#define CONFIG_BCM4356A2 "config_4356a2.txt"
+#define CONFIG_BCM4358A3 "config_4358a3.txt"
+#define CONFIG_BCM4359B1 "config_4359b1.txt"
+#define CONFIG_BCM4359C0 "config_4359c0.txt"
+#endif
+
+#ifdef BCMSDIO
+#define SBSDIO_CIS_SIZE_LIMIT          0x200
+
+#define FW_BCM4330B2 "fw_bcm40183b2"
+#define FW_BCM4330B2_AG "fw_bcm40183b2_ag"
+#define FW_BCM43362A0 "fw_bcm40181a0"
+#define FW_BCM43362A2 "fw_bcm40181a2"
+#define FW_BCM4334B1 "fw_bcm4334b1_ag"
+#define FW_BCM43438A0 "fw_bcm43438a0"
+#define FW_BCM43438A1 "fw_bcm43438a1"
+#define FW_BCM43436B0 "fw_bcm43436b0"
+#define FW_BCM43012B0 "fw_bcm43012b0"
+#define FW_BCM43341B1 "fw_bcm43341b0_ag"
+#define FW_BCM43241B4 "fw_bcm43241b4_ag"
+#define FW_BCM4339A0 "fw_bcm4339a0_ag"
+#define FW_BCM43455C0 "fw_bcm43455c0_ag"
+#define FW_BCM43456C5 "fw_bcm43456c5_ag"
+#define FW_BCM4354A1 "fw_bcm4354a1_ag"
+#define FW_BCM4356A2 "fw_bcm4356a2_ag"
+#define FW_BCM4358A3 "fw_bcm4358a3_ag"
+#define FW_BCM4359B1 "fw_bcm4359b1_ag"
+#define FW_BCM4359C0 "fw_bcm4359c0_ag"
+
+#define CLM_BCM43012B0 "clm_bcm43012b0"
+#endif
+#ifdef BCMPCIE
+#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"
+#endif
+
 #define htod32(i) i
 #define htod16(i) i
 #define dtoh32(i) i
 #define dtoh16(i) i
 #define htodchanspec(i) i
-#define dtohchanspec(i) i\r
-\r
-#ifdef BCMSDIO\r
-void\r
-dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)\r
-{\r
-       int i;\r
-\r
-       CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
-       if (mac_list->m_mac_list_head) {\r
-               for (i=0; i<mac_list->count; i++) {\r
-                       if (mac_list->m_mac_list_head[i].mac) {\r
-                               CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac));\r
-                               kfree(mac_list->m_mac_list_head[i].mac);\r
-                       }\r
-               }\r
-               CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head));\r
-               kfree(mac_list->m_mac_list_head);\r
-       }\r
-       mac_list->count = 0;\r
-}\r
-\r
-void\r
-dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)\r
-{\r
-       CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
-\r
-       if (chip_nv_list->m_chip_nv_path_head) {\r
-               CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head));\r
-               kfree(chip_nv_list->m_chip_nv_path_head);\r
-       }\r
-       chip_nv_list->count = 0;\r
-}\r
-\r
-#if defined(HW_OOB) || defined(FORCE_WOWLAN)\r
-void\r
-dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)\r
-{\r
-       uint32 gpiocontrol, addr;\r
-\r
-       if (CHIPID(chip) == BCM43362_CHIP_ID) {\r
-               printf("%s: Enable HW OOB for 43362\n", __FUNCTION__);\r
-               addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);\r
-               gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);\r
-               gpiocontrol |= 0x2;\r
-               bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);\r
-               bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);\r
-               bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);\r
-               bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);\r
-       }\r
-}\r
-#endif\r
-\r
-int\r
-dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac)\r
-{\r
-       int i, err = -1;\r
-       uint8 *ptr = 0;\r
-       unsigned char tpl_code, tpl_link='\0';\r
-       uint8 header[3] = {0x80, 0x07, 0x19};\r
-       uint8 *cis;\r
-\r
-       if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) {\r
-               CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__));\r
-               return err;\r
-       }\r
-       bzero(cis, SBSDIO_CIS_SIZE_LIMIT);\r
-\r
-       if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) {\r
-               CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err));\r
-               MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);\r
-               return err;\r
-       }\r
-       err = -1; // reset err;\r
-       ptr = cis;\r
-       do {\r
-               /* 0xff means we're done */\r
-               tpl_code = *ptr;\r
-               ptr++;\r
-               if (tpl_code == 0xff)\r
-                       break;\r
-\r
-               /* null entries have no link field or data */\r
-               if (tpl_code == 0x00)\r
-                       continue;\r
-\r
-               tpl_link = *ptr;\r
-               ptr++;\r
-               /* a size of 0xff also means we're done */\r
-               if (tpl_link == 0xff)\r
-                       break;\r
-               if (config_msg_level & CONFIG_TRACE_LEVEL) {\r
-                       printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n",\r
-                               __FUNCTION__, tpl_code, tpl_link, *ptr);\r
-                       printk("%s: value:", __FUNCTION__);\r
-                       for (i=0; i<tpl_link-1; i++) {\r
-                               printk("%02x ", ptr[i+1]);\r
-                               if ((i+1) % 16 == 0)\r
-                                       printk("\n");\r
-                       }\r
-                       printk("\n");\r
-               }\r
-\r
-               if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19)\r
-                       break;\r
-\r
-               ptr += tpl_link;\r
-       } while (1);\r
-\r
-       if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19) {\r
-               /* Normal OTP */\r
-               memcpy(mac, ptr+1, 6);\r
-               err = 0;\r
-       } else {\r
-               ptr = cis;\r
-               /* Special OTP */\r
-               if (bcmsdh_reg_read(sdh, SI_ENUM_BASE, 4) == 0x16044330) {\r
-                       for (i=0; i<SBSDIO_CIS_SIZE_LIMIT; i++) {\r
-                               if (!memcmp(header, ptr, 3)) {\r
-                                       memcpy(mac, ptr+3, 6);\r
-                                       err = 0;\r
-                                       break;\r
-                               }\r
-                               ptr++;\r
-                       }\r
-               }\r
-       }\r
-\r
-       ASSERT(cis);\r
-       MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);\r
-\r
-       return err;\r
-}\r
-\r
-void\r
-dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path)\r
-{\r
-       int i, j;\r
-       uint8 mac[6]={0};\r
-       int fw_num=0, mac_num=0;\r
-       uint32 oui, nic;\r
-       wl_mac_list_t *mac_list;\r
-       wl_mac_range_t *mac_range;\r
-       char *pfw_name;\r
-       int fw_type, fw_type_new;\r
-\r
-       mac_list = dhd->conf->fw_by_mac.m_mac_list_head;\r
-       fw_num = dhd->conf->fw_by_mac.count;\r
-       if (!mac_list || !fw_num)\r
-               return;\r
-\r
-       if (dhd_conf_get_mac(dhd, sdh, mac)) {\r
-               CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));\r
-               return;\r
-       }\r
-       oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);\r
-       nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(fw_path);\r
-       while (i > 0) {\r
-               if (fw_path[i] == '/') break;\r
-               i--;\r
-       }\r
-       pfw_name = &fw_path[i+1];\r
-       fw_type = (strstr(pfw_name, "_mfg") ?\r
-               FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ?\r
-               FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ?\r
-               FW_TYPE_P2P : FW_TYPE_STA)));\r
-\r
-       for (i=0; i<fw_num; i++) {\r
-               mac_num = mac_list[i].count;\r
-               mac_range = mac_list[i].mac;\r
-               fw_type_new = (strstr(mac_list[i].name, "_mfg") ?\r
-                       FW_TYPE_MFG : (strstr(mac_list[i].name, "_apsta") ?\r
-                       FW_TYPE_APSTA : (strstr(mac_list[i].name, "_p2p") ?\r
-                       FW_TYPE_P2P : FW_TYPE_STA)));\r
-               if (fw_type != fw_type_new) {\r
-                       printf("%s: fw_typ=%d != fw_type_new=%d\n", __FUNCTION__, fw_type, fw_type_new);\r
-                       continue;\r
-               }\r
-               for (j=0; j<mac_num; j++) {\r
-                       if (oui == mac_range[j].oui) {\r
-                               if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {\r
-                                       strcpy(pfw_name, mac_list[i].name);\r
-                                       printf("%s: matched oui=0x%06X, nic=0x%06X\n",\r
-                                               __FUNCTION__, oui, nic);\r
-                                       printf("%s: fw_path=%s\n", __FUNCTION__, fw_path);\r
-                                       return;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void\r
-dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)\r
-{\r
-       int i, j;\r
-       uint8 mac[6]={0};\r
-       int nv_num=0, mac_num=0;\r
-       uint32 oui, nic;\r
-       wl_mac_list_t *mac_list;\r
-       wl_mac_range_t *mac_range;\r
-       char *pnv_name;\r
-\r
-       mac_list = dhd->conf->nv_by_mac.m_mac_list_head;\r
-       nv_num = dhd->conf->nv_by_mac.count;\r
-       if (!mac_list || !nv_num)\r
-               return;\r
-\r
-       if (dhd_conf_get_mac(dhd, sdh, mac)) {\r
-               CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));\r
-               return;\r
-       }\r
-       oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);\r
-       nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(nv_path);\r
-       while (i > 0) {\r
-               if (nv_path[i] == '/') break;\r
-               i--;\r
-       }\r
-       pnv_name = &nv_path[i+1];\r
-\r
-       for (i=0; i<nv_num; i++) {\r
-               mac_num = mac_list[i].count;\r
-               mac_range = mac_list[i].mac;\r
-               for (j=0; j<mac_num; j++) {\r
-                       if (oui == mac_range[j].oui) {\r
-                               if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {\r
-                                       strcpy(pnv_name, mac_list[i].name);\r
-                                       printf("%s: matched oui=0x%06X, nic=0x%06X\n",\r
-                                               __FUNCTION__, oui, nic);\r
-                                       printf("%s: nv_path=%s\n", __FUNCTION__, nv_path);\r
-                                       return;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-#endif\r
-\r
-void\r
-dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)\r
-{\r
-       int fw_type, ag_type;\r
-       uint chip, chiprev;\r
-       int i;\r
-       char fw_tail[20];\r
-\r
-       chip = dhd->conf->chip;\r
-       chiprev = dhd->conf->chiprev;\r
-\r
-       if (fw_path[0] == '\0') {\r
-#ifdef CONFIG_BCMDHD_FW_PATH\r
-               bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);\r
-               if (fw_path[0] == '\0')\r
-#endif\r
-               {\r
-                       printf("firmware path is null\n");\r
-                       return;\r
-               }\r
-       }\r
-#ifndef FW_PATH_AUTO_SELECT\r
-       return;\r
-#endif\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(fw_path);\r
-       while (i > 0) {\r
-               if (fw_path[i] == '/') break;\r
-               i--;\r
-       }\r
-#ifdef BAND_AG\r
-       ag_type = FW_TYPE_AG;\r
-#else\r
-       ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;\r
-#endif\r
-       fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG :\r
-               (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA :\r
-               (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P :\r
-               (strstr(&fw_path[i], "_es") ? FW_TYPE_ES :\r
-               FW_TYPE_STA))));\r
-\r
-       if (fw_type == FW_TYPE_STA)\r
-               strcpy(fw_tail, ".bin");\r
-       else if (fw_type == FW_TYPE_APSTA)\r
-               strcpy(fw_tail, "_apsta.bin");\r
-       else if (fw_type == FW_TYPE_P2P)\r
-               strcpy(fw_tail, "_p2p.bin");\r
-       else if (fw_type == FW_TYPE_ES)\r
-               strcpy(fw_tail, "_es.bin");\r
-       else if (fw_type == FW_TYPE_MFG)\r
-               strcpy(fw_tail, "_mfg.bin");\r
-\r
-       switch (chip) {\r
-#ifdef BCMSDIO\r
-               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
-                       } else {\r
-                               if (chiprev == BCM4330B2_CHIP_REV)\r
-                                       strcpy(&fw_path[i+1], 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
-                       else\r
-                               strcpy(&fw_path[i+1], FW_BCM43362A2);\r
-                       break;\r
-               case BCM43430_CHIP_ID:\r
-                       if (chiprev == BCM43430A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43438A0);\r
-                       else if (chiprev == BCM43430A1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43438A1);\r
-                       else if (chiprev == BCM43430A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43436B0);\r
-                       break;\r
-               case BCM43012_CHIP_ID:\r
-                       if (chiprev == BCM43012B0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43012B0);\r
-               case BCM4334_CHIP_ID:\r
-                       if (chiprev == BCM4334B1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], 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
-                       break;\r
-               case BCM4324_CHIP_ID:\r
-                       if (chiprev == BCM43241B4_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM43241B4);\r
-                       break;\r
-               case BCM4335_CHIP_ID:\r
-                       if (chiprev == BCM4335A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], 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 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
-                       break;\r
-               case BCM4354_CHIP_ID:\r
-                       if (chiprev == BCM4354A1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4354A1);\r
-                       else if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], 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
-                       break;\r
-               case BCM43569_CHIP_ID:\r
-                       if (chiprev == BCM4358A3_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4358A3);\r
-                       break;\r
-               case BCM4359_CHIP_ID:\r
-                       if (chiprev == BCM4359B1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], FW_BCM4359B1);\r
-                       else if (chiprev == BCM4359C0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], 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
-                       break;\r
-#endif\r
-               default:\r
-                       strcpy(&fw_path[i+1], "fw_bcmdhd");\r
-       }\r
-       strcat(fw_path, fw_tail);\r
-\r
-       CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path));\r
-}\r
-\r
-void\r
-dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)\r
-{\r
-       uint chip, chiprev;\r
-       int i;\r
-       char fw_tail[20];\r
-\r
-       chip = dhd->conf->chip;\r
-       chiprev = dhd->conf->chiprev;\r
-\r
-       if (clm_path[0] == '\0') {\r
-               printf("clm path is null\n");\r
-               return;\r
-       }\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(clm_path);\r
-       while (i > 0) {\r
-               if (clm_path[i] == '/') break;\r
-               i--;\r
-       }\r
-\r
-       strcpy(fw_tail, ".blob");\r
-\r
-       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
-                       break;\r
-#endif\r
-               default:\r
-                       strcpy(&clm_path[i+1], "clm_bcmdhd");\r
-       }\r
-       strcat(clm_path, fw_tail);\r
-\r
-       CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_path));\r
-}\r
-\r
-void\r
-dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)\r
-{\r
-       int matched=-1;\r
-       uint chip, chiprev;\r
-       int i;\r
-\r
-       chip = dhd->conf->chip;\r
-       chiprev = dhd->conf->chiprev;\r
-\r
-       for (i=0; i<dhd->conf->nv_by_chip.count; i++) {\r
-               if (chip==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&\r
-                               chiprev==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {\r
-                       matched = i;\r
-                       break;\r
-               }\r
-       }\r
-       if (matched < 0)\r
-               return;\r
-\r
-       if (nv_path[0] == '\0') {\r
-#ifdef CONFIG_BCMDHD_NVRAM_PATH\r
-               bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);\r
-               if (nv_path[0] == '\0')\r
-#endif\r
-               {\r
-                       printf("nvram path is null\n");\r
-                       return;\r
-               }\r
-       }\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(nv_path);\r
+#define dtohchanspec(i) i
+
+#ifdef BCMSDIO
+void
+dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)
+{
+       int i;
+
+       CONFIG_TRACE(("%s called\n", __FUNCTION__));
+       if (mac_list->m_mac_list_head) {
+               for (i=0; i<mac_list->count; i++) {
+                       if (mac_list->m_mac_list_head[i].mac) {
+                               CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac));
+                               kfree(mac_list->m_mac_list_head[i].mac);
+                       }
+               }
+               CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head));
+               kfree(mac_list->m_mac_list_head);
+       }
+       mac_list->count = 0;
+}
+
+void
+dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)
+{
+       CONFIG_TRACE(("%s called\n", __FUNCTION__));
+
+       if (chip_nv_list->m_chip_nv_path_head) {
+               CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head));
+               kfree(chip_nv_list->m_chip_nv_path_head);
+       }
+       chip_nv_list->count = 0;
+}
+
+#if defined(HW_OOB) || defined(FORCE_WOWLAN)
+void
+dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)
+{
+       uint32 gpiocontrol, addr;
+
+       if (CHIPID(chip) == BCM43362_CHIP_ID) {
+               printf("%s: Enable HW OOB for 43362\n", __FUNCTION__);
+               addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);
+               gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);
+               gpiocontrol |= 0x2;
+               bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);
+               bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);
+               bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);
+               bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);
+       }
+}
+#endif
+
+int
+dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac)
+{
+       int i, err = -1;
+       uint8 *ptr = 0;
+       unsigned char tpl_code, tpl_link='\0';
+       uint8 header[3] = {0x80, 0x07, 0x19};
+       uint8 *cis;
+
+       if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) {
+               CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__));
+               return err;
+       }
+       bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
+
+       if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) {
+               CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err));
+               MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
+               return err;
+       }
+       err = -1; // reset err;
+       ptr = cis;
+       do {
+               /* 0xff means we're done */
+               tpl_code = *ptr;
+               ptr++;
+               if (tpl_code == 0xff)
+                       break;
+
+               /* null entries have no link field or data */
+               if (tpl_code == 0x00)
+                       continue;
+
+               tpl_link = *ptr;
+               ptr++;
+               /* a size of 0xff also means we're done */
+               if (tpl_link == 0xff)
+                       break;
+               if (config_msg_level & CONFIG_TRACE_LEVEL) {
+                       printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n",
+                               __FUNCTION__, tpl_code, tpl_link, *ptr);
+                       printk("%s: value:", __FUNCTION__);
+                       for (i=0; i<tpl_link-1; i++) {
+                               printk("%02x ", ptr[i+1]);
+                               if ((i+1) % 16 == 0)
+                                       printk("\n");
+                       }
+                       printk("\n");
+               }
+
+               if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19)
+                       break;
+
+               ptr += tpl_link;
+       } while (1);
+
+       if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19) {
+               /* Normal OTP */
+               memcpy(mac, ptr+1, 6);
+               err = 0;
+       } else {
+               ptr = cis;
+               /* Special OTP */
+               if (bcmsdh_reg_read(sdh, SI_ENUM_BASE, 4) == 0x16044330) {
+                       for (i=0; i<SBSDIO_CIS_SIZE_LIMIT; i++) {
+                               if (!memcmp(header, ptr, 3)) {
+                                       memcpy(mac, ptr+3, 6);
+                                       err = 0;
+                                       break;
+                               }
+                               ptr++;
+                       }
+               }
+       }
+
+       ASSERT(cis);
+       MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
+
+       return err;
+}
+
+void
+dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path)
+{
+       int i, j;
+       uint8 mac[6]={0};
+       int fw_num=0, mac_num=0;
+       uint32 oui, nic;
+       wl_mac_list_t *mac_list;
+       wl_mac_range_t *mac_range;
+       char *pfw_name;
+       int fw_type, fw_type_new;
+
+       mac_list = dhd->conf->fw_by_mac.m_mac_list_head;
+       fw_num = dhd->conf->fw_by_mac.count;
+       if (!mac_list || !fw_num)
+               return;
+
+       if (dhd_conf_get_mac(dhd, sdh, mac)) {
+               CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));
+               return;
+       }
+       oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
+       nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
+
+       /* find out the last '/' */
+       i = strlen(fw_path);
+       while (i > 0) {
+               if (fw_path[i] == '/') break;
+               i--;
+       }
+       pfw_name = &fw_path[i+1];
+       fw_type = (strstr(pfw_name, "_mfg") ?
+               FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ?
+               FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ?
+               FW_TYPE_P2P : FW_TYPE_STA)));
+
+       for (i=0; i<fw_num; i++) {
+               mac_num = mac_list[i].count;
+               mac_range = mac_list[i].mac;
+               fw_type_new = (strstr(mac_list[i].name, "_mfg") ?
+                       FW_TYPE_MFG : (strstr(mac_list[i].name, "_apsta") ?
+                       FW_TYPE_APSTA : (strstr(mac_list[i].name, "_p2p") ?
+                       FW_TYPE_P2P : FW_TYPE_STA)));
+               if (fw_type != fw_type_new) {
+                       printf("%s: fw_typ=%d != fw_type_new=%d\n", __FUNCTION__, fw_type, fw_type_new);
+                       continue;
+               }
+               for (j=0; j<mac_num; j++) {
+                       if (oui == mac_range[j].oui) {
+                               if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
+                                       strcpy(pfw_name, mac_list[i].name);
+                                       printf("%s: matched oui=0x%06X, nic=0x%06X\n",
+                                               __FUNCTION__, oui, nic);
+                                       printf("%s: fw_path=%s\n", __FUNCTION__, fw_path);
+                                       return;
+                               }
+                       }
+               }
+       }
+}
+
+void
+dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)
+{
+       int i, j;
+       uint8 mac[6]={0};
+       int nv_num=0, mac_num=0;
+       uint32 oui, nic;
+       wl_mac_list_t *mac_list;
+       wl_mac_range_t *mac_range;
+       char *pnv_name;
+
+       mac_list = dhd->conf->nv_by_mac.m_mac_list_head;
+       nv_num = dhd->conf->nv_by_mac.count;
+       if (!mac_list || !nv_num)
+               return;
+
+       if (dhd_conf_get_mac(dhd, sdh, mac)) {
+               CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));
+               return;
+       }
+       oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
+       nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
+
+       /* find out the last '/' */
+       i = strlen(nv_path);
+       while (i > 0) {
+               if (nv_path[i] == '/') break;
+               i--;
+       }
+       pnv_name = &nv_path[i+1];
+
+       for (i=0; i<nv_num; i++) {
+               mac_num = mac_list[i].count;
+               mac_range = mac_list[i].mac;
+               for (j=0; j<mac_num; j++) {
+                       if (oui == mac_range[j].oui) {
+                               if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
+                                       strcpy(pnv_name, mac_list[i].name);
+                                       printf("%s: matched oui=0x%06X, nic=0x%06X\n",
+                                               __FUNCTION__, oui, nic);
+                                       printf("%s: nv_path=%s\n", __FUNCTION__, nv_path);
+                                       return;
+                               }
+                       }
+               }
+       }
+}
+#endif
+
+void
+dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
+{
+       int fw_type, ag_type;
+       uint chip, chiprev;
+       int i;
+       char fw_tail[20];
+
+       chip = dhd->conf->chip;
+       chiprev = dhd->conf->chiprev;
+
+       if (fw_path[0] == '\0') {
+#ifdef CONFIG_BCMDHD_FW_PATH
+               bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
+               if (fw_path[0] == '\0')
+#endif
+               {
+                       printf("firmware path is null\n");
+                       return;
+               }
+       }
+#ifndef FW_PATH_AUTO_SELECT
+       return;
+#endif
+
+       /* find out the last '/' */
+       i = strlen(fw_path);
        while (i > 0) {
-               if (nv_path[i] == '/') break;\r
-               i--;\r
-       }\r
-\r
-       strcpy(&nv_path[i+1], 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
-\r
-void\r
-dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path)\r
-{\r
-       int i;\r
-\r
-       if (src_path[0] == '\0') {\r
-               printf("src_path is null\n");\r
-               return;\r
-       } else\r
-               strcpy(dst_path, src_path);\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(dst_path);\r
+               if (fw_path[i] == '/') break;
+               i--;
+       }
+#ifdef BAND_AG
+       ag_type = FW_TYPE_AG;
+#else
+       ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;
+#endif
+       fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG :
+               (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA :
+               (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P :
+               (strstr(&fw_path[i], "_es") ? FW_TYPE_ES :
+               FW_TYPE_STA))));
+
+       if (fw_type == FW_TYPE_STA)
+               strcpy(fw_tail, ".bin");
+       else if (fw_type == FW_TYPE_APSTA)
+               strcpy(fw_tail, "_apsta.bin");
+       else if (fw_type == FW_TYPE_P2P)
+               strcpy(fw_tail, "_p2p.bin");
+       else if (fw_type == FW_TYPE_ES)
+               strcpy(fw_tail, "_es.bin");
+       else if (fw_type == FW_TYPE_MFG)
+               strcpy(fw_tail, "_mfg.bin");
+
+       switch (chip) {
+#ifdef BCMSDIO
+               case BCM4330_CHIP_ID:
+                       if (ag_type == FW_TYPE_G) {
+                               if (chiprev == BCM4330B2_CHIP_REV)
+                                       strcpy(&fw_path[i+1], FW_BCM4330B2);
+                       } else {
+                               if (chiprev == BCM4330B2_CHIP_REV)
+                                       strcpy(&fw_path[i+1], FW_BCM4330B2_AG);
+                       }
+                       break;
+               case BCM43362_CHIP_ID:
+                       if (chiprev == BCM43362A0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43362A0);
+                       else
+                               strcpy(&fw_path[i+1], FW_BCM43362A2);
+                       break;
+               case BCM43430_CHIP_ID:
+                       if (chiprev == BCM43430A0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43438A0);
+                       else if (chiprev == BCM43430A1_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43438A1);
+                       else if (chiprev == BCM43430A2_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43436B0);
+                       break;
+               case BCM43012_CHIP_ID:
+                       if (chiprev == BCM43012B0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43012B0);
+                       break;
+               case BCM4334_CHIP_ID:
+                       if (chiprev == BCM4334B1_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4334B1);
+                       break;
+               case BCM43340_CHIP_ID:
+               case BCM43341_CHIP_ID:
+                       if (chiprev == BCM43341B0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43341B1);
+                       break;
+               case BCM4324_CHIP_ID:
+                       if (chiprev == BCM43241B4_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43241B4);
+                       break;
+               case BCM4335_CHIP_ID:
+                       if (chiprev == BCM4335A0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4339A0);
+                       break;
+               case BCM4339_CHIP_ID:
+                       if (chiprev == BCM4339A0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4339A0);
+                       break;
+               case BCM43454_CHIP_ID:
+                       if (chiprev == BCM43455C0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43455C0);
+                       break;
+               case BCM4345_CHIP_ID:
+                       if (chiprev == BCM43455C0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43455C0);
+                       else if (chiprev == BCM43456C5_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM43456C5);
+                       break;
+               case BCM4354_CHIP_ID:
+                       if (chiprev == BCM4354A1_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4354A1);
+                       else if (chiprev == BCM4356A2_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4356A2);
+                       break;
+               case BCM4356_CHIP_ID:
+               case BCM4371_CHIP_ID:
+                       if (chiprev == BCM4356A2_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4356A2);
+                       break;
+               case BCM43569_CHIP_ID:
+                       if (chiprev == BCM4358A3_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4358A3);
+                       break;
+               case BCM4359_CHIP_ID:
+                       if (chiprev == BCM4359B1_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4359B1);
+                       else if (chiprev == BCM4359C0_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4359C0);
+                       break;
+#endif
+#ifdef BCMPCIE
+               case BCM4354_CHIP_ID:
+               case BCM4356_CHIP_ID:
+                       if (chiprev == BCM4356A2_CHIP_REV)
+                               strcpy(&fw_path[i+1], FW_BCM4356A2);
+                       break;
+#endif
+               default:
+                       strcpy(&fw_path[i+1], "fw_bcmdhd");
+       }
+       strcat(fw_path, fw_tail);
+
+       CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path));
+}
+
+void
+dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
+{
+       uint chip, chiprev;
+       int i;
+       char fw_tail[20];
+
+       chip = dhd->conf->chip;
+       chiprev = dhd->conf->chiprev;
+
+       if (clm_path[0] == '\0') {
+               printf("clm path is null\n");
+               return;
+       }
+
+       /* find out the last '/' */
+       i = strlen(clm_path);
        while (i > 0) {
-               if (dst_path[i] == '/') break;\r
-               i--;\r
-       }\r
-       strcpy(&dst_path[i+1], dst_name);\r
-\r
-       CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));\r
-}\r
-\r
-#ifdef CONFIG_PATH_AUTO_SELECT\r
-void\r
-dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)\r
-{\r
-       uint chip, chiprev;\r
-       int i;\r
-\r
-       chip = dhd->conf->chip;\r
-       chiprev = dhd->conf->chiprev;\r
-\r
-       if (conf_path[0] == '\0') {\r
-               printf("config path is null\n");\r
-               return;\r
-       }\r
-\r
-       /* find out the last '/' */\r
-       i = strlen(conf_path);\r
-       while (i > 0) {\r
-               if (conf_path[i] == '/') break;\r
-               i--;\r
-       }\r
-\r
-       switch (chip) {\r
-#ifdef BCMSDIO\r
-               case BCM4330_CHIP_ID:\r
-                       if (chiprev == BCM4330B2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4330B2);\r
-                       break;\r
-               case BCM43362_CHIP_ID:\r
-                       if (chiprev == BCM43362A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43362A0);\r
-                       else\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43362A2);\r
-                       break;\r
-               case BCM43430_CHIP_ID:\r
-                       if (chiprev == BCM43430A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43438A0);\r
-                       else if (chiprev == BCM43430A1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43438A1);\r
-                       else if (chiprev == BCM43430A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43436B0);\r
-                       break;\r
-               case BCM4334_CHIP_ID:\r
-                       if (chiprev == BCM4334B1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], 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
-                       break;\r
-               case BCM4324_CHIP_ID:\r
-                       if (chiprev == BCM43241B4_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM43241B4);\r
-                       break;\r
-               case BCM4335_CHIP_ID:\r
-                       if (chiprev == BCM4335A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], 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
-                       break;\r
-               case BCM4339_CHIP_ID:\r
-                       if (chiprev == BCM4339A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4339A0);\r
-                       break;\r
-               case BCM4354_CHIP_ID:\r
-                       if (chiprev == BCM4354A1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4354A1);\r
-                       else if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], 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
-                       break;\r
-               case BCM43569_CHIP_ID:\r
-                       if (chiprev == BCM4358A3_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4358A3);\r
-                       break;\r
-               case BCM4359_CHIP_ID:\r
-                       if (chiprev == BCM4359B1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], CONFIG_BCM4359B1);\r
-                       else if (chiprev == BCM4359C0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], 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
-                       break;\r
-#endif\r
-       }\r
-\r
-       CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path));\r
-}\r
-#endif\r
-\r
-int\r
-dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,\r
-       int def, bool down)\r
-{\r
-       int ret = -1;\r
-       char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */\r
-\r
-       if (val >= def) {\r
-               if (down) {\r
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));\r
-               }\r
-               if (cmd == WLC_SET_VAR) {\r
-                       printf("%s: set %s %d\n", __FUNCTION__, name, val);\r
-                       bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));\r
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-               } else {\r
-                       printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);\r
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-               }\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,\r
-       int len, bool down)\r
-{\r
-       char iovbuf[WLC_IOCTL_SMLEN];\r
-       int ret = -1;\r
-\r
-       if (down) {\r
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));\r
-       }\r
-\r
-       if (cmd == WLC_SET_VAR) {\r
-               bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));\r
-               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-       } else {\r
-               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-int\r
-dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)\r
-{\r
-       char iovbuf[WLC_IOCTL_SMLEN];\r
-       int ret = -1;\r
-\r
-       if (cmd == WLC_GET_VAR) {\r
-               if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {\r
-                       ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);\r
-                       if (!ret) {\r
-                               memcpy(buf, iovbuf, len);\r
-                       } else {\r
-                               CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));\r
-                       }\r
-               } else {\r
-                       CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));\r
-               }\r
-       } else {\r
-               ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);\r
-               if (ret < 0)\r
-                       CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-uint\r
-dhd_conf_get_band(dhd_pub_t *dhd)\r
-{\r
-       uint band = WLC_BAND_AUTO;\r
-\r
-       if (dhd && dhd->conf)\r
-               band = dhd->conf->band;\r
-       else\r
-               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\r
-\r
-       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
-       int bcmerror = -1;\r
-\r
-       memset(cspec, 0, sizeof(wl_country_t));\r
-       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
-{\r
-       int bcmerror = -1, i;\r
-       struct dhd_conf *conf = dhd->conf;\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
-                       printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
-                       return 0;\r
-               }\r
-       }\r
-\r
-       return bcmerror;\r
-}\r
-\r
-int\r
-dhd_conf_fix_country(dhd_pub_t *dhd)\r
-{\r
-       int bcmerror = -1;\r
-       uint band;\r
-       wl_uint32_list_t *list;\r
-       u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
-\r
-       if (!(dhd && dhd->conf)) {\r
-               return bcmerror;\r
-       }\r
-
-       memset(valid_chan_list, 0, sizeof(valid_chan_list));\r
+               if (clm_path[i] == '/') break;
+               i--;
+       }
+
+       strcpy(fw_tail, ".blob");
+
+       switch (chip) {
+#ifdef BCMSDIO
+               case BCM43012_CHIP_ID:
+                       if (chiprev == BCM43012B0_CHIP_REV)
+                               strcpy(&clm_path[i+1], CLM_BCM43012B0);
+                       break;
+#endif
+               default:
+                       strcpy(&clm_path[i+1], "clm_bcmdhd");
+       }
+       strcat(clm_path, fw_tail);
+
+       CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_path));
+}
+
+void
+dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
+{
+       int matched=-1;
+       uint chip, chiprev;
+       int i;
+
+       chip = dhd->conf->chip;
+       chiprev = dhd->conf->chiprev;
+
+       for (i=0; i<dhd->conf->nv_by_chip.count; i++) {
+               if (chip == dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&
+                               chiprev == dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {
+                       matched = i;
+                       break;
+               }
+       }
+       if (matched < 0)
+               return;
+
+       if (nv_path[0] == '\0') {
+#ifdef CONFIG_BCMDHD_NVRAM_PATH
+               bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
+               if (nv_path[0] == '\0')
+#endif
+               {
+                       printf("nvram path is null\n");
+                       return;
+               }
+       }
+
+       /* find out the last '/' */
+       i = strlen(nv_path);
+       while (i > 0) {
+               if (nv_path[i] == '/') break;
+               i--;
+       }
+
+       strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);
+
+       CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path));
+}
+
+void
+dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path)
+{
+       int i;
+
+       if (src_path[0] == '\0') {
+               printf("src_path is null\n");
+               return;
+       } else
+               strcpy(dst_path, src_path);
+
+       /* find out the last '/' */
+       i = strlen(dst_path);
+       while (i > 0) {
+               if (dst_path[i] == '/') break;
+               i--;
+       }
+       strcpy(&dst_path[i+1], dst_name);
+
+       CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));
+}
+
+#ifdef CONFIG_PATH_AUTO_SELECT
+void
+dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
+{
+       uint chip, chiprev;
+       int i;
+
+       chip = dhd->conf->chip;
+       chiprev = dhd->conf->chiprev;
+
+       if (conf_path[0] == '\0') {
+               printf("config path is null\n");
+               return;
+       }
+
+       /* find out the last '/' */
+       i = strlen(conf_path);
+       while (i > 0) {
+               if (conf_path[i] == '/') break;
+               i--;
+       }
+
+       switch (chip) {
+#ifdef BCMSDIO
+               case BCM4330_CHIP_ID:
+                       if (chiprev == BCM4330B2_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4330B2);
+                       break;
+               case BCM43362_CHIP_ID:
+                       if (chiprev == BCM43362A0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43362A0);
+                       else
+                               strcpy(&conf_path[i+1], CONFIG_BCM43362A2);
+                       break;
+               case BCM43430_CHIP_ID:
+                       if (chiprev == BCM43430A0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43438A0);
+                       else if (chiprev == BCM43430A1_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43438A1);
+                       else if (chiprev == BCM43430A2_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43436B0);
+                       break;
+               case BCM4334_CHIP_ID:
+                       if (chiprev == BCM4334B1_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4334B1);
+                       break;
+               case BCM43340_CHIP_ID:
+               case BCM43341_CHIP_ID:
+                       if (chiprev == BCM43341B0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43341B0);
+                       break;
+               case BCM4324_CHIP_ID:
+                       if (chiprev == BCM43241B4_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43241B4);
+                       break;
+               case BCM4335_CHIP_ID:
+                       if (chiprev == BCM4335A0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
+                       break;
+               case BCM43454_CHIP_ID:
+                       if (chiprev == BCM43455C0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43454C0);
+                       break;
+               case BCM4345_CHIP_ID:
+                       if (chiprev == BCM43455C0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43455C0);
+                       else if (chiprev == BCM43456C5_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM43456C5);
+                       break;
+               case BCM4339_CHIP_ID:
+                       if (chiprev == BCM4339A0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
+                       break;
+               case BCM4354_CHIP_ID:
+                       if (chiprev == BCM4354A1_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4354A1);
+                       else if (chiprev == BCM4356A2_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
+                       break;
+               case BCM4356_CHIP_ID:
+               case BCM4371_CHIP_ID:
+                       if (chiprev == BCM4356A2_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
+                       break;
+               case BCM43569_CHIP_ID:
+                       if (chiprev == BCM4358A3_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4358A3);
+                       break;
+               case BCM4359_CHIP_ID:
+                       if (chiprev == BCM4359B1_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4359B1);
+                       else if (chiprev == BCM4359C0_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4359C0);
+                       break;
+#endif
+#ifdef BCMPCIE
+               case BCM4354_CHIP_ID:
+               case BCM4356_CHIP_ID:
+                       if (chiprev == BCM4356A2_CHIP_REV)
+                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
+                       break;
+#endif
+       }
+
+       CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path));
+}
+#endif
+
+int
+dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,
+       int def, bool down)
+{
+       int ret = -1;
+       char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */
+
+       if (val >= def) {
+               if (down) {
+                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
+                               CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
+               }
+               if (cmd == WLC_SET_VAR) {
+                       printf("%s: set %s %d\n", __FUNCTION__, name, val);
+                       bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));
+                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+               } else {
+                       printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);
+                       if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)
+                               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+               }
+       }
+
+       return ret;
+}
+
+int
+dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,
+       int len, bool down)
+{
+       char iovbuf[WLC_IOCTL_SMLEN];
+       int ret = -1;
+
+       if (down) {
+               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
+                       CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
+       }
+
+       if (cmd == WLC_SET_VAR) {
+               bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));
+               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+       } else {
+               if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)
+                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
+       }
+
+       return ret;
+}
+
+int
+dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)
+{
+       char iovbuf[WLC_IOCTL_SMLEN];
+       int ret = -1;
+
+       if (cmd == WLC_GET_VAR) {
+               if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
+                       ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);
+                       if (!ret) {
+                               memcpy(buf, iovbuf, len);
+                       } else {
+                               CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
+                       }
+               } else {
+                       CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));
+               }
+       } else {
+               ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);
+               if (ret < 0)
+                       CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
+       }
+
+       return ret;
+}
+
+uint
+dhd_conf_get_band(dhd_pub_t *dhd)
+{
+       uint band = WLC_BAND_AUTO;
+
+       if (dhd && dhd->conf)
+               band = dhd->conf->band;
+       else
+               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
+
+       return band;
+}
+
+int
+dhd_conf_set_country(dhd_pub_t *dhd)
+{
+       int bcmerror = -1;
+
+       memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
+       printf("%s: set country %s, revision %d\n", __FUNCTION__,
+               dhd->conf->cspec.ccode, dhd->conf->cspec.rev);
+       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);
+
+       return bcmerror;
+}
+
+int
+dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+       int bcmerror = -1;
+
+       memset(cspec, 0, sizeof(wl_country_t));
+       bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));
+       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)
+               CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));
+       else
+               printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
+
+       return bcmerror;
+}
+
+int
+dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+       int bcmerror = -1, i;
+       struct dhd_conf *conf = dhd->conf;
+
+       for (i = 0; i < conf->country_list.count; i++) {
+               if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) {
+                       memcpy(cspec->ccode,
+                               conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);
+                       cspec->rev = conf->country_list.cspec[i].rev;
+                       printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
+                       return 0;
+               }
+       }
+
+       return bcmerror;
+}
+
+int
+dhd_conf_fix_country(dhd_pub_t *dhd)
+{
+       int bcmerror = -1;
+       uint band;
+       wl_uint32_list_t *list;
+       u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+
+       if (!(dhd && dhd->conf)) {
+               return bcmerror;
+       }
+
+       memset(valid_chan_list, 0, sizeof(valid_chan_list));
        list = (wl_uint32_list_t *)(void *) valid_chan_list;
        list->count = htod32(WL_NUMCHANNELS);
-       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {\r
-               CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));\r
-       }\r
-\r
-       band = dhd_conf_get_band(dhd);\r
-\r
-       if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) &&\r
-                       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
-               }\r
-       }\r
-\r
-       return bcmerror;\r
-}\r
-\r
-bool\r
-dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)\r
-{\r
-       int i;\r
-       bool match = false;\r
-\r
-       if (dhd && dhd->conf) {\r
-               if (dhd->conf->channels.count == 0)\r
-                       return true;\r
-               for (i=0; i<dhd->conf->channels.count; i++) {\r
-                       if (channel == dhd->conf->channels.channel[i])\r
-                               match = true;\r
-               }\r
-       } else {\r
-               match = true;\r
-               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\r
-       }\r
-\r
-       return match;\r
-}\r
-\r
-int\r
-dhd_conf_set_roam(dhd_pub_t *dhd)\r
-{\r
-       int bcmerror = -1;\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       dhd_roam_disable = conf->roam_off;\r
-       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);\r
-\r
-       if (!conf->roam_off || !conf->roam_off_suspend) {\r
-               printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",\r
-                               (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);\r
-\r
-               printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",\r
-                               (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);\r
-\r
-               printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",\r
-                               (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);\r
-\r
-               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);\r
-       }\r
-\r
-       return bcmerror;\r
-}\r
-\r
-void\r
-dhd_conf_set_bw_cap(dhd_pub_t *dhd)\r
-{\r
-       struct {\r
-               u32 band;\r
-               u32 bw_cap;\r
-       } param = {0, 0};\r
-\r
-       if (dhd->conf->bw_cap_2g >= 0) {\r
-               param.band = WLC_BAND_2G;\r
-               param.bw_cap = (uint)dhd->conf->bw_cap_2g;\r
-               printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);\r
-       }\r
-\r
-       if (dhd->conf->bw_cap_5g >= 0) {\r
-               param.band = WLC_BAND_5G;\r
-               param.bw_cap = (uint)dhd->conf->bw_cap_5g;\r
-               printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);\r
-       }\r
-}\r
-\r
-void\r
-dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp)\r
-{\r
-       int bcmerror = -1;\r
-       char iovbuf[WLC_IOCTL_SMLEN];\r
-       edcf_acparam_t *acparam;\r
-\r
-       bzero(iovbuf, sizeof(iovbuf));\r
-\r
-       /*\r
-        * Get current acparams, using buf as an input buffer.\r
-        * Return data is array of 4 ACs of wme params.\r
-        */\r
-       if (mode == 0)\r
-               bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));\r
-       else\r
-               bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf));\r
-       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {\r
-               CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));\r
-               return;\r
-       }\r
-       memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);\r
-\r
-       acparam = &acp[AC_BK];\r
-       CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-       acparam = &acp[AC_BE];\r
-       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-       acparam = &acp[AC_VI];\r
-       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-       acparam = &acp[AC_VO];\r
-       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__,\r
-               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
-               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acparam->TXOP));\r
-\r
-       return;\r
-}\r
-\r
-void\r
-dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci)\r
-{\r
-       int aifsn, ecwmin, ecwmax, txop;\r
-       edcf_acparam_t *acp;\r
-       struct dhd_conf *conf = dhd->conf;\r
-       wme_param_t *wme;\r
-\r
-       if (mode == 0)\r
-               wme = &conf->wme_sta;\r
-       else\r
-               wme = &conf->wme_ap;\r
-\r
-       /* Default value */\r
-       aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;\r
-       ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;\r
-       ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;\r
-       txop = acparam_cur->TXOP;\r
-\r
-       /* Modified value */\r
-       if (wme->aifsn[aci] > 0)\r
-               aifsn = wme->aifsn[aci];\r
-       if (wme->ecwmin[aci] > 0)\r
-               ecwmin = wme->ecwmin[aci];\r
-       if (wme->ecwmax[aci] > 0)\r
-               ecwmax = wme->ecwmax[aci];\r
-       if (wme->txop[aci] > 0)\r
-               txop = wme->txop[aci];\r
-\r
-       if (!(wme->aifsn[aci] || wme->ecwmin[aci] ||\r
-                       wme->ecwmax[aci] || wme->txop[aci]))\r
-               return;\r
-\r
-       /* Update */\r
-       acp = acparam_cur;\r
-       acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);\r
-       acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);\r
-       acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));\r
-       acp->TXOP = txop;\r
-\r
-       printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
-               __FUNCTION__, mode?"ap":"sta",\r
-               acp->ACI, acp->ACI&EDCF_AIFSN_MASK,\r
-               acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               acp->TXOP);\r
-\r
-       /*\r
-       * Now use buf as an output buffer.\r
-       * Put WME acparams after "wme_ac\0" in buf.\r
-       * NOTE: only one of the four ACs can be set at a time.\r
-       */\r
-       if (mode == 0)\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
-       else\r
-               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
-\r
-}\r
-\r
-void\r
-dhd_conf_set_wme(dhd_pub_t *dhd, int mode)\r
-{\r
-       edcf_acparam_t acparam_cur[AC_COUNT];\r
-\r
-       if (dhd && dhd->conf) {\r
-               if (!dhd->conf->force_wme_ac) {\r
-                       CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",\r
-                               __FUNCTION__, dhd->conf->force_wme_ac));\r
-                       return;\r
-               }\r
-\r
-               CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));\r
-               dhd_conf_get_wme(dhd, mode, acparam_cur);\r
-\r
-               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK);\r
-               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE);\r
-               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI);\r
-               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO);\r
-\r
-               CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));\r
-               dhd_conf_get_wme(dhd, mode, acparam_cur);\r
-       } else {\r
-               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\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
-#define MACS "%02x%02x%02x%02x%02x%02x"\r
-\r
-       /*\r
-        * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.\r
-        *   1) dhd_master_mode=0\r
-        *   2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
-        * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)\r
-        *   1) dhd_master_mode=1\r
-        *   2) pkt_filter_del=100, 102, 103, 104, 105\r
-        *   3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E\r
-        * 3. magic pkt: magic_pkt_filter_add=141 0 1 12\r
-        * 4. Filter out netbios pkt:\r
-        *   Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089\r
-        */\r
-       for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {\r
-               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];\r
-               printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);\r
-       }\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
-               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
-               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
-               dhd->pktfilter_count += 1;\r
-       }\r
-}\r
-\r
-bool\r
-dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)\r
-{\r
-       int i;\r
-\r
-       if (dhd && dhd->conf) {\r
-               for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {\r
-                       if (id == dhd->conf->pkt_filter_del.id[i]) {\r
-                               printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);\r
-                               return true;\r
-                       }\r
-               }\r
-               return false;\r
-       }\r
-       return false;\r
-}\r
-\r
-void\r
-dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)\r
+       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {
+               CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));
+       }
+
+       band = dhd_conf_get_band(dhd);
+
+       if (bcmerror || ((band == WLC_BAND_AUTO || band == WLC_BAND_2G) &&
+                       dtoh32(list->count)<11)) {
+               CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",
+                       __FUNCTION__, bcmerror, dtoh32(list->count)));
+               if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {
+                       strcpy(dhd->conf->cspec.country_abbrev, "US");
+                       dhd->conf->cspec.rev = 0;
+                       strcpy(dhd->conf->cspec.ccode, "US");
+                       dhd_conf_set_country(dhd);
+               }
+       }
+
+       return bcmerror;
+}
+
+bool
+dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)
+{
+       int i;
+       bool match = false;
+
+       if (dhd && dhd->conf) {
+               if (dhd->conf->channels.count == 0)
+                       return true;
+               for (i=0; i<dhd->conf->channels.count; i++) {
+                       if (channel == dhd->conf->channels.channel[i])
+                               match = true;
+               }
+       } else {
+               match = true;
+               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
+       }
+
+       return match;
+}
+
+int
+dhd_conf_set_roam(dhd_pub_t *dhd)
 {
-       dhd->pktfilter_count = 6;\r
-       dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;\r
-       dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";\r
-       dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";\r
-       dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";\r
-       dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;\r
-       /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/\r
-       dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;\r
-\r
-       /* IPv4 broadcast address XXX.XXX.XXX.255 */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";\r
-       dhd->pktfilter_count++;\r
-       /* discard IPv4 multicast address 224.0.0.0/4 */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";\r
-       dhd->pktfilter_count++;\r
-       /* discard IPv6 multicast address FF00::/8 */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";\r
-       dhd->pktfilter_count++;\r
-       /* discard Netbios pkt */\r
-       dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";\r
-       dhd->pktfilter_count++;\r
-\r
-}\r
-#endif /* PKT_FILTER_SUPPORT */\r
-\r
-int\r
-dhd_conf_get_pm(dhd_pub_t *dhd)\r
-{\r
-       if (dhd && dhd->conf)\r
-               return dhd->conf->pm;\r
-       return -1;\r
-}\r
-\r
-#ifdef PROP_TXSTATUS\r
-int\r
-dhd_conf_get_disable_proptx(dhd_pub_t *dhd)\r
-{\r
-       struct dhd_conf *conf = dhd->conf;\r
-       int disable_proptx = -1;\r
-       int fw_proptx = 0;\r
-\r
-       /* check fw proptx priority:\r
-         * 1st: check fw support by wl cap\r
-         * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default\r
-         *        if you would like to disable it, please set disable_proptx=1 in config.txt\r
-         * 3th: disable when proptxstatus not support in wl cap\r
-         */\r
-       if (FW_SUPPORTED(dhd, proptxstatus)) {\r
-               fw_proptx = 1;\r
-       } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||\r
-                       dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
-               fw_proptx = 1;\r
-       } else {\r
-               fw_proptx = 0;\r
-       }\r
-\r
-       /* returned disable_proptx value:\r
-         * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)\r
-         * 0: depend on fw support\r
-         * 1: always disable proptx\r
-         */\r
-       if (conf->disable_proptx == 0) {\r
-               // check fw support as well\r
-               if (fw_proptx)\r
-                       disable_proptx = 0;\r
-               else\r
-                       disable_proptx = 1;\r
-       } else if (conf->disable_proptx >= 1) {\r
-               disable_proptx = 1;\r
-       } else {\r
-               // check fw support as well\r
-               if (fw_proptx)\r
-                       disable_proptx = -1;\r
-               else\r
-                       disable_proptx = 1;\r
-       }\r
-\r
-       printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx);\r
-\r
-       return disable_proptx;\r
-}\r
-#endif\r
-\r
-uint\r
-pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf)\r
-{\r
-       bool findNewline, changenewline=FALSE, pick=FALSE;\r
-       int column;\r
-       uint n, pick_column=0;\r
-\r
-       findNewline = FALSE;\r
-       column = 0;\r
-\r
-       if (start_pos >= len) {\r
-               CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__));\r
-               return 0;\r
-       }\r
-\r
-       for (n = start_pos; n < len; n++) {\r
-               if (varbuf[n] == '\r')\r
-                       continue;\r
-               if ((findNewline || changenewline) && varbuf[n] != '\n')\r
-                       continue;\r
-               findNewline = FALSE;\r
-               if (varbuf[n] == '#') {\r
-                       findNewline = TRUE;\r
-                       continue;\r
-               }\r
-               if (varbuf[n] == '\\') {\r
-                       changenewline = TRUE;\r
-                       continue;\r
-               }\r
-               if (!changenewline && varbuf[n] == '\n') {\r
-                       if (column == 0)\r
-                               continue;\r
-                       column = 0;\r
-                       continue;\r
-               }\r
-               if (changenewline && varbuf[n] == '\n') {\r
-                       changenewline = FALSE;\r
-                       continue;\r
-               }\r
-\r
-               if (column==0 && !pick) { // start to pick\r
-                       pick = TRUE;\r
-                       column++;\r
-                       pick_column = 0;\r
-               } else {\r
-                       if (pick && column==0) { // stop to pick\r
-                               pick = FALSE;\r
-                               break;\r
-                       } else\r
-                               column++;\r
-               }\r
-               if (pick) {\r
-                       if (varbuf[n] == 0x9)\r
-                               continue;\r
-                       if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ')\r
-                               continue;\r
-                       pickbuf[pick_column] = varbuf[n];\r
-                       pick_column++;\r
-               }\r
-       }\r
-\r
-       return n; // return current position\r
-}\r
-\r
-bool\r
-dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param)\r
-{\r
-       char *data = full_param+len_param;\r
-\r
-       if (!strncmp("dhd_msg_level=", full_param, len_param)) {\r
-               dhd_msg_level = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);\r
-       }\r
-#ifdef BCMSDIO\r
-       else if (!strncmp("sd_msglevel=", full_param, len_param)) {\r
-               sd_msglevel = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel);\r
-       }\r
-#endif\r
-       else if (!strncmp("android_msg_level=", full_param, len_param)) {\r
-               android_msg_level = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);\r
-       }\r
-       else if (!strncmp("config_msg_level=", full_param, len_param)) {\r
-               config_msg_level = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);\r
-       }\r
-#ifdef WL_CFG80211\r
-       else if (!strncmp("wl_dbg_level=", full_param, len_param)) {\r
-               wl_dbg_level = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);\r
-       }\r
-#endif\r
-#if defined(WL_WIRELESS_EXT)\r
-       else if (!strncmp("iw_msg_level=", full_param, len_param)) {\r
-               iw_msg_level = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);\r
-       }\r
-#endif\r
-#if defined(DHD_DEBUG)\r
-       else if (!strncmp("dhd_console_ms=", full_param, len_param)) {\r
-               dhd_console_ms = (int)simple_strtol(data, NULL, 0);\r
-               printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);\r
-       }\r
-#endif\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-
-void\r
-dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val)\r
-{\r
-       char *pick_tmp, *pch;\r
-\r
-       /* Process WMM parameters */\r
-       pick_tmp = pick;\r
-       pch = bcmstrstr(pick_tmp, "aifsn ");\r
-       if (pch) {\r
-               wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);\r
-               printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]);\r
-       }\r
-       pick_tmp = pick;\r
-       pch = bcmstrstr(pick_tmp, "ecwmin ");\r
-       if (pch) {\r
-               wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);\r
-               printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]);\r
-       }\r
-       pick_tmp = pick;\r
-       pch = bcmstrstr(pick_tmp, "ecwmax ");\r
-       if (pch) {\r
-               wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);\r
-               printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]);\r
-       }\r
-       pick_tmp = pick;\r
-       pch = bcmstrstr(pick_tmp, "txop ");\r
-       if (pch) {\r
-               wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);\r
-               printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]);\r
-       }\r
-\r
-}\r
-
-bool\r
-dhd_conf_read_wme_ac_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
-       // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e\r
-       // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e\r
-\r
-       /* Process WMM parameters */\r
-       if (!strncmp("force_wme_ac=", full_param, len_param)) {\r
-               conf->force_wme_ac = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);\r
-       }
-       else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE);\r
-       }\r
-       else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK);\r
-       }\r
-       else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI);\r
-       }\r
-       else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO);\r
-       }\r
-       else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE);\r
-       }\r
-       else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK);\r
-       }\r
-       else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI);\r
-       }\r
-       else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) {\r
-               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO);\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-bool\r
-dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)\r
-{\r
-       int i, j;\r
-       char *pch, *pick_tmp;\r
-       wl_mac_list_t *mac_list;\r
-       wl_mac_range_t *mac_range;\r
-       struct dhd_conf *conf = dhd->conf;\r
-       char *data = full_param+len_param;\r
-\r
-       /* Process fw_by_mac:\r
-        * fw_by_mac=[fw_mac_num] \\r
-        *  [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \\r
-        *                                    [oui1-1] [nic_start1-1] [nic_end1-1]... \\r
-        *                                    [oui1-n] [nic_start1-n] [nic_end1-n] \\r
-        *  [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \\r
-        *                                    [oui2-1] [nic_start2-1] [nic_end2-1]... \\r
-        *                                    [oui2-n] [nic_start2-n] [nic_end2-n] \\r
-        * Ex: fw_by_mac=2 \\r
-        *  fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \\r
-        *  fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \\r
-        *                           0x983B16 0x916157 0x916487\r
-        */\r
-\r
-       if (!strncmp("fw_by_mac=", full_param, len_param)) {\r
-               pick_tmp = data;\r
-               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-               conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);\r
-               if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) {\r
-                       conf->fw_by_mac.count = 0;\r
-                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
-               }\r
-               printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count);\r
-               conf->fw_by_mac.m_mac_list_head = mac_list;\r
-               for (i=0; i<conf->fw_by_mac.count; i++) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       strcpy(mac_list[i].name, pch);\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);\r
-                       printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,\r
-                               mac_list[i].name, mac_list[i].count);\r
-                       if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {\r
-                               mac_list[i].count = 0;\r
-                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
-                               break;\r
-                       }\r
-                       mac_list[i].mac = mac_range;\r
-                       for (j=0; j<mac_list[i].count; j++) {\r
-                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                               mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);\r
-                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                               mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);\r
-                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                               mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);\r
-                               printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",\r
-                                       __FUNCTION__, mac_range[j].oui,\r
-                                       mac_range[j].nic_start, mac_range[j].nic_end);\r
-                       }\r
-               }\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-bool\r
-dhd_conf_read_nv_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)\r
-{\r
-       int i, j;\r
-       char *pch, *pick_tmp;\r
-       wl_mac_list_t *mac_list;\r
-       wl_mac_range_t *mac_range;\r
-       struct dhd_conf *conf = dhd->conf;\r
-       char *data = full_param+len_param;\r
-\r
-       /* Process nv_by_mac:\r
-        * [nv_by_mac]: The same format as fw_by_mac\r
-        */\r
-       if (!strncmp("nv_by_mac=", full_param, len_param)) {\r
-               pick_tmp = data;\r
-               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-               conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);\r
-               if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) {\r
-                       conf->nv_by_mac.count = 0;\r
-                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
-               }\r
-               printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count);\r
-               conf->nv_by_mac.m_mac_list_head = mac_list;\r
-               for (i=0; i<conf->nv_by_mac.count; i++) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       strcpy(mac_list[i].name, pch);\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);\r
-                       printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,\r
-                               mac_list[i].name, mac_list[i].count);\r
-                       if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {\r
-                               mac_list[i].count = 0;\r
-                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
-                               break;\r
-                       }\r
-                       mac_list[i].mac = mac_range;\r
-                       for (j=0; j<mac_list[i].count; j++) {\r
-                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                               mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);\r
-                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                               mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);\r
-                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                               mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);\r
-                               printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",\r
-                                       __FUNCTION__, mac_range[j].oui,\r
-                                       mac_range[j].nic_start, mac_range[j].nic_end);\r
-                       }\r
-               }\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-bool\r
-dhd_conf_read_nv_by_chip(dhd_pub_t *dhd, char *full_param, uint len_param)\r
-{\r
-       int i;\r
-       char *pch, *pick_tmp;\r
-       wl_chip_nv_path_t *chip_nv_path;\r
-       struct dhd_conf *conf = dhd->conf;\r
-       char *data = full_param+len_param;\r
-\r
-       /* Process nv_by_chip:\r
-        * nv_by_chip=[nv_chip_num] \\r
-        *  [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \\r
-        * Ex: nv_by_chip=2 \\r
-        *  43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \\r
-        */\r
-       if (!strncmp("nv_by_chip=", full_param, len_param)) {\r
-               pick_tmp = data;\r
-               pch = bcmstrtok(&pick_tmp, " ", 0);\r
-               conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);\r
-               if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) {\r
-                       conf->nv_by_chip.count = 0;\r
-                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
-               }\r
-               printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count);\r
-               conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;\r
-               for (i=0; i<conf->nv_by_chip.count; i++) {\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);\r
-                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
-                       strcpy(chip_nv_path[i].name, pch);\r
-                       printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__,\r
-                               chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);\r
-               }\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-bool\r
-dhd_conf_read_roam_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("roam_off=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->roam_off = 0;\r
-               else\r
-                       conf->roam_off = 1;\r
-               printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);\r
-       }\r
-       else if (!strncmp("roam_off_suspend=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->roam_off_suspend = 0;\r
-               else\r
-                       conf->roam_off_suspend = 1;\r
-               printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend);\r
-       }\r
-       else if (!strncmp("roam_trigger=", full_param, len_param)) {\r
-               conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: roam_trigger = %d\n", __FUNCTION__,\r
-                       conf->roam_trigger[0]);\r
-       }\r
-       else if (!strncmp("roam_scan_period=", full_param, len_param)) {\r
-               conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: roam_scan_period = %d\n", __FUNCTION__,\r
-                       conf->roam_scan_period[0]);\r
-       }\r
-       else if (!strncmp("roam_delta=", full_param, len_param)) {\r
-               conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);\r
-       }\r
-       else if (!strncmp("fullroamperiod=", full_param, len_param)) {\r
-               conf->fullroamperiod = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: fullroamperiod = %d\n", __FUNCTION__,\r
-                       conf->fullroamperiod);\r
-       } else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-bool\r
-dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)\r
-{\r
-       int i;\r
-       char *pch, *pick_tmp;\r
-       struct dhd_conf *conf = dhd->conf;\r
-       char *data = full_param+len_param;\r
-\r
-       /* Process country_list:\r
-        * country_list=[country1]:[ccode1]/[regrev1],\r
-        * [country2]:[ccode2]/[regrev2] \\r
-        * Ex: country_list=US:US/0, TW:TW/1\r
-        */\r
-       if (!strncmp("country_list=", 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
-                       strcpy(conf->country_list.cspec[i].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
-                       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
-                       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
-               }\r
-               printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-#ifdef PKT_FILTER_SUPPORT\r
-bool\r
-dhd_conf_read_pkt_filter(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
-       char *pch, *pick_tmp;\r
-       int i;\r
-\r
-       /* Process pkt filter:\r
-        * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
-        * 2) pkt_filter_del=100, 102, 103, 104, 105\r
-        * 3) magic_pkt_filter_add=141 0 1 12\r
-        */\r
-       if (!strncmp("dhd_master_mode=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       dhd_master_mode = FALSE;\r
-               else\r
-                       dhd_master_mode = TRUE;\r
-               printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);\r
-       }\r
-       else if (!strncmp("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->pkt_filter_add.filter[i][0], pch);\r
-                       printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);\r
-                       pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
-                       i++;\r
-               }\r
-               conf->pkt_filter_add.count = i;\r
-       }\r
-       else if (!strncmp("pkt_filter_del=", 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
-                       conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);\r
-                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-                       i++;\r
-               }\r
-               conf->pkt_filter_del.count = i;\r
-               printf("%s: pkt_filter_del id = ", __FUNCTION__);\r
-               for (i=0; i<conf->pkt_filter_del.count; i++)\r
-                       printf("%d ", conf->pkt_filter_del.id[i]);\r
-               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
-               }\r
-               conf->magic_pkt_filter_add.count = i;\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-#endif\r
-\r
-#ifdef IAPSTA_PREINIT\r
-/*\r
- * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]\r
- * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]\r
-                hidden [y|n] maxassoc [x]\r
-                amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\r
-                emode [none|wep|tkip|aes|tkipaes]\r
-                key [xxxxx]\r
- * iapsta_enable=ifname [wlan0|wlan1]\r
-*/\r
-bool\r
-dhd_conf_read_iapsta(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("iapsta_init=", full_param, len_param)) {\r
-               sprintf(conf->iapsta_init, "iapsta_init %s", data);\r
-               printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);\r
-       }\r
-       else if (!strncmp("iapsta_config=", full_param, len_param)) {\r
-               sprintf(conf->iapsta_config, "iapsta_config %s", data);\r
-               printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);\r
-       }\r
-       else if (!strncmp("iapsta_enable=", full_param, len_param)) {\r
-               sprintf(conf->iapsta_enable, "iapsta_enable %s", data);\r
-               printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-#endif\r
-\r
-#ifdef IDHCPC\r
-bool\r
-dhd_conf_read_dhcp_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("dhcpc_enable=", full_param, len_param)) {\r
-               conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-#endif\r
-\r
-#ifdef BCMSDIO\r
-bool\r
-dhd_conf_read_sdio_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("dhd_doflow=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       dhd_doflow = FALSE;\r
-               else\r
-                       dhd_doflow = TRUE;\r
-               printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow);\r
-       }\r
-       else if (!strncmp("dhd_slpauto=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       dhd_slpauto = FALSE;\r
-               else\r
-                       dhd_slpauto = TRUE;\r
-               printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);\r
-       }\r
-       else if (!strncmp("kso_enable=", full_param, len_param)) {\r
-               if (!strncmp(data, "1", 1))\r
-                       dhd_slpauto = FALSE;\r
-               else\r
-                       dhd_slpauto = TRUE;\r
-               printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);\r
-       }\r
-       else if (!strncmp("bus:txglom=", full_param, len_param)) {\r
-               conf->bus_txglom = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);\r
-       }\r
-       else if (!strncmp("use_rxchain=", full_param, len_param)) {\r
-               conf->use_rxchain = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain);\r
-       }\r
-       else if (!strncmp("dhd_txminmax=", full_param, len_param)) {\r
-               conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax);\r
-       }\r
-       else if (!strncmp("txinrx_thres=", full_param, len_param)) {\r
-               conf->txinrx_thres = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres);\r
-       }\r
-       else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) {\r
-               conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);\r
-       }\r
-       else if (!strncmp("oob_enabled_later=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->oob_enabled_later = FALSE;\r
-               else\r
-                       conf->oob_enabled_later = TRUE;\r
-               printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);\r
-       }\r
-#if defined(BCMSDIOH_TXGLOM)\r
-       else if (!strncmp("txglomsize=", full_param, len_param)) {\r
-               conf->txglomsize = (uint)simple_strtol(data, NULL, 10);\r
-               if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)\r
-                       conf->txglomsize = SDPCM_MAXGLOM_SIZE;\r
-               printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize);\r
-       }\r
-       else if (!strncmp("swtxglom=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->swtxglom = FALSE;\r
-               else\r
-                       conf->swtxglom = TRUE;\r
-               printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom);\r
-       }\r
-       else if (!strncmp("txglom_ext=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->txglom_ext = FALSE;\r
-               else\r
-                       conf->txglom_ext = TRUE;\r
-               printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext);\r
-               if (conf->txglom_ext) {\r
-                       if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID))\r
-                               conf->txglom_bucket_size = 1680;\r
-                       else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
-                                       conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID)\r
-                               conf->txglom_bucket_size = 1684;\r
-               }\r
-               printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size);\r
-       }\r
-       else if (!strncmp("bus:rxglom=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->bus_rxglom = FALSE;\r
-               else\r
-                       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
-       }\r
-       else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->txctl_tmo_fix = FALSE;\r
-               else\r
-                       conf->txctl_tmo_fix = TRUE;\r
-               printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);\r
-       }\r
-       else if (!strncmp("tx_in_rx=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->tx_in_rx = FALSE;\r
-               else\r
-                       conf->tx_in_rx = TRUE;\r
-               printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);\r
-       }\r
-       else if (!strncmp("tx_max_offset=", full_param, len_param)) {\r
-               conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);\r
-       }\r
-       else if (!strncmp("txglom_mode=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->txglom_mode = FALSE;\r
-               else\r
-                       conf->txglom_mode = TRUE;\r
-               printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);\r
-       }\r
-#endif\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
-       struct dhd_conf *conf = dhd->conf;\r
-       char *data = full_param+len_param;\r
-\r
-       if (!strncmp("lpc=", full_param, len_param)) {\r
-               conf->lpc = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);\r
-       }\r
-       else if (!strncmp("deepsleep=", full_param, len_param)) {\r
-               if (!strncmp(data, "1", 1))\r
-                       conf->deepsleep = TRUE;\r
-               else\r
-                       conf->deepsleep = FALSE;\r
-               printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);\r
-       }\r
-       else if (!strncmp("PM=", full_param, len_param)) {\r
-               conf->pm = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: PM = %d\n", __FUNCTION__, conf->pm);\r
-       }\r
-       else if (!strncmp("pm_in_suspend=", full_param, len_param)) {\r
-               conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);\r
-       }\r
-       else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) {\r
-               conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);\r
-       }\r
-       else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {\r
-               if (!strncmp(data, "1", 1))\r
-                       conf->xmit_in_suspend = TRUE;\r
-               else\r
-                       conf->xmit_in_suspend = FALSE;\r
-               printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-bool\r
-dhd_conf_read_others(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
-       uint len_data = strlen(data);\r
-       char *pch, *pick_tmp;\r
-       int i;\r
-\r
-       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
-               if (!strcmp(data, "b"))\r
-                       conf->band = WLC_BAND_2G;\r
-               else if (!strcmp(data, "a"))\r
-                       conf->band = WLC_BAND_5G;\r
-               else\r
-                       conf->band = WLC_BAND_AUTO;\r
-               printf("%s: band = %d\n", __FUNCTION__, conf->band);\r
-       }\r
-       else if (!strncmp("mimo_bw_cap=", full_param, len_param)) {\r
-               conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);\r
-       }\r
-       else if (!strncmp("bw_cap_2g=", full_param, len_param)) {\r
-               conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0);\r
-               printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);\r
-       }\r
-       else if (!strncmp("bw_cap_5g=", full_param, len_param)) {\r
-               conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0);\r
-               printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g);\r
-       }\r
-       else if (!strncmp("ccode=", full_param, len_param)) {\r
-               memset(&conf->cspec, 0, sizeof(wl_country_t));\r
-               memcpy(conf->cspec.country_abbrev, data, len_data);\r
-               memcpy(conf->cspec.ccode, data, len_data);\r
-               printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode);\r
-       }\r
-       else if (!strncmp("regrev=", full_param, len_param)) {\r
-               conf->cspec.rev = (int32)simple_strtol(data, NULL, 10);\r
-               printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev);\r
-       }\r
-       else if (!strncmp("channels=", full_param, len_param)) {\r
-               pick_tmp = data;\r
-               pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-               i=0;\r
-               while (pch != NULL && i<WL_NUMCHANNELS) {\r
-                       conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);\r
-                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
-                       i++;\r
-               }\r
-               conf->channels.count = i;\r
-               printf("%s: channels = ", __FUNCTION__);\r
-               for (i=0; i<conf->channels.count; i++)\r
-                       printf("%d ", conf->channels.channel[i]);\r
-               printf("\n");\r
-       }\r
-       else if (!strncmp("keep_alive_period=", full_param, len_param)) {\r
-               conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: keep_alive_period = %d\n", __FUNCTION__,\r
-                       conf->keep_alive_period);\r
-       }\r
-       else if (!strncmp("stbc=", full_param, len_param)) {\r
-               conf->stbc = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);\r
-       }\r
-       else if (!strncmp("phy_oclscdenable=", full_param, len_param)) {\r
-               conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable);\r
-       }\r
-       else if (!strncmp("srl=", full_param, len_param)) {\r
-               conf->srl = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: srl = %d\n", __FUNCTION__, conf->srl);\r
-       }\r
-       else if (!strncmp("lrl=", full_param, len_param)) {\r
-               conf->lrl = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);\r
-       }\r
-       else if (!strncmp("bcn_timeout=", full_param, len_param)) {\r
-               conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);\r
-       }\r
-       else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) {\r
-               conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);\r
-       }\r
-       else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) {\r
-               conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);\r
-       }\r
-       else if (!strncmp("spect=", full_param, len_param)) {\r
-               conf->spect = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: spect = %d\n", __FUNCTION__, conf->spect);\r
-       }\r
-       else if (!strncmp("txbf=", full_param, len_param)) {\r
-               conf->txbf = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);\r
-       }\r
-       else if (!strncmp("frameburst=", full_param, len_param)) {\r
-               conf->frameburst = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);\r
-       }\r
-       else if (!strncmp("disable_proptx=", full_param, len_param)) {\r
-               conf->disable_proptx = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx);\r
-       }\r
-#ifdef DHDTCPACK_SUPPRESS\r
-       else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) {\r
-               conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);\r
-       }\r
-#endif\r
-       else if (!strncmp("pktprio8021x=", full_param, len_param)) {\r
-               conf->pktprio8021x = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);\r
-       }\r
-       else if (!strncmp("dhd_txbound=", full_param, len_param)) {\r
-               dhd_txbound = (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound);\r
-       }\r
-       else if (!strncmp("dhd_rxbound=", full_param, len_param)) {\r
-               dhd_rxbound = (uint)simple_strtol(data, NULL, 10);\r
-               printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);\r
-       }\r
-       else if (!strncmp("rsdb_mode=", full_param, len_param)) {\r
-               conf->rsdb_mode = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode);\r
-       }\r
-       else if (!strncmp("vhtmode=", full_param, len_param)) {\r
-               if (!strncmp(data, "0", 1))\r
-                       conf->vhtmode = 0;\r
-               else\r
-                       conf->vhtmode = 1;\r
-               printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);\r
-       }\r
-       else if (!strncmp("num_different_channels=", full_param, len_param)) {\r
-               conf->num_different_channels = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);\r
-       }\r
-       else if (!strncmp("autocountry=", full_param, len_param)) {\r
-               conf->autocountry = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry);\r
-       }\r
-       else if (!strncmp("tsq=", full_param, len_param)) {\r
-               conf->tsq = (int)simple_strtol(data, NULL, 10);\r
-               printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);\r
-       }\r
-       else\r
-               return false;\r
-\r
-       return true;\r
-}\r
-\r
-int\r
-dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)\r
-{\r
-       int bcmerror = -1;\r
-       uint len, start_pos=0;\r
-       void * image = NULL;\r
-       char * memblock = NULL;\r
-       char *bufp, *pick = NULL, *pch;\r
-       bool conf_file_exists;\r
-       uint len_param;\r
-\r
-       conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));\r
-       if (!conf_file_exists) {\r
-               printf("%s: config path %s\n", __FUNCTION__, conf_path);\r
-               return (0);\r
-       }\r
-\r
-       if (conf_file_exists) {\r
-               image = dhd_os_open_image(conf_path);\r
-               if (image == NULL) {\r
-                       printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);\r
-                       goto err;\r
-               }\r
-       }\r
-\r
-       memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);\r
-       if (memblock == NULL) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_CONFIG));\r
-               goto err;\r
-       }\r
-\r
-       pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
-       if (!pick) {\r
-               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
-                       __FUNCTION__, MAXSZ_BUF));\r
-               goto err;\r
-       }\r
-\r
-       /* Read variables */\r
-       if (conf_file_exists) {\r
-               len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);\r
-       }\r
-       if (len > 0 && len < MAXSZ_CONFIG) {\r
-               bufp = (char *)memblock;\r
-               bufp[len] = 0;\r
-\r
-               while (start_pos < len) {\r
-                       memset(pick, 0, MAXSZ_BUF);\r
-                       start_pos = pick_config_vars(bufp, len, start_pos, pick);\r
-                       pch = strchr(pick, '=');\r
-                       if (pch != NULL) {\r
-                               len_param = pch-pick+1;\r
-                               if (len_param == strlen(pick)) {\r
-                                       CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));\r
-                                       continue;\r
-                               }\r
-                       } else {\r
-                               CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));\r
-                               continue;\r
-                       }\r
-\r
-                       if (dhd_conf_read_log_level(dhd, pick, len_param))\r
-                               continue;\r
-                       else if (dhd_conf_read_roam_params(dhd, pick, len_param))\r
-                               continue;\r
-                       else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param))\r
-                               continue;\r
-                       else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param))\r
-                               continue;\r
-                       else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param))\r
-                               continue;\r
-                       else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param))\r
-                               continue;\r
-                       else if (dhd_conf_read_country_list(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
-#endif /* PKT_FILTER_SUPPORT */\r
-#ifdef IAPSTA_PREINIT\r
-                       else if (dhd_conf_read_iapsta(dhd, pick, len_param))\r
-                               continue;\r
-#endif /* IAPSTA_PREINIT */\r
-#ifdef IDHCPC\r
-                       else if (dhd_conf_read_dhcp_params(dhd, pick, len_param))\r
-                               continue;\r
-#endif /* IDHCPC */\r
-#ifdef BCMSDIO\r
-                       else if (dhd_conf_read_sdio_params(dhd, pick, len_param))\r
-                               continue;\r
-#endif /* BCMSDIO */\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
-                               continue;\r
+       int bcmerror = -1;
+       struct dhd_conf *conf = dhd->conf;
+
+       dhd_roam_disable = conf->roam_off;
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);
+
+       if (!conf->roam_off || !conf->roam_off_suspend) {
+               printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",
+                               (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);
+
+               printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",
+                               (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);
+
+               printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",
+                               (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);
+
+               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);
+       }
+
+       return bcmerror;
+}
+
+void
+dhd_conf_set_bw_cap(dhd_pub_t *dhd)
+{
+       struct {
+               u32 band;
+               u32 bw_cap;
+       } param = {0, 0};
+
+       if (dhd->conf->bw_cap_2g >= 0) {
+               param.band = WLC_BAND_2G;
+               param.bw_cap = (uint)dhd->conf->bw_cap_2g;
+               printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
+       }
+
+       if (dhd->conf->bw_cap_5g >= 0) {
+               param.band = WLC_BAND_5G;
+               param.bw_cap = (uint)dhd->conf->bw_cap_5g;
+               printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
+       }
+}
+
+void
+dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp)
+{
+       int bcmerror = -1;
+       char iovbuf[WLC_IOCTL_SMLEN];
+       edcf_acparam_t *acparam;
+
+       bzero(iovbuf, sizeof(iovbuf));
+
+       /*
+        * Get current acparams, using buf as an input buffer.
+        * Return data is array of 4 ACs of wme params.
+        */
+       if (mode == 0)
+               bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));
+       else
+               bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf));
+       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
+               CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));
+               return;
+       }
+       memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);
+
+       acparam = &acp[AC_BK];
+       CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+       acparam = &acp[AC_BE];
+       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+       acparam = &acp[AC_VI];
+       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+       acparam = &acp[AC_VO];
+       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__,
+               acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+               acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acparam->TXOP));
+
+       return;
+}
+
+void
+dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci)
+{
+       int aifsn, ecwmin, ecwmax, txop;
+       edcf_acparam_t *acp;
+       struct dhd_conf *conf = dhd->conf;
+       wme_param_t *wme;
+
+       if (mode == 0)
+               wme = &conf->wme_sta;
+       else
+               wme = &conf->wme_ap;
+
+       /* Default value */
+       aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;
+       ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;
+       ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;
+       txop = acparam_cur->TXOP;
+
+       /* Modified value */
+       if (wme->aifsn[aci] > 0)
+               aifsn = wme->aifsn[aci];
+       if (wme->ecwmin[aci] > 0)
+               ecwmin = wme->ecwmin[aci];
+       if (wme->ecwmax[aci] > 0)
+               ecwmax = wme->ecwmax[aci];
+       if (wme->txop[aci] > 0)
+               txop = wme->txop[aci];
+
+       if (!(wme->aifsn[aci] || wme->ecwmin[aci] ||
+                       wme->ecwmax[aci] || wme->txop[aci]))
+               return;
+
+       /* Update */
+       acp = acparam_cur;
+       acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);
+       acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);
+       acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));
+       acp->TXOP = txop;
+
+       printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+               __FUNCTION__, mode?"ap":"sta",
+               acp->ACI, acp->ACI&EDCF_AIFSN_MASK,
+               acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+               acp->TXOP);
+
+       /*
+       * Now use buf as an output buffer.
+       * Put WME acparams after "wme_ac\0" in buf.
+       * NOTE: only one of the four ACs can be set at a time.
+       */
+       if (mode == 0)
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);
+       else
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE);
+
+}
+
+void
+dhd_conf_set_wme(dhd_pub_t *dhd, int mode)
+{
+       edcf_acparam_t acparam_cur[AC_COUNT];
+
+       if (dhd && dhd->conf) {
+               if (!dhd->conf->force_wme_ac) {
+                       CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",
+                               __FUNCTION__, dhd->conf->force_wme_ac));
+                       return;
+               }
+
+               CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));
+               dhd_conf_get_wme(dhd, mode, acparam_cur);
+
+               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK);
+               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE);
+               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI);
+               dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO);
+
+               CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));
+               dhd_conf_get_wme(dhd, mode, acparam_cur);
+       } else {
+               CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
+       }
+
+       return;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+void
+dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
+{
+       int i, j;
+       char str[12];
+#define MACS "%02x%02x%02x%02x%02x%02x"
+
+       /*
+        * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.
+        *   1) dhd_master_mode=0
+        *   2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
+        * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)
+        *   1) dhd_master_mode=1
+        *   2) pkt_filter_del=100, 102, 103, 104, 105
+        *   3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E
+        * 3. magic pkt: magic_pkt_filter_add=141 0 1 12
+        * 4. Filter out netbios pkt:
+        *   Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089
+        */
+       for (i=0; i<dhd->conf->pkt_filter_add.count; i++) {
+               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];
+               printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);
+       }
+       dhd->pktfilter_count += i;
+
+       for (i=0; i<dhd->conf->magic_pkt_filter_add.count; i++) {
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+               for (j=0; j<16; j++)
+                       strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
+               strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
+               sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));
+               for (j=0; j<16; j++)
+                       strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str);
+               dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i];
+               dhd->pktfilter_count += 1;
+       }
+}
+
+bool
+dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)
+{
+       int i;
+
+       if (dhd && dhd->conf) {
+               for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {
+                       if (id == dhd->conf->pkt_filter_del.id[i]) {
+                               printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);
+                               return true;
+                       }
+               }
+               return false;
+       }
+       return false;
+}
+
+void
+dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)
+{
+       dhd->pktfilter_count = 6;
+       dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;
+       dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+       dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";
+       dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";
+       dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
+       /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/
+       dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;
+
+       /* IPv4 broadcast address XXX.XXX.XXX.255 */
+       dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";
+       dhd->pktfilter_count++;
+       /* discard IPv4 multicast address 224.0.0.0/4 */
+       dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";
+       dhd->pktfilter_count++;
+       /* discard IPv6 multicast address FF00::/8 */
+       dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";
+       dhd->pktfilter_count++;
+       /* discard Netbios pkt */
+       dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";
+       dhd->pktfilter_count++;
+
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+int
+dhd_conf_get_pm(dhd_pub_t *dhd)
+{
+       if (dhd && dhd->conf)
+               return dhd->conf->pm;
+       return -1;
+}
+
+#define AP_IN_SUSPEND 1
+#define AP_DOWN_IN_SUSPEND 2
+int
+dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd)
+{
+       int mode = 0;
+
+       /* returned ap_in_suspend value:
+        * 0: nothing
+        * 1: ap enabled in suspend
+        * 2: ap enabled, but down in suspend
+        */
+       if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+               mode = dhd->conf->ap_in_suspend;
+       }
+
+       return mode;
+}
+
+int
+dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend)
+{
+       int mode = 0;
+       uint wl_down = 1;
+
+       mode = dhd_conf_get_ap_mode_in_suspend(dhd);
+       if (mode)
+               printf("%s: suspend %d, mode %d\n", __FUNCTION__, suspend, mode);
+       if (suspend) {
+               if (mode == AP_IN_SUSPEND) {
+#ifdef SUSPEND_EVENT
+                       if (dhd->conf->suspend_eventmask_enable) {
+                               char *eventmask = dhd->conf->suspend_eventmask;
+                               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);
+                       }
+#endif
+               } else if (mode == AP_DOWN_IN_SUSPEND)
+                       dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+       } else {
+               if (mode == AP_IN_SUSPEND) {
+#ifdef SUSPEND_EVENT
+                       if (dhd->conf->suspend_eventmask_enable) {
+                               char *eventmask = dhd->conf->resume_eventmask;
+                               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);
+                       }
+#endif
+               } else if (mode == AP_DOWN_IN_SUSPEND) {
+                       wl_down = 0;
+                       dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+               }
+       }
+
+       return mode;
+}
+
+#ifdef PROP_TXSTATUS
+int
+dhd_conf_get_disable_proptx(dhd_pub_t *dhd)
+{
+       struct dhd_conf *conf = dhd->conf;
+       int disable_proptx = -1;
+       int fw_proptx = 0;
+
+       /* check fw proptx priority:
+         * 1st: check fw support by wl cap
+         * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default
+         *        if you would like to disable it, please set disable_proptx=1 in config.txt
+         * 3th: disable when proptxstatus not support in wl cap
+         */
+       if (FW_SUPPORTED(dhd, proptxstatus)) {
+               fw_proptx = 1;
+       } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
+                       dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+               fw_proptx = 1;
+       } else {
+               fw_proptx = 0;
+       }
+
+       /* returned disable_proptx value:
+         * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)
+         * 0: depend on fw support
+         * 1: always disable proptx
+         */
+       if (conf->disable_proptx == 0) {
+               // check fw support as well
+               if (fw_proptx)
+                       disable_proptx = 0;
+               else
+                       disable_proptx = 1;
+       } else if (conf->disable_proptx >= 1) {
+               disable_proptx = 1;
+       } else {
+               // check fw support as well
+               if (fw_proptx)
+                       disable_proptx = -1;
+               else
+                       disable_proptx = 1;
+       }
+
+       printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx);
+
+       return disable_proptx;
+}
+#endif
+
+uint
+pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf)
+{
+       bool findNewline, changenewline=FALSE, pick=FALSE;
+       int column;
+       uint n, pick_column=0;
+
+       findNewline = FALSE;
+       column = 0;
+
+       if (start_pos >= len) {
+               CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__));
+               return 0;
+       }
+
+       for (n = start_pos; n < len; n++) {
+               if (varbuf[n] == '\r')
+                       continue;
+               if ((findNewline || changenewline) && varbuf[n] != '\n')
+                       continue;
+               findNewline = FALSE;
+               if (varbuf[n] == '#') {
+                       findNewline = TRUE;
+                       continue;
+               }
+               if (varbuf[n] == '\\') {
+                       changenewline = TRUE;
+                       continue;
+               }
+               if (!changenewline && varbuf[n] == '\n') {
+                       if (column == 0)
+                               continue;
+                       column = 0;
+                       continue;
+               }
+               if (changenewline && varbuf[n] == '\n') {
+                       changenewline = FALSE;
+                       continue;
+               }
+
+               if (column == 0 && !pick) { // start to pick
+                       pick = TRUE;
+                       column++;
+                       pick_column = 0;
+               } else {
+                       if (pick && column == 0) { // stop to pick
+                               pick = FALSE;
+                               break;
+                       } else
+                               column++;
+               }
+               if (pick) {
+                       if (varbuf[n] == 0x9)
+                               continue;
+                       if (pick_column>0 && pickbuf[pick_column-1] == ' ' && varbuf[n] == ' ')
+                               continue;
+                       pickbuf[pick_column] = varbuf[n];
+                       pick_column++;
+               }
+       }
+
+       return n; // return current position
+}
+
+bool
+dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       char *data = full_param+len_param;
+
+       if (!strncmp("dhd_msg_level=", full_param, len_param)) {
+               dhd_msg_level = (int)simple_strtol(data, NULL, 0);
+               printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);
+       }
+#ifdef BCMSDIO
+       else if (!strncmp("sd_msglevel=", full_param, len_param)) {
+               sd_msglevel = (int)simple_strtol(data, NULL, 0);
+               printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel);
+       }
+#endif
+       else if (!strncmp("android_msg_level=", full_param, len_param)) {
+               android_msg_level = (int)simple_strtol(data, NULL, 0);
+               printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);
+       }
+       else if (!strncmp("config_msg_level=", full_param, len_param)) {
+               config_msg_level = (int)simple_strtol(data, NULL, 0);
+               printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);
+       }
+#ifdef WL_CFG80211
+       else if (!strncmp("wl_dbg_level=", full_param, len_param)) {
+               wl_dbg_level = (int)simple_strtol(data, NULL, 0);
+               printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);
+       }
+#endif
+#if defined(WL_WIRELESS_EXT)
+       else if (!strncmp("iw_msg_level=", full_param, len_param)) {
+               iw_msg_level = (int)simple_strtol(data, NULL, 0);
+               printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);
+       }
+#endif
+#if defined(DHD_DEBUG)
+       else if (!strncmp("dhd_console_ms=", full_param, len_param)) {
+               dhd_console_ms = (int)simple_strtol(data, NULL, 0);
+               printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);
+       }
+#endif
+       else
+               return false;
+
+       return true;
+}
+
+void
+dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val)
+{
+       char *pick_tmp, *pch;
+
+       pick_tmp = pick;
+       pch = bcmstrstr(pick_tmp, "aifsn ");
+       if (pch) {
+               wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);
+               printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]);
+       }
+       pick_tmp = pick;
+       pch = bcmstrstr(pick_tmp, "ecwmin ");
+       if (pch) {
+               wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);
+               printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]);
+       }
+       pick_tmp = pick;
+       pch = bcmstrstr(pick_tmp, "ecwmax ");
+       if (pch) {
+               wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);
+               printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]);
+       }
+       pick_tmp = pick;
+       pch = bcmstrstr(pick_tmp, "txop ");
+       if (pch) {
+               wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);
+               printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]);
+       }
+
+}
+
+bool
+dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e
+       // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e
+
+       if (!strncmp("force_wme_ac=", full_param, len_param)) {
+               conf->force_wme_ac = (int)simple_strtol(data, NULL, 10);
+               printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);
+       }
+       else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE);
+       }
+       else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK);
+       }
+       else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI);
+       }
+       else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO);
+       }
+       else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE);
+       }
+       else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK);
+       }
+       else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI);
+       }
+       else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) {
+               dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO);
+       }
+       else
+               return false;
+
+       return true;
+}
+
+bool
+dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       int i, j;
+       char *pch, *pick_tmp;
+       wl_mac_list_t *mac_list;
+       wl_mac_range_t *mac_range;
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       /* Process fw_by_mac:
+        * fw_by_mac=[fw_mac_num] \
+        *  [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \
+        *                                    [oui1-1] [nic_start1-1] [nic_end1-1]... \
+        *                                    [oui1-n] [nic_start1-n] [nic_end1-n] \
+        *  [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \
+        *                                    [oui2-1] [nic_start2-1] [nic_end2-1]... \
+        *                                    [oui2-n] [nic_start2-n] [nic_end2-n] \
+        * Ex: fw_by_mac=2 \
+        *  fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
+        *  fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
+        *                           0x983B16 0x916157 0x916487
+        */
+
+       if (!strncmp("fw_by_mac=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, " ", 0);
+               conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
+               if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) {
+                       conf->fw_by_mac.count = 0;
+                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+               }
+               printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count);
+               conf->fw_by_mac.m_mac_list_head = mac_list;
+               for (i=0; i<conf->fw_by_mac.count; i++) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       strcpy(mac_list[i].name, pch);
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
+                       printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,
+                               mac_list[i].name, mac_list[i].count);
+                       if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {
+                               mac_list[i].count = 0;
+                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+                               break;
+                       }
+                       mac_list[i].mac = mac_range;
+                       for (j=0; j<mac_list[i].count; j++) {
+                               pch = bcmstrtok(&pick_tmp, " ", 0);
+                               mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
+                               pch = bcmstrtok(&pick_tmp, " ", 0);
+                               mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
+                               pch = bcmstrtok(&pick_tmp, " ", 0);
+                               mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
+                               printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
+                                       __FUNCTION__, mac_range[j].oui,
+                                       mac_range[j].nic_start, mac_range[j].nic_end);
+                       }
+               }
+       }
+       else
+               return false;
+
+       return true;
+}
+
+bool
+dhd_conf_read_nv_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       int i, j;
+       char *pch, *pick_tmp;
+       wl_mac_list_t *mac_list;
+       wl_mac_range_t *mac_range;
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       /* Process nv_by_mac:
+        * [nv_by_mac]: The same format as fw_by_mac
+        */
+       if (!strncmp("nv_by_mac=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, " ", 0);
+               conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
+               if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) {
+                       conf->nv_by_mac.count = 0;
+                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+               }
+               printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count);
+               conf->nv_by_mac.m_mac_list_head = mac_list;
+               for (i=0; i<conf->nv_by_mac.count; i++) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       strcpy(mac_list[i].name, pch);
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
+                       printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,
+                               mac_list[i].name, mac_list[i].count);
+                       if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {
+                               mac_list[i].count = 0;
+                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+                               break;
+                       }
+                       mac_list[i].mac = mac_range;
+                       for (j=0; j<mac_list[i].count; j++) {
+                               pch = bcmstrtok(&pick_tmp, " ", 0);
+                               mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
+                               pch = bcmstrtok(&pick_tmp, " ", 0);
+                               mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
+                               pch = bcmstrtok(&pick_tmp, " ", 0);
+                               mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
+                               printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
+                                       __FUNCTION__, mac_range[j].oui,
+                                       mac_range[j].nic_start, mac_range[j].nic_end);
+                       }
+               }
+       }
+       else
+               return false;
+
+       return true;
+}
+
+bool
+dhd_conf_read_nv_by_chip(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       int i;
+       char *pch, *pick_tmp;
+       wl_chip_nv_path_t *chip_nv_path;
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       /* Process nv_by_chip:
+        * nv_by_chip=[nv_chip_num] \
+        *  [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \
+        * Ex: nv_by_chip=2 \
+        *  43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \
+        */
+       if (!strncmp("nv_by_chip=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, " ", 0);
+               conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);
+               if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) {
+                       conf->nv_by_chip.count = 0;
+                       CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+               }
+               printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count);
+               conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;
+               for (i=0; i<conf->nv_by_chip.count; i++) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       strcpy(chip_nv_path[i].name, pch);
+                       printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__,
+                               chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);
+               }
+       }
+       else
+               return false;
+
+       return true;
+}
+
+bool
+dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       if (!strncmp("roam_off=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->roam_off = 0;
+               else
+                       conf->roam_off = 1;
+               printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);
+       }
+       else if (!strncmp("roam_off_suspend=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->roam_off_suspend = 0;
+               else
+                       conf->roam_off_suspend = 1;
+               printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend);
+       }
+       else if (!strncmp("roam_trigger=", full_param, len_param)) {
+               conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10);
+               printf("%s: roam_trigger = %d\n", __FUNCTION__,
+                       conf->roam_trigger[0]);
+       }
+       else if (!strncmp("roam_scan_period=", full_param, len_param)) {
+               conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10);
+               printf("%s: roam_scan_period = %d\n", __FUNCTION__,
+                       conf->roam_scan_period[0]);
+       }
+       else if (!strncmp("roam_delta=", full_param, len_param)) {
+               conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10);
+               printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);
+       }
+       else if (!strncmp("fullroamperiod=", full_param, len_param)) {
+               conf->fullroamperiod = (int)simple_strtol(data, NULL, 10);
+               printf("%s: fullroamperiod = %d\n", __FUNCTION__,
+                       conf->fullroamperiod);
+       } else
+               return false;
+
+       return true;
+}
+
+bool
+dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       int i;
+       char *pch, *pick_tmp;
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       /* Process country_list:
+        * country_list=[country1]:[ccode1]/[regrev1],
+        * [country2]:[ccode2]/[regrev2] \
+        * Ex: country_list=US:US/0, TW:TW/1
+        */
+       if (!strncmp("country_list=", full_param, len_param)) {
+               pick_tmp = data;
+               for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {
+                       /* Process country code */
+                       pch = bcmstrtok(&pick_tmp, ":", 0);
+                       if (!pch)
+                               break;
+                       strcpy(conf->country_list.cspec[i].country_abbrev, pch);
+                       pch = bcmstrtok(&pick_tmp, "/", 0);
+                       if (!pch)
+                               break;
+                       memcpy(conf->country_list.cspec[i].ccode, pch, 2);
+                       pch = bcmstrtok(&pick_tmp, ", ", 0);
+                       if (!pch)
+                               break;
+                       conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);
+                       conf->country_list.count ++;
+                       CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,
+                               conf->country_list.cspec[i].country_abbrev,
+                               conf->country_list.cspec[i].ccode,
+                               conf->country_list.cspec[i].rev));
+               }
+               printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);
+       }
+       else
+               return false;
+
+       return true;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+bool
+dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+       char *pch, *pick_tmp;
+       int i;
+
+       /* Process pkt filter:
+        * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
+        * 2) pkt_filter_del=100, 102, 103, 104, 105
+        * 3) magic_pkt_filter_add=141 0 1 12
+        */
+       if (!strncmp("dhd_master_mode=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       dhd_master_mode = FALSE;
+               else
+                       dhd_master_mode = TRUE;
+               printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);
+       }
+       else if (!strncmp("pkt_filter_add=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, ",.-", 0);
+               i=0;
+               while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+                       strcpy(&conf->pkt_filter_add.filter[i][0], pch);
+                       printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);
+                       pch = bcmstrtok(&pick_tmp, ",.-", 0);
+                       i++;
+               }
+               conf->pkt_filter_add.count = i;
+       }
+       else if (!strncmp("pkt_filter_del=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+               i=0;
+               while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+                       conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);
+                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+                       i++;
+               }
+               conf->pkt_filter_del.count = i;
+               printf("%s: pkt_filter_del id = ", __FUNCTION__);
+               for (i=0; i<conf->pkt_filter_del.count; i++)
+                       printf("%d ", conf->pkt_filter_del.id[i]);
+               printf("\n");
+       }
+       else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, ",.-", 0);
+               i=0;
+               while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+                       strcpy(&conf->magic_pkt_filter_add.filter[i][0], pch);
+                       printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]);
+                       pch = bcmstrtok(&pick_tmp, ",.-", 0);
+                       i++;
+               }
+               conf->magic_pkt_filter_add.count = i;
+       }
+       else
+               return false;
+
+       return true;
+}
+#endif
+
+#ifdef IAPSTA_PREINIT
+/*
+ * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]
+ * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]
+                hidden [y|n] maxassoc [x]
+                amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]
+                emode [none|wep|tkip|aes|tkipaes]
+                key [xxxxx]
+ * iapsta_enable=ifname [wlan0|wlan1]
+*/
+bool
+dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       if (!strncmp("iapsta_init=", full_param, len_param)) {
+               sprintf(conf->iapsta_init, "iapsta_init %s", data);
+               printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);
+       }
+       else if (!strncmp("iapsta_config=", full_param, len_param)) {
+               sprintf(conf->iapsta_config, "iapsta_config %s", data);
+               printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);
+       }
+       else if (!strncmp("iapsta_enable=", full_param, len_param)) {
+               sprintf(conf->iapsta_enable, "iapsta_enable %s", data);
+               printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);
+       }
+       else
+               return false;
+
+       return true;
+}
+#endif
+
+#ifdef IDHCP
+bool
+dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+       struct ipv4_addr ipa_set;
+
+       if (!strncmp("dhcpc_enable=", full_param, len_param)) {
+               conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10);
+               printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);
+       }
+       else if (!strncmp("dhcpd_enable=", full_param, len_param)) {
+               conf->dhcpd_enable = (int)simple_strtol(data, NULL, 10);
+               printf("%s: dhcpd_enable = %d\n", __FUNCTION__, conf->dhcpd_enable);
+       }
+       else if (!strncmp("dhcpd_ip_addr=", full_param, len_param)) {
+               if (!bcm_atoipv4(data, &ipa_set))
+                       printf("%s : dhcpd_ip_addr adress setting failed.\n", __FUNCTION__);
+               conf->dhcpd_ip_addr = ipa_set;
+               printf("%s: dhcpd_ip_addr = %s\n",__FUNCTION__, data);
+       }
+       else if (!strncmp("dhcpd_ip_mask=", full_param, len_param)) {
+               if (!bcm_atoipv4(data, &ipa_set))
+                       printf("%s : dhcpd_ip_mask adress setting failed.\n", __FUNCTION__);
+               conf->dhcpd_ip_mask = ipa_set;
+               printf("%s: dhcpd_ip_mask = %s\n",__FUNCTION__, data);
+       }
+       else if (!strncmp("dhcpd_ip_start=", full_param, len_param)) {
+               if (!bcm_atoipv4(data, &ipa_set))
+                       printf("%s : dhcpd_ip_start adress setting failed.\n", __FUNCTION__);
+               conf->dhcpd_ip_start = ipa_set;
+               printf("%s: dhcpd_ip_start = %s\n",__FUNCTION__, data);
+       }
+       else if (!strncmp("dhcpd_ip_end=", full_param, len_param)) {
+               if (!bcm_atoipv4(data, &ipa_set))
+                       printf("%s : dhcpd_ip_end adress setting failed.\n", __FUNCTION__);
+               conf->dhcpd_ip_end = ipa_set;
+               printf("%s: dhcpd_ip_end = %s\n",__FUNCTION__, data);
+       }
+       else
+               return false;
+
+       return true;
+}
+#endif
+
+#ifdef BCMSDIO
+bool
+dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       if (!strncmp("dhd_doflow=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       dhd_doflow = FALSE;
+               else
+                       dhd_doflow = TRUE;
+               printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow);
+       }
+       else if (!strncmp("dhd_slpauto=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       dhd_slpauto = FALSE;
+               else
+                       dhd_slpauto = TRUE;
+               printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);
+       }
+       else if (!strncmp("kso_enable=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       dhd_slpauto = FALSE;
+               else
+                       dhd_slpauto = TRUE;
+               printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);
+       }
+       else if (!strncmp("bus:txglom=", full_param, len_param)) {
+               conf->bus_txglom = (int)simple_strtol(data, NULL, 10);
+               printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);
+       }
+       else if (!strncmp("use_rxchain=", full_param, len_param)) {
+               conf->use_rxchain = (int)simple_strtol(data, NULL, 10);
+               printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain);
+       }
+       else if (!strncmp("dhd_txminmax=", full_param, len_param)) {
+               conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10);
+               printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax);
+       }
+       else if (!strncmp("txinrx_thres=", full_param, len_param)) {
+               conf->txinrx_thres = (int)simple_strtol(data, NULL, 10);
+               printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres);
+       }
+       else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) {
+               conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10);
+               printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);
+       }
+       else if (!strncmp("oob_enabled_later=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->oob_enabled_later = FALSE;
+               else
+                       conf->oob_enabled_later = TRUE;
+               printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);
+       }
+       else if (!strncmp("dpc_cpucore=", full_param, len_param)) {
+               conf->dpc_cpucore = (int)simple_strtol(data, NULL, 10);
+               printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore);
+       }
+       else if (!strncmp("rxf_cpucore=", full_param, len_param)) {
+               conf->rxf_cpucore = (int)simple_strtol(data, NULL, 10);
+               printf("%s: rxf_cpucore = %d\n", __FUNCTION__, conf->rxf_cpucore);
+       }
+#if defined(BCMSDIOH_TXGLOM)
+       else if (!strncmp("txglomsize=", full_param, len_param)) {
+               conf->txglomsize = (uint)simple_strtol(data, NULL, 10);
+               if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
+                       conf->txglomsize = SDPCM_MAXGLOM_SIZE;
+               printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize);
+       }
+       else if (!strncmp("swtxglom=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->swtxglom = FALSE;
+               else
+                       conf->swtxglom = TRUE;
+               printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom);
+       }
+       else if (!strncmp("txglom_ext=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->txglom_ext = FALSE;
+               else
+                       conf->txglom_ext = TRUE;
+               printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext);
+               if (conf->txglom_ext) {
+                       if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID))
+                               conf->txglom_bucket_size = 1680;
+                       else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
+                                       conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID)
+                               conf->txglom_bucket_size = 1684;
+               }
+               printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size);
+       }
+       else if (!strncmp("bus:rxglom=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->bus_rxglom = FALSE;
+               else
+                       conf->bus_rxglom = TRUE;
+               printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);
+       }
+       else if (!strncmp("dhd_poll=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->dhd_poll = 0;
+               else
+                       conf->dhd_poll = 1;
+               printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);
+       }
+       else if (!strncmp("deferred_tx_len=", full_param, len_param)) {
+               conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);
+               printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);
+       }
+       else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->txctl_tmo_fix = FALSE;
+               else
+                       conf->txctl_tmo_fix = TRUE;
+               printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);
+       }
+       else if (!strncmp("tx_in_rx=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->tx_in_rx = FALSE;
+               else
+                       conf->tx_in_rx = TRUE;
+               printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);
+       }
+       else if (!strncmp("tx_max_offset=", full_param, len_param)) {
+               conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);
+               printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);
+       }
+       else if (!strncmp("txglom_mode=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->txglom_mode = FALSE;
+               else
+                       conf->txglom_mode = TRUE;
+               printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);
+       }
+#endif
+       else
+               return false;
+
+       return true;
+}
+#endif
+
+bool
+dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+
+       if (!strncmp("lpc=", full_param, len_param)) {
+               conf->lpc = (int)simple_strtol(data, NULL, 10);
+               printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);
+       }
+       else if (!strncmp("deepsleep=", full_param, len_param)) {
+               if (!strncmp(data, "1", 1))
+                       conf->deepsleep = TRUE;
+               else
+                       conf->deepsleep = FALSE;
+               printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);
+       }
+       else if (!strncmp("PM=", full_param, len_param)) {
+               conf->pm = (int)simple_strtol(data, NULL, 10);
+               printf("%s: PM = %d\n", __FUNCTION__, conf->pm);
+       }
+       else if (!strncmp("pm_in_suspend=", full_param, len_param)) {
+               conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10);
+               printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);
+       }
+       else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) {
+               conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10);
+               printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);
+       }
+       else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {
+               if (!strncmp(data, "1", 1))
+                       conf->xmit_in_suspend = TRUE;
+               else
+                       conf->xmit_in_suspend = FALSE;
+               printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);
+       }
+       else if (!strncmp("ap_in_suspend=", full_param, len_param)) {
+               conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);
+               printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);
+       }
+       else
+               return false;
+
+       return true;
+}
+
+bool
+dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+       struct dhd_conf *conf = dhd->conf;
+       char *data = full_param+len_param;
+       uint len_data = strlen(data);
+       char *pch, *pick_tmp;
+       int i;
+
+       if (!strncmp("band=", full_param, len_param)) {
+               /* Process band:
+                * band=a for 5GHz only and band=b for 2.4GHz only
+                */
+               if (!strcmp(data, "b"))
+                       conf->band = WLC_BAND_2G;
+               else if (!strcmp(data, "a"))
+                       conf->band = WLC_BAND_5G;
+               else
+                       conf->band = WLC_BAND_AUTO;
+               printf("%s: band = %d\n", __FUNCTION__, conf->band);
+       }
+       else if (!strncmp("mimo_bw_cap=", full_param, len_param)) {
+               conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10);
+               printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);
+       }
+       else if (!strncmp("bw_cap_2g=", full_param, len_param)) {
+               conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0);
+               printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);
+       }
+       else if (!strncmp("bw_cap_5g=", full_param, len_param)) {
+               conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0);
+               printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g);
+       }
+       else if (!strncmp("ccode=", full_param, len_param)) {
+               memset(&conf->cspec, 0, sizeof(wl_country_t));
+               memcpy(conf->cspec.country_abbrev, data, len_data);
+               memcpy(conf->cspec.ccode, data, len_data);
+               printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode);
+       }
+       else if (!strncmp("regrev=", full_param, len_param)) {
+               conf->cspec.rev = (int32)simple_strtol(data, NULL, 10);
+               printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev);
+       }
+       else if (!strncmp("channels=", full_param, len_param)) {
+               pick_tmp = data;
+               pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+               i=0;
+               while (pch != NULL && i<WL_NUMCHANNELS) {
+                       conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);
+                       pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+                       i++;
+               }
+               conf->channels.count = i;
+               printf("%s: channels = ", __FUNCTION__);
+               for (i=0; i<conf->channels.count; i++)
+                       printf("%d ", conf->channels.channel[i]);
+               printf("\n");
+       }
+       else if (!strncmp("keep_alive_period=", full_param, len_param)) {
+               conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10);
+               printf("%s: keep_alive_period = %d\n", __FUNCTION__,
+                       conf->keep_alive_period);
+       }
+       else if (!strncmp("stbc=", full_param, len_param)) {
+               conf->stbc = (int)simple_strtol(data, NULL, 10);
+               printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);
+       }
+       else if (!strncmp("phy_oclscdenable=", full_param, len_param)) {
+               conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10);
+               printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable);
+       }
+       else if (!strncmp("srl=", full_param, len_param)) {
+               conf->srl = (int)simple_strtol(data, NULL, 10);
+               printf("%s: srl = %d\n", __FUNCTION__, conf->srl);
+       }
+       else if (!strncmp("lrl=", full_param, len_param)) {
+               conf->lrl = (int)simple_strtol(data, NULL, 10);
+               printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);
+       }
+       else if (!strncmp("bcn_timeout=", full_param, len_param)) {
+               conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10);
+               printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);
+       }
+       else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) {
+               conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10);
+               printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);
+       }
+       else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) {
+               conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10);
+               printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);
+       }
+       else if (!strncmp("spect=", full_param, len_param)) {
+               conf->spect = (int)simple_strtol(data, NULL, 10);
+               printf("%s: spect = %d\n", __FUNCTION__, conf->spect);
+       }
+       else if (!strncmp("txbf=", full_param, len_param)) {
+               conf->txbf = (int)simple_strtol(data, NULL, 10);
+               printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);
+       }
+       else if (!strncmp("frameburst=", full_param, len_param)) {
+               conf->frameburst = (int)simple_strtol(data, NULL, 10);
+               printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);
+       }
+       else if (!strncmp("disable_proptx=", full_param, len_param)) {
+               conf->disable_proptx = (int)simple_strtol(data, NULL, 10);
+               printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx);
+       }
+#ifdef DHDTCPACK_SUPPRESS
+       else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) {
+               conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10);
+               printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);
+       }
+#endif
+       else if (!strncmp("pktprio8021x=", full_param, len_param)) {
+               conf->pktprio8021x = (int)simple_strtol(data, NULL, 10);
+               printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);
+       }
+       else if (!strncmp("dhd_txbound=", full_param, len_param)) {
+               dhd_txbound = (uint)simple_strtol(data, NULL, 10);
+               printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound);
+       }
+       else if (!strncmp("dhd_rxbound=", full_param, len_param)) {
+               dhd_rxbound = (uint)simple_strtol(data, NULL, 10);
+               printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);
+       }
+       else if (!strncmp("rsdb_mode=", full_param, len_param)) {
+               conf->rsdb_mode = (int)simple_strtol(data, NULL, 10);
+               printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode);
+       }
+       else if (!strncmp("vhtmode=", full_param, len_param)) {
+               if (!strncmp(data, "0", 1))
+                       conf->vhtmode = 0;
+               else
+                       conf->vhtmode = 1;
+               printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);
+       }
+       else if (!strncmp("num_different_channels=", full_param, len_param)) {
+               conf->num_different_channels = (int)simple_strtol(data, NULL, 10);
+               printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);
+       }
+       else if (!strncmp("autocountry=", full_param, len_param)) {
+               conf->autocountry = (int)simple_strtol(data, NULL, 10);
+               printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry);
+       }
+       else if (!strncmp("tsq=", full_param, len_param)) {
+               conf->tsq = (int)simple_strtol(data, NULL, 10);
+               printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);
+       }
+       else
+               return false;
+
+       return true;
+}
+
+int
+dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
+{
+       int bcmerror = -1;
+       uint len, start_pos=0;
+       void * image = NULL;
+       char * memblock = NULL;
+       char *bufp, *pick = NULL, *pch;
+       bool conf_file_exists;
+       uint len_param;
+
+       conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));
+       if (!conf_file_exists) {
+               printf("%s: config path %s\n", __FUNCTION__, conf_path);
+               return (0);
+       }
+
+       if (conf_file_exists) {
+               image = dhd_os_open_image(conf_path);
+               if (image == NULL) {
+                       printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);
+                       goto err;
+               }
+       }
+
+       memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);
+       if (memblock == NULL) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_CONFIG));
+               goto err;
+       }
+
+       pick = MALLOC(dhd->osh, MAXSZ_BUF);
+       if (!pick) {
+               CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
+                       __FUNCTION__, MAXSZ_BUF));
+               goto err;
+       }
+
+       /* Read variables */
+       if (conf_file_exists) {
+               len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);
+       }
+       if (len > 0 && len < MAXSZ_CONFIG) {
+               bufp = (char *)memblock;
+               bufp[len] = 0;
+
+               while (start_pos < len) {
+                       memset(pick, 0, MAXSZ_BUF);
+                       start_pos = pick_config_vars(bufp, len, start_pos, pick);
+                       pch = strchr(pick, '=');
+                       if (pch != NULL) {
+                               len_param = pch-pick+1;
+                               if (len_param == strlen(pick)) {
+                                       CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));
+                                       continue;
+                               }
+                       } else {
+                               CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));
+                               continue;
+                       }
+
+                       if (dhd_conf_read_log_level(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_roam_params(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_country_list(dhd, pick, len_param))
+                               continue;
+#ifdef PKT_FILTER_SUPPORT
+                       else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))
+                               continue;
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef IAPSTA_PREINIT
+                       else if (dhd_conf_read_iapsta(dhd, pick, len_param))
+                               continue;
+#endif /* IAPSTA_PREINIT */
+#ifdef IDHCP
+                       else if (dhd_conf_read_dhcp_params(dhd, pick, len_param))
+                               continue;
+#endif /* IDHCP */
+#ifdef BCMSDIO
+                       else if (dhd_conf_read_sdio_params(dhd, pick, len_param))
+                               continue;
+#endif /* BCMSDIO */
+                       else if (dhd_conf_read_pm_params(dhd, pick, len_param))
+                               continue;
+                       else if (dhd_conf_read_others(dhd, pick, len_param))
+                               continue;
                        else
-                               continue;\r
-               }\r
-\r
-               bcmerror = 0;\r
-       } else {\r
-               CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));\r
-               bcmerror = BCME_SDIO_ERROR;\r
-       }\r
-\r
-err:\r
-       if (pick)\r
-               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
-\r
-       if (memblock)\r
-               MFREE(dhd->osh, memblock, MAXSZ_CONFIG);\r
-\r
-       if (image)\r
-               dhd_os_close_image(image);\r
-\r
-       return bcmerror;\r
-}\r
-\r
-int\r
-dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)\r
-{\r
-       printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);\r
-       dhd->conf->chip = chip;\r
-       dhd->conf->chiprev = chiprev;\r
-       return 0;\r
-}\r
-\r
-uint\r
-dhd_conf_get_chip(void *context)\r
-{\r
-       dhd_pub_t *dhd = context;\r
-\r
-       if (dhd && dhd->conf)\r
-               return dhd->conf->chip;\r
-       return 0;\r
-}\r
-\r
-uint\r
-dhd_conf_get_chiprev(void *context)\r
-{\r
-       dhd_pub_t *dhd = context;\r
-\r
-       if (dhd && dhd->conf)\r
-               return dhd->conf->chiprev;\r
-       return 0;\r
-}\r
-\r
-#ifdef BCMSDIO\r
-void\r
-dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)\r
-{\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       if (enable) {\r
-#if defined(SWTXGLOM)\r
-               if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
-                               conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
-                               conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
-                       // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom\r
-                       conf->swtxglom = TRUE;\r
-                       conf->txglom_ext = TRUE;\r
-               }\r
-               if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) {\r
-                       conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only\r
-               }\r
-#elif defined(BCMSDIOH_TXGLOM_EXT)\r
-               if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
-                               conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
-                               conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
-                       conf->txglom_mode = SDPCM_TXGLOM_CPY;\r
-               }\r
-#endif\r
-               // other parameters set in preinit or config.txt\r
-       } else {\r
-               // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt\r
-               conf->txglom_ext = FALSE;\r
-               conf->txglom_bucket_size = 0;\r
-               conf->txglomsize = 0;\r
-               conf->deferred_tx_len = 0;\r
-       }\r
-       printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__,\r
-               conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size);\r
-       printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__,\r
-               conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom);\r
-       printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,\r
-               conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax);\r
-       printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__,\r
-               conf->tx_max_offset, conf->txctl_tmo_fix);\r
-\r
-}\r
-#endif\r
-\r
-int\r
-dhd_conf_preinit(dhd_pub_t *dhd)\r
-{\r
-       struct dhd_conf *conf = dhd->conf;\r
-\r
-       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
-\r
-#ifdef BCMSDIO\r
-       dhd_conf_free_mac_list(&conf->fw_by_mac);\r
-       dhd_conf_free_mac_list(&conf->nv_by_mac);\r
-       dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);\r
-#endif\r
-       memset(&conf->country_list, 0, sizeof(conf_country_list_t));\r
-       conf->band = WLC_BAND_AUTO;\r
-       conf->mimo_bw_cap = -1;\r
-       conf->bw_cap_2g = -1;\r
-       conf->bw_cap_5g = -1;\r
-       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {\r
-               strcpy(conf->cspec.country_abbrev, "ALL");\r
-               strcpy(conf->cspec.ccode, "ALL");\r
-               conf->cspec.rev = 0;\r
-       } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID ||\r
-                       conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||\r
-                       conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID ||\r
-                       conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) {\r
-               strcpy(conf->cspec.country_abbrev, "CN");\r
-               strcpy(conf->cspec.ccode, "CN");\r
-               conf->cspec.rev = 38;\r
-       } else {\r
-               strcpy(conf->cspec.country_abbrev, "CN");\r
-               strcpy(conf->cspec.ccode, "CN");\r
-               conf->cspec.rev = 0;\r
-       }\r
-       memset(&conf->channels, 0, sizeof(wl_channel_list_t));\r
-       conf->roam_off = 1;\r
-       conf->roam_off_suspend = 1;\r
-#ifdef CUSTOM_ROAM_TRIGGER_SETTING\r
-       conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;\r
-#else\r
-       conf->roam_trigger[0] = -65;\r
-#endif\r
-       conf->roam_trigger[1] = WLC_BAND_ALL;\r
-       conf->roam_scan_period[0] = 10;\r
-       conf->roam_scan_period[1] = WLC_BAND_ALL;\r
-#ifdef CUSTOM_ROAM_DELTA_SETTING\r
-       conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;\r
-#else\r
-       conf->roam_delta[0] = 15;\r
-#endif\r
-       conf->roam_delta[1] = WLC_BAND_ALL;\r
+                               continue;
+               }
+
+               bcmerror = 0;
+       } else {
+               CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));
+               bcmerror = BCME_SDIO_ERROR;
+       }
+
+err:
+       if (pick)
+               MFREE(dhd->osh, pick, MAXSZ_BUF);
+
+       if (memblock)
+               MFREE(dhd->osh, memblock, MAXSZ_CONFIG);
+
+       if (image)
+               dhd_os_close_image(image);
+
+       return bcmerror;
+}
+
+int
+dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)
+{
+       printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);
+       dhd->conf->chip = chip;
+       dhd->conf->chiprev = chiprev;
+       return 0;
+}
+
+uint
+dhd_conf_get_chip(void *context)
+{
+       dhd_pub_t *dhd = context;
+
+       if (dhd && dhd->conf)
+               return dhd->conf->chip;
+       return 0;
+}
+
+uint
+dhd_conf_get_chiprev(void *context)
+{
+       dhd_pub_t *dhd = context;
+
+       if (dhd && dhd->conf)
+               return dhd->conf->chiprev;
+       return 0;
+}
+
+#ifdef BCMSDIO
+void
+dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)
+{
+       struct dhd_conf *conf = dhd->conf;
+
+       if (enable) {
+#if defined(SWTXGLOM)
+               if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
+                               conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
+                               conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+                       // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom
+                       conf->swtxglom = TRUE;
+                       conf->txglom_ext = TRUE;
+               }
+               if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) {
+                       conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only
+               }
+#elif defined(BCMSDIOH_TXGLOM_EXT)
+               if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
+                               conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
+                               conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+                       conf->txglom_mode = SDPCM_TXGLOM_CPY;
+               }
+#endif
+               // other parameters set in preinit or config.txt
+       } else {
+               // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt
+               conf->txglom_ext = FALSE;
+               conf->txglom_bucket_size = 0;
+               conf->txglomsize = 0;
+               conf->deferred_tx_len = 0;
+       }
+       printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__,
+               conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size);
+       printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__,
+               conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom);
+       printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,
+               conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax);
+       printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__,
+               conf->tx_max_offset, conf->txctl_tmo_fix);
+
+}
+#endif
+
+int
+dhd_conf_preinit(dhd_pub_t *dhd)
+{
+       struct dhd_conf *conf = dhd->conf;
+
+       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
+
+#ifdef BCMSDIO
+       dhd_conf_free_mac_list(&conf->fw_by_mac);
+       dhd_conf_free_mac_list(&conf->nv_by_mac);
+       dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
+#endif
+       memset(&conf->country_list, 0, sizeof(conf_country_list_t));
+       conf->band = WLC_BAND_AUTO;
+       conf->mimo_bw_cap = -1;
+       conf->bw_cap_2g = -1;
+       conf->bw_cap_5g = -1;
+       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {
+               strcpy(conf->cspec.country_abbrev, "ALL");
+               strcpy(conf->cspec.ccode, "ALL");
+               conf->cspec.rev = 0;
+       } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID ||
+                       conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
+                       conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID ||
+                       conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) {
+               strcpy(conf->cspec.country_abbrev, "CN");
+               strcpy(conf->cspec.ccode, "CN");
+               conf->cspec.rev = 38;
+       } else {
+               strcpy(conf->cspec.country_abbrev, "CN");
+               strcpy(conf->cspec.ccode, "CN");
+               conf->cspec.rev = 0;
+       }
+       memset(&conf->channels, 0, sizeof(wl_channel_list_t));
+       conf->roam_off = 1;
+       conf->roam_off_suspend = 1;
+#ifdef CUSTOM_ROAM_TRIGGER_SETTING
+       conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;
+#else
+       conf->roam_trigger[0] = -65;
+#endif
+       conf->roam_trigger[1] = WLC_BAND_ALL;
+       conf->roam_scan_period[0] = 10;
+       conf->roam_scan_period[1] = WLC_BAND_ALL;
+#ifdef CUSTOM_ROAM_DELTA_SETTING
+       conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;
+#else
+       conf->roam_delta[0] = 15;
+#endif
+       conf->roam_delta[1] = WLC_BAND_ALL;
 #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
-       conf->fullroamperiod = 60;\r
+       conf->fullroamperiod = 60;
 #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
-       conf->fullroamperiod = 120;\r
-#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */\r
-#ifdef CUSTOM_KEEP_ALIVE_SETTING\r
-       conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;\r
-#else\r
-       conf->keep_alive_period = 28000;\r
-#endif\r
-       conf->force_wme_ac = 0;\r
-       memset(&conf->wme_sta, 0, sizeof(wme_param_t));\r
-       memset(&conf->wme_ap, 0, sizeof(wme_param_t));\r
-       conf->stbc = -1;\r
-       conf->phy_oclscdenable = -1;\r
-#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
-       conf->bcn_timeout = 15;\r
-       conf->spect = -1;\r
-       conf->txbf = -1;\r
-       conf->lpc = -1;\r
-       conf->disable_proptx = -1;\r
-#ifdef BCMSDIO\r
-       conf->bus_txglom = -1;\r
-       conf->use_rxchain = 0;\r
-       conf->bus_rxglom = TRUE;\r
-       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 = FALSE;\r
-       conf->tx_in_rx = TRUE;\r
-       conf->txglom_mode = SDPCM_TXGLOM_MDESC;\r
-       conf->deferred_tx_len = 0;\r
-       conf->dhd_txminmax = 1;\r
-       conf->txinrx_thres = -1;\r
-       conf->sd_f2_blocksize = 0;\r
-       conf->oob_enabled_later = FALSE;\r
-#endif\r
-       conf->ampdu_ba_wsize = 0;\r
-       conf->ampdu_hostreorder = -1;\r
-       conf->dpc_cpucore = -1;\r
-       conf->rxf_cpucore = -1;\r
-       conf->frameburst = -1;\r
-       conf->deepsleep = FALSE;\r
-       conf->pm = -1;\r
-       conf->pm_in_suspend = -1;\r
-       conf->pm2_sleep_ret = -1;\r
-       conf->num_different_channels = -1;\r
-       conf->xmit_in_suspend = TRUE;\r
-#ifdef IDHCPC\r
-       conf->dhcpc_enable = -1;\r
-#endif\r
-       conf->tsq = 0;\r
+       conf->fullroamperiod = 120;
+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
+#ifdef CUSTOM_KEEP_ALIVE_SETTING
+       conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;
+#else
+       conf->keep_alive_period = 28000;
+#endif
+       conf->force_wme_ac = 0;
+       memset(&conf->wme_sta, 0, sizeof(wme_param_t));
+       memset(&conf->wme_ap, 0, sizeof(wme_param_t));
+       conf->stbc = -1;
+       conf->phy_oclscdenable = -1;
+#ifdef PKT_FILTER_SUPPORT
+       memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));
+       memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));
+       memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t));
+#endif
+       conf->srl = -1;
+       conf->lrl = -1;
+       conf->bcn_timeout = 15;
+       conf->spect = -1;
+       conf->txbf = -1;
+       conf->lpc = -1;
+       conf->disable_proptx = -1;
+#ifdef BCMSDIO
+       conf->bus_txglom = -1;
+       conf->use_rxchain = 0;
+       conf->bus_rxglom = TRUE;
+       conf->txglom_ext = FALSE;
+       conf->tx_max_offset = 0;
+       conf->txglomsize = SDPCM_DEFGLOM_SIZE;
+       conf->dhd_poll = -1;
+       conf->txctl_tmo_fix = FALSE;
+       conf->tx_in_rx = TRUE;
+       conf->txglom_mode = SDPCM_TXGLOM_MDESC;
+       conf->deferred_tx_len = 0;
+       conf->dhd_txminmax = 1;
+       conf->txinrx_thres = -1;
+       conf->sd_f2_blocksize = 0;
+       conf->oob_enabled_later = FALSE;
+#endif
+       conf->ampdu_ba_wsize = 0;
+       conf->ampdu_hostreorder = -1;
+       conf->dpc_cpucore = -1;
+       conf->rxf_cpucore = -1;
+       conf->frameburst = -1;
+       conf->deepsleep = FALSE;
+       conf->pm = -1;
+       conf->pm_in_suspend = -1;
+       conf->pm2_sleep_ret = -1;
+       conf->num_different_channels = -1;
+       conf->xmit_in_suspend = TRUE;
+       conf->ap_in_suspend = 0;
+#ifdef IDHCP
+       conf->dhcpc_enable = -1;
+       conf->dhcpd_enable = -1;
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
+       conf->tsq = 10;
+#else
+       conf->tsq = 0;
+#endif
+#ifdef DHDTCPACK_SUPPRESS
+       conf->tcpack_sup_mode = TCPACK_SUP_OFF;
+#endif
+       conf->pktprio8021x = -1;
+       conf->rsdb_mode = -2;
+       conf->vhtmode = -1;
+       conf->autocountry = -1;
+#ifdef IAPSTA_PREINIT
+       memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init));
+       memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config));
+       memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable));
+#endif
+#ifdef CUSTOMER_HW_AMLOGIC
+       dhd_slpauto = FALSE;
+#endif
+#ifdef BCMSDIO
+       if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM43454_CHIP_ID ||
+                       conf->chip == BCM4345_CHIP_ID) {
+               conf->txctl_tmo_fix = 1;
+       }
+#endif
+       if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
+                       conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||
+                       conf->chip == BCM4359_CHIP_ID) {
 #ifdef DHDTCPACK_SUPPRESS
-       conf->tcpack_sup_mode = TCPACK_SUP_OFF;\r
-#endif\r
-       conf->pktprio8021x = -1;\r
-       conf->rsdb_mode = -2;\r
-       conf->vhtmode = -1;\r
-       conf->autocountry = -1;\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
-#ifdef BCMSDIO\r
-       if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) {\r
-               conf->txctl_tmo_fix = 1;\r
-       }\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
-               conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;\r
-#endif\r
-               dhd_rxbound = 64;\r
-               dhd_txbound = 64;\r
-               conf->txbf = 1;\r
-               conf->frameburst = 1;\r
-#ifdef BCMSDIO\r
-               conf->dhd_txminmax = -1;\r
-               conf->txinrx_thres = 128;\r
-               conf->sd_f2_blocksize = 256;\r
-               conf->oob_enabled_later = TRUE;\r
-#endif\r
-       }\r
-\r
-#ifdef BCMSDIO\r
-#if defined(SWTXGLOM)\r
-       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
-                       conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
-                       conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
-               conf->swtxglom = FALSE; // disabled by default\r
-               conf->txglom_ext = TRUE; // enabled by default\r
-               conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled\r
-               conf->txglomsize = 16;\r
-       } else {\r
-               conf->swtxglom = FALSE; // use 1.201.59.x txglom by default\r
-               conf->txglom_ext = FALSE;\r
-       }\r
-\r
-       if (conf->chip == BCM43362_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1680; // fixed value, don't change\r
-               conf->tx_in_rx = FALSE;\r
-               conf->tx_max_offset = 1;\r
-       }\r
-       if (conf->chip == BCM4330_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1680; // fixed value, don't change\r
-               conf->tx_in_rx = FALSE;\r
-               conf->tx_max_offset = 0;\r
-       }\r
-       if (conf->chip == BCM4334_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1684; // fixed value, don't change\r
-               conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle\r
-               conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110\r
-       }\r
-       if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1684; // fixed value, don't change\r
-               conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle\r
-               conf->tx_max_offset = 1;\r
-       }\r
-       if (conf->chip == BCM4324_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1684; // fixed value, don't change\r
-               conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle\r
-               conf->tx_max_offset = 0;\r
-       }\r
-#endif\r
-#if defined(BCMSDIOH_TXGLOM_EXT)\r
-       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
-                       conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
-                       conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
-               conf->txglom_ext = TRUE;\r
-               conf->use_rxchain = 0;\r
-               conf->tx_in_rx = TRUE;\r
-               conf->tx_max_offset = 1;\r
-       } else {\r
-               conf->txglom_ext = FALSE;\r
-       }\r
-       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1680; // fixed value, don't change\r
-               conf->txglomsize = 6;\r
-       }\r
-       if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||\r
-                       conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
-               conf->txglom_bucket_size = 1684; // fixed value, don't change\r
-               conf->txglomsize = 16;\r
-       }\r
-#endif\r
-       if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)\r
-               conf->txglomsize = SDPCM_MAXGLOM_SIZE;\r
-       conf->deferred_tx_len = 0;\r
-#endif\r
-\r
-       return 0;\r
-}\r
-\r
-int\r
-dhd_conf_reset(dhd_pub_t *dhd)\r
-{\r
-#ifdef BCMSDIO\r
-       dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);\r
-       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
-       memset(dhd->conf, 0, sizeof(dhd_conf_t));\r
-       return 0;\r
-}\r
-\r
-int\r
-dhd_conf_attach(dhd_pub_t *dhd)\r
-{\r
-       dhd_conf_t *conf;\r
-\r
-       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
-\r
-       if (dhd->conf != NULL) {\r
-               printf("%s: config is attached before!\n", __FUNCTION__);\r
-               return 0;\r
-       }\r
-       /* Allocate private bus interface state */\r
-       if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {\r
-               CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));\r
-               goto fail;\r
-       }\r
-       memset(conf, 0, sizeof(dhd_conf_t));\r
-\r
-       dhd->conf = conf;\r
-\r
-       return 0;\r
-\r
-fail:\r
-       if (conf != NULL)\r
-               MFREE(dhd->osh, conf, sizeof(dhd_conf_t));\r
-       return BCME_NOMEM;\r
-}\r
-\r
-void\r
-dhd_conf_detach(dhd_pub_t *dhd)\r
-{\r
-       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
-\r
-       if (dhd->conf) {\r
-#ifdef BCMSDIO\r
-               dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);\r
-               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
-               MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));\r
-       }\r
-       dhd->conf = NULL;\r
-}\r
+               conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;
+#endif
+               dhd_rxbound = 128;
+               dhd_txbound = 64;
+               conf->txbf = 1;
+               conf->frameburst = 1;
+#ifdef BCMSDIO
+               conf->dhd_txminmax = -1;
+               conf->txinrx_thres = 128;
+               conf->sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
+               conf->oob_enabled_later = TRUE;
+#ifdef CUSTOMER_HW_AMLOGIC
+               conf->rxf_cpucore = 2;
+#endif
+#endif
+       }
+
+#ifdef BCMSDIO
+#if defined(SWTXGLOM)
+       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
+                       conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
+                       conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+               conf->swtxglom = FALSE; // disabled by default
+               conf->txglom_ext = TRUE; // enabled by default
+               conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled
+               conf->txglomsize = 16;
+       } else {
+               conf->swtxglom = FALSE; // use 1.201.59.x txglom by default
+               conf->txglom_ext = FALSE;
+       }
+
+       if (conf->chip == BCM43362_CHIP_ID) {
+               conf->txglom_bucket_size = 1680; // fixed value, don't change
+               conf->tx_in_rx = FALSE;
+               conf->tx_max_offset = 1;
+       }
+       if (conf->chip == BCM4330_CHIP_ID) {
+               conf->txglom_bucket_size = 1680; // fixed value, don't change
+               conf->tx_in_rx = FALSE;
+               conf->tx_max_offset = 0;
+       }
+       if (conf->chip == BCM4334_CHIP_ID) {
+               conf->txglom_bucket_size = 1684; // fixed value, don't change
+               conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
+               conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110
+       }
+       if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) {
+               conf->txglom_bucket_size = 1684; // fixed value, don't change
+               conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
+               conf->tx_max_offset = 1;
+       }
+       if (conf->chip == BCM4324_CHIP_ID) {
+               conf->txglom_bucket_size = 1684; // fixed value, don't change
+               conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
+               conf->tx_max_offset = 0;
+       }
+#endif
+#if defined(BCMSDIOH_TXGLOM_EXT)
+       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
+                       conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
+                       conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+               conf->txglom_ext = TRUE;
+               conf->use_rxchain = 0;
+               conf->tx_in_rx = TRUE;
+               conf->tx_max_offset = 1;
+       } else {
+               conf->txglom_ext = FALSE;
+       }
+       if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {
+               conf->txglom_bucket_size = 1680; // fixed value, don't change
+               conf->txglomsize = 6;
+       }
+       if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
+                       conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
+               conf->txglom_bucket_size = 1684; // fixed value, don't change
+               conf->txglomsize = 16;
+       }
+#endif
+       if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
+               conf->txglomsize = SDPCM_MAXGLOM_SIZE;
+       conf->deferred_tx_len = 0;
+#endif
+
+       return 0;
+}
+
+int
+dhd_conf_reset(dhd_pub_t *dhd)
+{
+#ifdef BCMSDIO
+       dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);
+       dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
+       dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
+#endif
+       memset(dhd->conf, 0, sizeof(dhd_conf_t));
+       return 0;
+}
+
+int
+dhd_conf_attach(dhd_pub_t *dhd)
+{
+       dhd_conf_t *conf;
+
+       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
+
+       if (dhd->conf != NULL) {
+               printf("%s: config is attached before!\n", __FUNCTION__);
+               return 0;
+       }
+       /* Allocate private bus interface state */
+       if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {
+               CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));
+               goto fail;
+       }
+       memset(conf, 0, sizeof(dhd_conf_t));
+
+       dhd->conf = conf;
+
+       return 0;
+
+fail:
+       if (conf != NULL)
+               MFREE(dhd->osh, conf, sizeof(dhd_conf_t));
+       return BCME_NOMEM;
+}
+
+void
+dhd_conf_detach(dhd_pub_t *dhd)
+{
+       CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
+
+       if (dhd->conf) {
+#ifdef BCMSDIO
+               dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);
+               dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
+               dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
+#endif
+               MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));
+       }
+       dhd->conf = NULL;
+}
diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej b/bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej
deleted file mode 100644 (file)
index c5d7f90..0000000
+++ /dev/null
@@ -1,5140 +0,0 @@
---- bcmdhd.1.363.59.144.x.cn/dhd_config.c
-+++ bcmdhd.1.363.59.144.x.cn/dhd_config.c
-@@ -1,2581 +1,2581 @@
--\r
--#include <typedefs.h>\r
--#include <osl.h>\r
--\r
--#include <bcmutils.h>\r
--#include <hndsoc.h>\r
--#include <bcmsdbus.h>\r
-+
-+#include <typedefs.h>
-+#include <osl.h>
-+
-+#include <bcmutils.h>
-+#include <hndsoc.h>
-+#include <bcmsdbus.h>
- #if defined(HW_OOB) || defined(FORCE_WOWLAN)
--#include <bcmdefs.h>\r
--#include <bcmsdh.h>\r
--#include <sdio.h>\r
--#include <sbchipc.h>\r
--#endif\r
--\r
--#include <dhd_config.h>\r
--#include <dhd_dbg.h>\r
--\r
-+#include <bcmdefs.h>
-+#include <bcmsdh.h>
-+#include <sdio.h>
-+#include <sbchipc.h>
-+#endif
-+
-+#include <dhd_config.h>
-+#include <dhd_dbg.h>
-+
- /* message levels */
--#define CONFIG_ERROR_LEVEL    0x0001\r
--#define CONFIG_TRACE_LEVEL    0x0002\r
-+#define CONFIG_ERROR_LEVEL    0x0001
-+#define CONFIG_TRACE_LEVEL    0x0002
--uint config_msg_level = CONFIG_ERROR_LEVEL;\r
-+uint config_msg_level = CONFIG_ERROR_LEVEL;
--#define CONFIG_ERROR(x) \\r
-+#define CONFIG_ERROR(x) \
-       do { \
--              if (config_msg_level & CONFIG_ERROR_LEVEL) { \\r
--                      printk(KERN_ERR "CONFIG-ERROR) ");      \\r
-+              if (config_msg_level & CONFIG_ERROR_LEVEL) { \
-+                      printk(KERN_ERR "CONFIG-ERROR) ");      \
-                       printk x; \
-               } \
-       } while (0)
--#define CONFIG_TRACE(x) \\r
-+#define CONFIG_TRACE(x) \
-       do { \
--              if (config_msg_level & CONFIG_TRACE_LEVEL) { \\r
--                      printk(KERN_ERR "CONFIG-TRACE) ");      \\r
-+              if (config_msg_level & CONFIG_TRACE_LEVEL) { \
-+                      printk(KERN_ERR "CONFIG-TRACE) ");      \
-                       printk x; \
-               } \
--      } while (0)\r
--\r
--#define MAXSZ_BUF             1000\r
--#define       MAXSZ_CONFIG    4096\r
--\r
--#define FW_TYPE_STA     0\r
--#define FW_TYPE_APSTA   1\r
--#define FW_TYPE_P2P     2\r
--#define FW_TYPE_ES      3\r
--#define FW_TYPE_MFG     4\r
--#define FW_TYPE_G       0\r
--#define FW_TYPE_AG      1\r
--\r
--#ifdef CONFIG_PATH_AUTO_SELECT\r
--#ifdef BCMSDIO\r
--#define CONFIG_BCM4330B2 "config_40183b2.txt"\r
--#define CONFIG_BCM43362A0 "config_40181a0.txt"\r
--#define CONFIG_BCM43362A2 "config_40181a2.txt"\r
--#define CONFIG_BCM43438A0 "config_43438a0.txt"\r
--#define CONFIG_BCM43438A1 "config_43438a1.txt"\r
--#define CONFIG_BCM43436B0 "config_43436b0.txt"\r
--#define CONFIG_BCM4334B1 "config_4334b1.txt"\r
--#define CONFIG_BCM43341B0 "config_43341b0.txt"\r
--#define CONFIG_BCM43241B4 "config_43241b4.txt"\r
--#define CONFIG_BCM4339A0 "config_4339a0.txt"\r
--#define CONFIG_BCM43455C0 "config_43455c0.txt"\r
--#define CONFIG_BCM43456C5 "config_43456c5.txt"\r
--#define CONFIG_BCM4354A1 "config_4354a1.txt"\r
--#endif\r
--#define CONFIG_BCM4356A2 "config_4356a2.txt"\r
--#define CONFIG_BCM4358A3 "config_4358a3.txt"\r
--#define CONFIG_BCM4359B1 "config_4359b1.txt"\r
--#define CONFIG_BCM4359C0 "config_4359c0.txt"\r
--#endif\r
--\r
--#ifdef BCMSDIO\r
--#define SBSDIO_CIS_SIZE_LIMIT         0x200           /* maximum bytes in one CIS */\r
--\r
--#define FW_BCM4330B2 "fw_bcm40183b2"\r
--#define FW_BCM4330B2_AG "fw_bcm40183b2_ag"\r
--#define FW_BCM43362A0 "fw_bcm40181a0"\r
--#define FW_BCM43362A2 "fw_bcm40181a2"\r
--#define FW_BCM4334B1 "fw_bcm4334b1_ag"\r
--#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_BCM43341B1 "fw_bcm43341b0_ag"\r
--#define FW_BCM43241B4 "fw_bcm43241b4_ag"\r
--#define FW_BCM4339A0 "fw_bcm4339a0_ag"\r
--#define FW_BCM43455C0 "fw_bcm43455c0_ag"\r
--#define FW_BCM43456C5 "fw_bcm43456c5_ag"\r
--#define FW_BCM4354A1 "fw_bcm4354a1_ag"\r
--#define FW_BCM4356A2 "fw_bcm4356a2_ag"\r
--#define FW_BCM4358A3 "fw_bcm4358a3_ag"\r
--#define FW_BCM4359B1 "fw_bcm4359b1_ag"\r
--#define FW_BCM4359C0 "fw_bcm4359c0_ag"\r
--\r
--#define CLM_BCM43012B0 "clm_bcm43012b0"\r
--#endif\r
--#ifdef BCMPCIE\r
--#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"\r
--#endif\r
--\r
-+      } while (0)
-+
-+#define MAXSZ_BUF             1000
-+#define       MAXSZ_CONFIG    4096
-+
-+#define FW_TYPE_STA     0
-+#define FW_TYPE_APSTA   1
-+#define FW_TYPE_P2P     2
-+#define FW_TYPE_ES      3
-+#define FW_TYPE_MFG     4
-+#define FW_TYPE_G       0
-+#define FW_TYPE_AG      1
-+
-+#ifdef CONFIG_PATH_AUTO_SELECT
-+#ifdef BCMSDIO
-+#define CONFIG_BCM4330B2 "config_40183b2.txt"
-+#define CONFIG_BCM43362A0 "config_40181a0.txt"
-+#define CONFIG_BCM43362A2 "config_40181a2.txt"
-+#define CONFIG_BCM43438A0 "config_43438a0.txt"
-+#define CONFIG_BCM43438A1 "config_43438a1.txt"
-+#define CONFIG_BCM43436B0 "config_43436b0.txt"
-+#define CONFIG_BCM4334B1 "config_4334b1.txt"
-+#define CONFIG_BCM43341B0 "config_43341b0.txt"
-+#define CONFIG_BCM43241B4 "config_43241b4.txt"
-+#define CONFIG_BCM4339A0 "config_4339a0.txt"
-+#define CONFIG_BCM43455C0 "config_43455c0.txt"
-+#define CONFIG_BCM43456C5 "config_43456c5.txt"
-+#define CONFIG_BCM4354A1 "config_4354a1.txt"
-+#endif
-+#define CONFIG_BCM4356A2 "config_4356a2.txt"
-+#define CONFIG_BCM4358A3 "config_4358.txt"
-+#define CONFIG_BCM4359B1 "config_4359b1.txt"
-+#define CONFIG_BCM4359C0 "config_4359c0.txt"
-+#endif
-+
-+#ifdef BCMSDIO
-+#define SBSDIO_CIS_SIZE_LIMIT         0x200           /* maximum bytes in one CIS */
-+
-+#define FW_BCM4330B2 "fw_bcm40183b2"
-+#define FW_BCM4330B2_AG "fw_bcm40183b2_ag"
-+#define FW_BCM43362A0 "fw_bcm40181a0"
-+#define FW_BCM43362A2 "fw_bcm40181a2"
-+#define FW_BCM4334B1 "fw_bcm4334b1_ag"
-+#define FW_BCM43438A0 "fw_bcm43438a0"
-+#define FW_BCM43438A1 "fw_bcm43438a1"
-+#define FW_BCM43436B0 "fw_bcm43436b0"
-+#define FW_BCM43012B0 "fw_bcm43012b0"
-+#define FW_BCM43341B1 "fw_bcm43341b0_ag"
-+#define FW_BCM43241B4 "fw_bcm43241b4_ag"
-+#define FW_BCM4339A0 "fw_bcm4339a0_ag"
-+#define FW_BCM43455C0 "fw_bcm43455c0_ag"
-+#define FW_BCM43456C5 "fw_bcm43456c5_ag"
-+#define FW_BCM4354A1 "fw_bcm4354a1_ag"
-+#define FW_BCM4356A2 "fw_bcm4356a2_ag"
-+#define FW_BCM4358A3 "fw_bcm4358_ag"
-+#define FW_BCM4359B1 "fw_bcm4359b1_ag"
-+#define FW_BCM4359C0 "fw_bcm4359c0_ag"
-+
-+#define CLM_BCM43012B0 "clm_bcm43012b0"
-+#endif
-+#ifdef BCMPCIE
-+#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"
-+#endif
-+
- #define htod32(i) i
- #define htod16(i) i
- #define dtoh32(i) i
- #define dtoh16(i) i
- #define htodchanspec(i) i
--#define dtohchanspec(i) i\r
--\r
--#ifdef BCMSDIO\r
--void\r
--dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)\r
--{\r
--      int i;\r
--\r
--      CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
--      if (mac_list->m_mac_list_head) {\r
--              for (i=0; i<mac_list->count; i++) {\r
--                      if (mac_list->m_mac_list_head[i].mac) {\r
--                              CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac));\r
--                              kfree(mac_list->m_mac_list_head[i].mac);\r
--                      }\r
--              }\r
--              CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head));\r
--              kfree(mac_list->m_mac_list_head);\r
--      }\r
--      mac_list->count = 0;\r
--}\r
--\r
--void\r
--dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)\r
--{\r
--      CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
--\r
--      if (chip_nv_list->m_chip_nv_path_head) {\r
--              CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head));\r
--              kfree(chip_nv_list->m_chip_nv_path_head);\r
--      }\r
--      chip_nv_list->count = 0;\r
--}\r
--\r
--#if defined(HW_OOB) || defined(FORCE_WOWLAN)\r
--void\r
--dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)\r
--{\r
--      uint32 gpiocontrol, addr;\r
--\r
--      if (CHIPID(chip) == BCM43362_CHIP_ID) {\r
--              printf("%s: Enable HW OOB for 43362\n", __FUNCTION__);\r
--              addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);\r
--              gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);\r
--              gpiocontrol |= 0x2;\r
--              bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);\r
--              bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);\r
--              bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);\r
--              bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);\r
--      }\r
--}\r
--#endif\r
--\r
--int\r
--dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac)\r
--{\r
--      int i, err = -1;\r
--      uint8 *ptr = 0;\r
--      unsigned char tpl_code, tpl_link='\0';\r
--      uint8 header[3] = {0x80, 0x07, 0x19};\r
--      uint8 *cis;\r
--\r
--      if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) {\r
--              CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__));\r
--              return err;\r
--      }\r
--      bzero(cis, SBSDIO_CIS_SIZE_LIMIT);\r
--\r
--      if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) {\r
--              CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err));\r
--              MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);\r
--              return err;\r
--      }\r
--      err = -1; // reset err;\r
--      ptr = cis;\r
--      do {\r
--              /* 0xff means we're done */\r
--              tpl_code = *ptr;\r
--              ptr++;\r
--              if (tpl_code == 0xff)\r
--                      break;\r
--\r
--              /* null entries have no link field or data */\r
--              if (tpl_code == 0x00)\r
--                      continue;\r
--\r
--              tpl_link = *ptr;\r
--              ptr++;\r
--              /* a size of 0xff also means we're done */\r
--              if (tpl_link == 0xff)\r
--                      break;\r
--              if (config_msg_level & CONFIG_TRACE_LEVEL) {\r
--                      printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n",\r
--                              __FUNCTION__, tpl_code, tpl_link, *ptr);\r
--                      printk("%s: value:", __FUNCTION__);\r
--                      for (i=0; i<tpl_link-1; i++) {\r
--                              printk("%02x ", ptr[i+1]);\r
--                              if ((i+1) % 16 == 0)\r
--                                      printk("\n");\r
--                      }\r
--                      printk("\n");\r
--              }\r
--\r
--              if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19)\r
--                      break;\r
--\r
--              ptr += tpl_link;\r
--      } while (1);\r
--\r
--      if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19) {\r
--              /* Normal OTP */\r
--              memcpy(mac, ptr+1, 6);\r
--              err = 0;\r
--      } else {\r
--              ptr = cis;\r
--              /* Special OTP */\r
--              if (bcmsdh_reg_read(sdh, SI_ENUM_BASE, 4) == 0x16044330) {\r
--                      for (i=0; i<SBSDIO_CIS_SIZE_LIMIT; i++) {\r
--                              if (!memcmp(header, ptr, 3)) {\r
--                                      memcpy(mac, ptr+3, 6);\r
--                                      err = 0;\r
--                                      break;\r
--                              }\r
--                              ptr++;\r
--                      }\r
--              }\r
--      }\r
--\r
--      ASSERT(cis);\r
--      MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);\r
--\r
--      return err;\r
--}\r
--\r
--void\r
--dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path)\r
--{\r
--      int i, j;\r
--      uint8 mac[6]={0};\r
--      int fw_num=0, mac_num=0;\r
--      uint32 oui, nic;\r
--      wl_mac_list_t *mac_list;\r
--      wl_mac_range_t *mac_range;\r
--      char *pfw_name;\r
--      int fw_type, fw_type_new;\r
--\r
--      mac_list = dhd->conf->fw_by_mac.m_mac_list_head;\r
--      fw_num = dhd->conf->fw_by_mac.count;\r
--      if (!mac_list || !fw_num)\r
--              return;\r
--\r
--      if (dhd_conf_get_mac(dhd, sdh, mac)) {\r
--              CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));\r
--              return;\r
--      }\r
--      oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);\r
--      nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(fw_path);\r
--      while (i > 0) {\r
--              if (fw_path[i] == '/') break;\r
--              i--;\r
--      }\r
--      pfw_name = &fw_path[i+1];\r
--      fw_type = (strstr(pfw_name, "_mfg") ?\r
--              FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ?\r
--              FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ?\r
--              FW_TYPE_P2P : FW_TYPE_STA)));\r
--\r
--      for (i=0; i<fw_num; i++) {\r
--              mac_num = mac_list[i].count;\r
--              mac_range = mac_list[i].mac;\r
--              fw_type_new = (strstr(mac_list[i].name, "_mfg") ?\r
--                      FW_TYPE_MFG : (strstr(mac_list[i].name, "_apsta") ?\r
--                      FW_TYPE_APSTA : (strstr(mac_list[i].name, "_p2p") ?\r
--                      FW_TYPE_P2P : FW_TYPE_STA)));\r
--              if (fw_type != fw_type_new) {\r
--                      printf("%s: fw_typ=%d != fw_type_new=%d\n", __FUNCTION__, fw_type, fw_type_new);\r
--                      continue;\r
--              }\r
--              for (j=0; j<mac_num; j++) {\r
--                      if (oui == mac_range[j].oui) {\r
--                              if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {\r
--                                      strcpy(pfw_name, mac_list[i].name);\r
--                                      printf("%s: matched oui=0x%06X, nic=0x%06X\n",\r
--                                              __FUNCTION__, oui, nic);\r
--                                      printf("%s: fw_path=%s\n", __FUNCTION__, fw_path);\r
--                                      return;\r
--                              }\r
--                      }\r
--              }\r
--      }\r
--}\r
--\r
--void\r
--dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)\r
--{\r
--      int i, j;\r
--      uint8 mac[6]={0};\r
--      int nv_num=0, mac_num=0;\r
--      uint32 oui, nic;\r
--      wl_mac_list_t *mac_list;\r
--      wl_mac_range_t *mac_range;\r
--      char *pnv_name;\r
--\r
--      mac_list = dhd->conf->nv_by_mac.m_mac_list_head;\r
--      nv_num = dhd->conf->nv_by_mac.count;\r
--      if (!mac_list || !nv_num)\r
--              return;\r
--\r
--      if (dhd_conf_get_mac(dhd, sdh, mac)) {\r
--              CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));\r
--              return;\r
--      }\r
--      oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);\r
--      nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(nv_path);\r
--      while (i > 0) {\r
--              if (nv_path[i] == '/') break;\r
--              i--;\r
--      }\r
--      pnv_name = &nv_path[i+1];\r
--\r
--      for (i=0; i<nv_num; i++) {\r
--              mac_num = mac_list[i].count;\r
--              mac_range = mac_list[i].mac;\r
--              for (j=0; j<mac_num; j++) {\r
--                      if (oui == mac_range[j].oui) {\r
--                              if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {\r
--                                      strcpy(pnv_name, mac_list[i].name);\r
--                                      printf("%s: matched oui=0x%06X, nic=0x%06X\n",\r
--                                              __FUNCTION__, oui, nic);\r
--                                      printf("%s: nv_path=%s\n", __FUNCTION__, nv_path);\r
--                                      return;\r
--                              }\r
--                      }\r
--              }\r
--      }\r
--}\r
--#endif\r
--\r
--void\r
--dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)\r
--{\r
--      int fw_type, ag_type;\r
--      uint chip, chiprev;\r
--      int i;\r
--      char fw_tail[20];\r
--\r
--      chip = dhd->conf->chip;\r
--      chiprev = dhd->conf->chiprev;\r
--\r
--      if (fw_path[0] == '\0') {\r
--#ifdef CONFIG_BCMDHD_FW_PATH\r
--              bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);\r
--              if (fw_path[0] == '\0')\r
--#endif\r
--              {\r
--                      printf("firmware path is null\n");\r
--                      return;\r
--              }\r
--      }\r
--#ifndef FW_PATH_AUTO_SELECT\r
--      return;\r
--#endif\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(fw_path);\r
--      while (i > 0) {\r
--              if (fw_path[i] == '/') break;\r
--              i--;\r
--      }\r
--#ifdef BAND_AG\r
--      ag_type = FW_TYPE_AG;\r
--#else\r
--      ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;\r
--#endif\r
--      fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG :\r
--              (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA :\r
--              (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P :\r
--              (strstr(&fw_path[i], "_es") ? FW_TYPE_ES :\r
--              FW_TYPE_STA))));\r
--\r
--      if (fw_type == FW_TYPE_STA)\r
--              strcpy(fw_tail, ".bin");\r
--      else if (fw_type == FW_TYPE_APSTA)\r
--              strcpy(fw_tail, "_apsta.bin");\r
--      else if (fw_type == FW_TYPE_P2P)\r
--              strcpy(fw_tail, "_p2p.bin");\r
--      else if (fw_type == FW_TYPE_ES)\r
--              strcpy(fw_tail, "_es.bin");\r
--      else if (fw_type == FW_TYPE_MFG)\r
--              strcpy(fw_tail, "_mfg.bin");\r
--\r
--      switch (chip) {\r
--#ifdef BCMSDIO\r
--              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
--                      } else {\r
--                              if (chiprev == BCM4330B2_CHIP_REV)\r
--                                      strcpy(&fw_path[i+1], 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
--                      else\r
--                              strcpy(&fw_path[i+1], FW_BCM43362A2);\r
--                      break;\r
--              case BCM43430_CHIP_ID:\r
--                      if (chiprev == BCM43430A0_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM43438A0);\r
--                      else if (chiprev == BCM43430A1_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM43438A1);\r
--                      else if (chiprev == BCM43430A2_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM43436B0);\r
--                      break;\r
--              case BCM43012_CHIP_ID:\r
--                      if (chiprev == BCM43012B0_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM43012B0);\r
--              case BCM4334_CHIP_ID:\r
--                      if (chiprev == BCM4334B1_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], 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
--                      break;\r
--              case BCM4324_CHIP_ID:\r
--                      if (chiprev == BCM43241B4_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM43241B4);\r
--                      break;\r
--              case BCM4335_CHIP_ID:\r
--                      if (chiprev == BCM4335A0_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], 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 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
--                      break;\r
--              case BCM4354_CHIP_ID:\r
--                      if (chiprev == BCM4354A1_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM4354A1);\r
--                      else if (chiprev == BCM4356A2_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], 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
--                      break;\r
--              case BCM43569_CHIP_ID:\r
--                      if (chiprev == BCM4358A3_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM4358A3);\r
--                      break;\r
--              case BCM4359_CHIP_ID:\r
--                      if (chiprev == BCM4359B1_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], FW_BCM4359B1);\r
--                      else if (chiprev == BCM4359C0_CHIP_REV)\r
--                              strcpy(&fw_path[i+1], 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
--                      break;\r
--#endif\r
--              default:\r
--                      strcpy(&fw_path[i+1], "fw_bcmdhd");\r
--      }\r
--      strcat(fw_path, fw_tail);\r
--\r
--      CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path));\r
--}\r
--\r
--void\r
--dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)\r
--{\r
--      uint chip, chiprev;\r
--      int i;\r
--      char fw_tail[20];\r
--\r
--      chip = dhd->conf->chip;\r
--      chiprev = dhd->conf->chiprev;\r
--\r
--      if (clm_path[0] == '\0') {\r
--              printf("clm path is null\n");\r
--              return;\r
--      }\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(clm_path);\r
--      while (i > 0) {\r
--              if (clm_path[i] == '/') break;\r
--              i--;\r
--      }\r
--\r
--      strcpy(fw_tail, ".blob");\r
--\r
--      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
--                      break;\r
--#endif\r
--              default:\r
--                      strcpy(&clm_path[i+1], "clm_bcmdhd");\r
--      }\r
--      strcat(clm_path, fw_tail);\r
--\r
--      CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_path));\r
--}\r
--\r
--void\r
--dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)\r
--{\r
--      int matched=-1;\r
--      uint chip, chiprev;\r
--      int i;\r
--\r
--      chip = dhd->conf->chip;\r
--      chiprev = dhd->conf->chiprev;\r
--\r
--      for (i=0; i<dhd->conf->nv_by_chip.count; i++) {\r
--              if (chip==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&\r
--                              chiprev==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {\r
--                      matched = i;\r
--                      break;\r
--              }\r
--      }\r
--      if (matched < 0)\r
--              return;\r
--\r
--      if (nv_path[0] == '\0') {\r
--#ifdef CONFIG_BCMDHD_NVRAM_PATH\r
--              bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);\r
--              if (nv_path[0] == '\0')\r
--#endif\r
--              {\r
--                      printf("nvram path is null\n");\r
--                      return;\r
--              }\r
--      }\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(nv_path);\r
-+#define dtohchanspec(i) i
-+
-+#ifdef BCMSDIO
-+void
-+dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)
-+{
-+      int i;
-+
-+      CONFIG_TRACE(("%s called\n", __FUNCTION__));
-+      if (mac_list->m_mac_list_head) {
-+              for (i=0; i<mac_list->count; i++) {
-+                      if (mac_list->m_mac_list_head[i].mac) {
-+                              CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac));
-+                              kfree(mac_list->m_mac_list_head[i].mac);
-+                      }
-+              }
-+              CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head));
-+              kfree(mac_list->m_mac_list_head);
-+      }
-+      mac_list->count = 0;
-+}
-+
-+void
-+dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)
-+{
-+      CONFIG_TRACE(("%s called\n", __FUNCTION__));
-+
-+      if (chip_nv_list->m_chip_nv_path_head) {
-+              CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head));
-+              kfree(chip_nv_list->m_chip_nv_path_head);
-+      }
-+      chip_nv_list->count = 0;
-+}
-+
-+#if defined(HW_OOB) || defined(FORCE_WOWLAN)
-+void
-+dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)
-+{
-+      uint32 gpiocontrol, addr;
-+
-+      if (CHIPID(chip) == BCM43362_CHIP_ID) {
-+              printf("%s: Enable HW OOB for 43362\n", __FUNCTION__);
-+              addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);
-+              gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);
-+              gpiocontrol |= 0x2;
-+              bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);
-+              bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);
-+              bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);
-+              bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);
-+      }
-+}
-+#endif
-+
-+int
-+dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac)
-+{
-+      int i, err = -1;
-+      uint8 *ptr = 0;
-+      unsigned char tpl_code, tpl_link='\0';
-+      uint8 header[3] = {0x80, 0x07, 0x19};
-+      uint8 *cis;
-+
-+      if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) {
-+              CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__));
-+              return err;
-+      }
-+      bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
-+
-+      if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) {
-+              CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err));
-+              MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
-+              return err;
-+      }
-+      err = -1; // reset err;
-+      ptr = cis;
-+      do {
-+              /* 0xff means we're done */
-+              tpl_code = *ptr;
-+              ptr++;
-+              if (tpl_code == 0xff)
-+                      break;
-+
-+              /* null entries have no link field or data */
-+              if (tpl_code == 0x00)
-+                      continue;
-+
-+              tpl_link = *ptr;
-+              ptr++;
-+              /* a size of 0xff also means we're done */
-+              if (tpl_link == 0xff)
-+                      break;
-+              if (config_msg_level & CONFIG_TRACE_LEVEL) {
-+                      printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n",
-+                              __FUNCTION__, tpl_code, tpl_link, *ptr);
-+                      printk("%s: value:", __FUNCTION__);
-+                      for (i=0; i<tpl_link-1; i++) {
-+                              printk("%02x ", ptr[i+1]);
-+                              if ((i+1) % 16 == 0)
-+                                      printk("\n");
-+                      }
-+                      printk("\n");
-+              }
-+
-+              if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19)
-+                      break;
-+
-+              ptr += tpl_link;
-+      } while (1);
-+
-+      if (tpl_code == 0x80 && tpl_link == 0x07 && *ptr == 0x19) {
-+              /* Normal OTP */
-+              memcpy(mac, ptr+1, 6);
-+              err = 0;
-+      } else {
-+              ptr = cis;
-+              /* Special OTP */
-+              if (bcmsdh_reg_read(sdh, SI_ENUM_BASE, 4) == 0x16044330) {
-+                      for (i=0; i<SBSDIO_CIS_SIZE_LIMIT; i++) {
-+                              if (!memcmp(header, ptr, 3)) {
-+                                      memcpy(mac, ptr+3, 6);
-+                                      err = 0;
-+                                      break;
-+                              }
-+                              ptr++;
-+                      }
-+              }
-+      }
-+
-+      ASSERT(cis);
-+      MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
-+
-+      return err;
-+}
-+
-+void
-+dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path)
-+{
-+      int i, j;
-+      uint8 mac[6]={0};
-+      int fw_num=0, mac_num=0;
-+      uint32 oui, nic;
-+      wl_mac_list_t *mac_list;
-+      wl_mac_range_t *mac_range;
-+      char *pfw_name;
-+      int fw_type, fw_type_new;
-+
-+      mac_list = dhd->conf->fw_by_mac.m_mac_list_head;
-+      fw_num = dhd->conf->fw_by_mac.count;
-+      if (!mac_list || !fw_num)
-+              return;
-+
-+      if (dhd_conf_get_mac(dhd, sdh, mac)) {
-+              CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));
-+              return;
-+      }
-+      oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
-+      nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
-+
-+      /* find out the last '/' */
-+      i = strlen(fw_path);
-       while (i > 0) {
--              if (nv_path[i] == '/') break;\r
--              i--;\r
--      }\r
--\r
--      strcpy(&nv_path[i+1], 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
--\r
--void\r
--dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path)\r
--{\r
--      int i;\r
--\r
--      if (src_path[0] == '\0') {\r
--              printf("src_path is null\n");\r
--              return;\r
--      } else\r
--              strcpy(dst_path, src_path);\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(dst_path);\r
-+              if (fw_path[i] == '/') break;
-+              i--;
-+      }
-+      pfw_name = &fw_path[i+1];
-+      fw_type = (strstr(pfw_name, "_mfg") ?
-+              FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ?
-+              FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ?
-+              FW_TYPE_P2P : FW_TYPE_STA)));
-+
-+      for (i=0; i<fw_num; i++) {
-+              mac_num = mac_list[i].count;
-+              mac_range = mac_list[i].mac;
-+              fw_type_new = (strstr(mac_list[i].name, "_mfg") ?
-+                      FW_TYPE_MFG : (strstr(mac_list[i].name, "_apsta") ?
-+                      FW_TYPE_APSTA : (strstr(mac_list[i].name, "_p2p") ?
-+                      FW_TYPE_P2P : FW_TYPE_STA)));
-+              if (fw_type != fw_type_new) {
-+                      printf("%s: fw_typ=%d != fw_type_new=%d\n", __FUNCTION__, fw_type, fw_type_new);
-+                      continue;
-+              }
-+              for (j=0; j<mac_num; j++) {
-+                      if (oui == mac_range[j].oui) {
-+                              if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
-+                                      strcpy(pfw_name, mac_list[i].name);
-+                                      printf("%s: matched oui=0x%06X, nic=0x%06X\n",
-+                                              __FUNCTION__, oui, nic);
-+                                      printf("%s: fw_path=%s\n", __FUNCTION__, fw_path);
-+                                      return;
-+                              }
-+                      }
-+              }
-+      }
-+}
-+
-+void
-+dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path)
-+{
-+      int i, j;
-+      uint8 mac[6]={0};
-+      int nv_num=0, mac_num=0;
-+      uint32 oui, nic;
-+      wl_mac_list_t *mac_list;
-+      wl_mac_range_t *mac_range;
-+      char *pnv_name;
-+
-+      mac_list = dhd->conf->nv_by_mac.m_mac_list_head;
-+      nv_num = dhd->conf->nv_by_mac.count;
-+      if (!mac_list || !nv_num)
-+              return;
-+
-+      if (dhd_conf_get_mac(dhd, sdh, mac)) {
-+              CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__));
-+              return;
-+      }
-+      oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
-+      nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
-+
-+      /* find out the last '/' */
-+      i = strlen(nv_path);
-       while (i > 0) {
--              if (dst_path[i] == '/') break;\r
--              i--;\r
--      }\r
--      strcpy(&dst_path[i+1], dst_name);\r
--\r
--      CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));\r
--}\r
--\r
--#ifdef CONFIG_PATH_AUTO_SELECT\r
--void\r
--dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)\r
--{\r
--      uint chip, chiprev;\r
--      int i;\r
--\r
--      chip = dhd->conf->chip;\r
--      chiprev = dhd->conf->chiprev;\r
--\r
--      if (conf_path[0] == '\0') {\r
--              printf("config path is null\n");\r
--              return;\r
--      }\r
--\r
--      /* find out the last '/' */\r
--      i = strlen(conf_path);\r
--      while (i > 0) {\r
--              if (conf_path[i] == '/') break;\r
--              i--;\r
--      }\r
--\r
--      switch (chip) {\r
--#ifdef BCMSDIO\r
--              case BCM4330_CHIP_ID:\r
--                      if (chiprev == BCM4330B2_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM4330B2);\r
--                      break;\r
--              case BCM43362_CHIP_ID:\r
--                      if (chiprev == BCM43362A0_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM43362A0);\r
--                      else\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM43362A2);\r
--                      break;\r
--              case BCM43430_CHIP_ID:\r
--                      if (chiprev == BCM43430A0_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM43438A0);\r
--                      else if (chiprev == BCM43430A1_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM43438A1);\r
--                      else if (chiprev == BCM43430A2_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM43436B0);\r
--                      break;\r
--              case BCM4334_CHIP_ID:\r
--                      if (chiprev == BCM4334B1_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], 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
--                      break;\r
--              case BCM4324_CHIP_ID:\r
--                      if (chiprev == BCM43241B4_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM43241B4);\r
--                      break;\r
--              case BCM4335_CHIP_ID:\r
--                      if (chiprev == BCM4335A0_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], 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
--                      break;\r
--              case BCM4339_CHIP_ID:\r
--                      if (chiprev == BCM4339A0_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM4339A0);\r
--                      break;\r
--              case BCM4354_CHIP_ID:\r
--                      if (chiprev == BCM4354A1_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM4354A1);\r
--                      else if (chiprev == BCM4356A2_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], 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
--                      break;\r
--              case BCM43569_CHIP_ID:\r
--                      if (chiprev == BCM4358A3_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM4358A3);\r
--                      break;\r
--              case BCM4359_CHIP_ID:\r
--                      if (chiprev == BCM4359B1_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], CONFIG_BCM4359B1);\r
--                      else if (chiprev == BCM4359C0_CHIP_REV)\r
--                              strcpy(&conf_path[i+1], 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
--                      break;\r
--#endif\r
--      }\r
--\r
--      CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path));\r
--}\r
--#endif\r
--\r
--int\r
--dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,\r
--      int def, bool down)\r
--{\r
--      int ret = -1;\r
--      char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */\r
--\r
--      if (val >= def) {\r
--              if (down) {\r
--                      if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
--                              CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));\r
--              }\r
--              if (cmd == WLC_SET_VAR) {\r
--                      printf("%s: set %s %d\n", __FUNCTION__, name, val);\r
--                      bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));\r
--                      if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
--                              CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
--              } else {\r
--                      printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);\r
--                      if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)\r
--                              CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
--              }\r
--      }\r
--\r
--      return ret;\r
--}\r
--\r
--int\r
--dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,\r
--      int len, bool down)\r
--{\r
--      char iovbuf[WLC_IOCTL_SMLEN];\r
--      int ret = -1;\r
--\r
--      if (down) {\r
--              if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
--                      CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));\r
--      }\r
--\r
--      if (cmd == WLC_SET_VAR) {\r
--              bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));\r
--              if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
--                      CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
--      } else {\r
--              if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)\r
--                      CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));\r
--      }\r
--\r
--      return ret;\r
--}\r
--\r
--int\r
--dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)\r
--{\r
--      char iovbuf[WLC_IOCTL_SMLEN];\r
--      int ret = -1;\r
--\r
--      if (cmd == WLC_GET_VAR) {\r
--              if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {\r
--                      ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);\r
--                      if (!ret) {\r
--                              memcpy(buf, iovbuf, len);\r
--                      } else {\r
--                              CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));\r
--                      }\r
--              } else {\r
--                      CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));\r
--              }\r
--      } else {\r
--              ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);\r
--              if (ret < 0)\r
--                      CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));\r
--      }\r
--\r
--      return ret;\r
--}\r
--\r
--uint\r
--dhd_conf_get_band(dhd_pub_t *dhd)\r
--{\r
--      uint band = WLC_BAND_AUTO;\r
--\r
--      if (dhd && dhd->conf)\r
--              band = dhd->conf->band;\r
--      else\r
--              CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\r
--\r
--      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
--      int bcmerror = -1;\r
--\r
--      memset(cspec, 0, sizeof(wl_country_t));\r
--      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
--{\r
--      int bcmerror = -1, i;\r
--      struct dhd_conf *conf = dhd->conf;\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
--                      printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
--                      return 0;\r
--              }\r
--      }\r
--\r
--      return bcmerror;\r
--}\r
--\r
--int\r
--dhd_conf_fix_country(dhd_pub_t *dhd)\r
--{\r
--      int bcmerror = -1;\r
--      uint band;\r
--      wl_uint32_list_t *list;\r
--      u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];\r
--\r
--      if (!(dhd && dhd->conf)) {\r
--              return bcmerror;\r
--      }\r
--
--      memset(valid_chan_list, 0, sizeof(valid_chan_list));\r
-+              if (nv_path[i] == '/') break;
-+              i--;
-+      }
-+      pnv_name = &nv_path[i+1];
-+
-+      for (i=0; i<nv_num; i++) {
-+              mac_num = mac_list[i].count;
-+              mac_range = mac_list[i].mac;
-+              for (j=0; j<mac_num; j++) {
-+                      if (oui == mac_range[j].oui) {
-+                              if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
-+                                      strcpy(pnv_name, mac_list[i].name);
-+                                      printf("%s: matched oui=0x%06X, nic=0x%06X\n",
-+                                              __FUNCTION__, oui, nic);
-+                                      printf("%s: nv_path=%s\n", __FUNCTION__, nv_path);
-+                                      return;
-+                              }
-+                      }
-+              }
-+      }
-+}
-+#endif
-+
-+void
-+dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
-+{
-+      int fw_type, ag_type;
-+      uint chip, chiprev;
-+      int i;
-+      char fw_tail[20];
-+
-+      chip = dhd->conf->chip;
-+      chiprev = dhd->conf->chiprev;
-+
-+      if (fw_path[0] == '\0') {
-+#ifdef CONFIG_BCMDHD_FW_PATH
-+              bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
-+              if (fw_path[0] == '\0')
-+#endif
-+              {
-+                      printf("firmware path is null\n");
-+                      return;
-+              }
-+      }
-+#ifndef FW_PATH_AUTO_SELECT
-+      return;
-+#endif
-+
-+      /* find out the last '/' */
-+      i = strlen(fw_path);
-+      while (i > 0) {
-+              if (fw_path[i] == '/') break;
-+              i--;
-+      }
-+#ifdef BAND_AG
-+      ag_type = FW_TYPE_AG;
-+#else
-+      ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G;
-+#endif
-+      fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG :
-+              (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA :
-+              (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P :
-+              (strstr(&fw_path[i], "_es") ? FW_TYPE_ES :
-+              FW_TYPE_STA))));
-+
-+      if (fw_type == FW_TYPE_STA)
-+              strcpy(fw_tail, ".bin");
-+      else if (fw_type == FW_TYPE_APSTA)
-+              strcpy(fw_tail, "_apsta.bin");
-+      else if (fw_type == FW_TYPE_P2P)
-+              strcpy(fw_tail, "_p2p.bin");
-+      else if (fw_type == FW_TYPE_ES)
-+              strcpy(fw_tail, "_es.bin");
-+      else if (fw_type == FW_TYPE_MFG)
-+              strcpy(fw_tail, "_mfg.bin");
-+
-+      switch (chip) {
-+#ifdef BCMSDIO
-+              case BCM4330_CHIP_ID:
-+                      if (ag_type == FW_TYPE_G) {
-+                              if (chiprev == BCM4330B2_CHIP_REV)
-+                                      strcpy(&fw_path[i+1], FW_BCM4330B2);
-+                      } else {
-+                              if (chiprev == BCM4330B2_CHIP_REV)
-+                                      strcpy(&fw_path[i+1], FW_BCM4330B2_AG);
-+                      }
-+                      break;
-+              case BCM43362_CHIP_ID:
-+                      if (chiprev == BCM43362A0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43362A0);
-+                      else
-+                              strcpy(&fw_path[i+1], FW_BCM43362A2);
-+                      break;
-+              case BCM43430_CHIP_ID:
-+                      if (chiprev == BCM43430A0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43438A0);
-+                      else if (chiprev == BCM43430A1_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43438A1);
-+                      else if (chiprev == BCM43430A2_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43436B0);
-+                      break;
-+              case BCM43012_CHIP_ID:
-+                      if (chiprev == BCM43012B0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43012B0);
-+              case BCM4334_CHIP_ID:
-+                      if (chiprev == BCM4334B1_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4334B1);
-+                      break;
-+              case BCM43340_CHIP_ID:
-+              case BCM43341_CHIP_ID:
-+                      if (chiprev == BCM43341B0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43341B1);
-+                      break;
-+              case BCM4324_CHIP_ID:
-+                      if (chiprev == BCM43241B4_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43241B4);
-+                      break;
-+              case BCM4335_CHIP_ID:
-+                      if (chiprev == BCM4335A0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4339A0);
-+                      break;
-+              case BCM4339_CHIP_ID:
-+                      if (chiprev == BCM4339A0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4339A0);
-+                      break;
-+              case BCM4345_CHIP_ID:
-+              case BCM43454_CHIP_ID:
-+                      if (chiprev == BCM43455C0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43455C0);
-+                      else if (chiprev == BCM43455C5_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM43456C5);
-+                      break;
-+              case BCM4354_CHIP_ID:
-+                      if (chiprev == BCM4354A1_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4354A1);
-+                      else if (chiprev == BCM4356A2_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4356A2);
-+                      break;
-+              case BCM4356_CHIP_ID:
-+              case BCM4371_CHIP_ID:
-+                      if (chiprev == BCM4356A2_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4356A2);
-+                      break;
-+              case BCM43569_CHIP_ID:
-+                      if (chiprev == BCM4358A3_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4358A3);
-+                      break;
-+              case BCM4359_CHIP_ID:
-+                      if (chiprev == BCM4359B1_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4359B1);
-+                      else if (chiprev == BCM4359C0_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4359C0);
-+                      break;
-+#endif
-+#ifdef BCMPCIE
-+              case BCM4354_CHIP_ID:
-+              case BCM4356_CHIP_ID:
-+                      if (chiprev == BCM4356A2_CHIP_REV)
-+                              strcpy(&fw_path[i+1], FW_BCM4356A2);
-+                      break;
-+#endif
-+              default:
-+                      strcpy(&fw_path[i+1], "fw_bcmdhd");
-+      }
-+      strcat(fw_path, fw_tail);
-+
-+      CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path));
-+}
-+
-+void
-+dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
-+{
-+      uint chip, chiprev;
-+      int i;
-+      char fw_tail[20];
-+
-+      chip = dhd->conf->chip;
-+      chiprev = dhd->conf->chiprev;
-+
-+      if (clm_path[0] == '\0') {
-+              printf("clm path is null\n");
-+              return;
-+      }
-+
-+      /* find out the last '/' */
-+      i = strlen(clm_path);
-+      while (i > 0) {
-+              if (clm_path[i] == '/') break;
-+              i--;
-+      }
-+
-+      strcpy(fw_tail, ".blob");
-+
-+      switch (chip) {
-+#ifdef BCMSDIO
-+              case BCM43012_CHIP_ID:
-+                      if (chiprev == BCM43012B0_CHIP_REV)
-+                              strcpy(&clm_path[i+1], CLM_BCM43012B0);
-+                      break;
-+#endif
-+              default:
-+                      strcpy(&clm_path[i+1], "clm_bcmdhd");
-+      }
-+      strcat(clm_path, fw_tail);
-+
-+      CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_path));
-+}
-+
-+void
-+dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
-+{
-+      int matched=-1;
-+      uint chip, chiprev;
-+      int i;
-+
-+      chip = dhd->conf->chip;
-+      chiprev = dhd->conf->chiprev;
-+
-+      for (i=0; i<dhd->conf->nv_by_chip.count; i++) {
-+              if (chip==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&
-+                              chiprev==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {
-+                      matched = i;
-+                      break;
-+              }
-+      }
-+      if (matched < 0)
-+              return;
-+
-+      if (nv_path[0] == '\0') {
-+#ifdef CONFIG_BCMDHD_NVRAM_PATH
-+              bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
-+              if (nv_path[0] == '\0')
-+#endif
-+              {
-+                      printf("nvram path is null\n");
-+                      return;
-+              }
-+      }
-+
-+      /* find out the last '/' */
-+      i = strlen(nv_path);
-+      while (i > 0) {
-+              if (nv_path[i] == '/') break;
-+              i--;
-+      }
-+
-+      strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);
-+
-+      CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path));
-+}
-+
-+void
-+dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path)
-+{
-+      int i;
-+
-+      if (src_path[0] == '\0') {
-+              printf("src_path is null\n");
-+              return;
-+      } else
-+              strcpy(dst_path, src_path);
-+
-+      /* find out the last '/' */
-+      i = strlen(dst_path);
-+      while (i > 0) {
-+              if (dst_path[i] == '/') break;
-+              i--;
-+      }
-+      strcpy(&dst_path[i+1], dst_name);
-+
-+      CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path));
-+}
-+
-+#ifdef CONFIG_PATH_AUTO_SELECT
-+void
-+dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
-+{
-+      uint chip, chiprev;
-+      int i;
-+
-+      chip = dhd->conf->chip;
-+      chiprev = dhd->conf->chiprev;
-+
-+      if (conf_path[0] == '\0') {
-+              printf("config path is null\n");
-+              return;
-+      }
-+
-+      /* find out the last '/' */
-+      i = strlen(conf_path);
-+      while (i > 0) {
-+              if (conf_path[i] == '/') break;
-+              i--;
-+      }
-+
-+      switch (chip) {
-+#ifdef BCMSDIO
-+              case BCM4330_CHIP_ID:
-+                      if (chiprev == BCM4330B2_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4330B2);
-+                      break;
-+              case BCM43362_CHIP_ID:
-+                      if (chiprev == BCM43362A0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43362A0);
-+                      else
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43362A2);
-+                      break;
-+              case BCM43430_CHIP_ID:
-+                      if (chiprev == BCM43430A0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43438A0);
-+                      else if (chiprev == BCM43430A1_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43438A1);
-+                      else if (chiprev == BCM43430A2_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43436B0);
-+                      break;
-+              case BCM4334_CHIP_ID:
-+                      if (chiprev == BCM4334B1_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4334B1);
-+                      break;
-+              case BCM43340_CHIP_ID:
-+              case BCM43341_CHIP_ID:
-+                      if (chiprev == BCM43341B0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43341B0);
-+                      break;
-+              case BCM4324_CHIP_ID:
-+                      if (chiprev == BCM43241B4_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43241B4);
-+                      break;
-+              case BCM4335_CHIP_ID:
-+                      if (chiprev == BCM4335A0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
-+                      break;
-+              case BCM4345_CHIP_ID:
-+              case BCM43454_CHIP_ID:
-+                      if (chiprev == BCM43455C0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43455C0);
-+                      else if (chiprev == BCM43455C5_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM43456C5);
-+                      break;
-+              case BCM4339_CHIP_ID:
-+                      if (chiprev == BCM4339A0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4339A0);
-+                      break;
-+              case BCM4354_CHIP_ID:
-+                      if (chiprev == BCM4354A1_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4354A1);
-+                      else if (chiprev == BCM4356A2_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
-+                      break;
-+              case BCM4356_CHIP_ID:
-+              case BCM4371_CHIP_ID:
-+                      if (chiprev == BCM4356A2_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
-+                      break;
-+              case BCM43569_CHIP_ID:
-+                      if (chiprev == BCM4358A3_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4358A3);
-+                      break;
-+              case BCM4359_CHIP_ID:
-+                      if (chiprev == BCM4359B1_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4359B1);
-+                      else if (chiprev == BCM4359C0_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4359C0);
-+                      break;
-+#endif
-+#ifdef BCMPCIE
-+              case BCM4354_CHIP_ID:
-+              case BCM4356_CHIP_ID:
-+                      if (chiprev == BCM4356A2_CHIP_REV)
-+                              strcpy(&conf_path[i+1], CONFIG_BCM4356A2);
-+                      break;
-+#endif
-+      }
-+
-+      CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path));
-+}
-+#endif
-+
-+int
-+dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,
-+      int def, bool down)
-+{
-+      int ret = -1;
-+      char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */
-+
-+      if (val >= def) {
-+              if (down) {
-+                      if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
-+                              CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
-+              }
-+              if (cmd == WLC_SET_VAR) {
-+                      printf("%s: set %s %d\n", __FUNCTION__, name, val);
-+                      bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));
-+                      if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
-+                              CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
-+              } else {
-+                      printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);
-+                      if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)
-+                              CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
-+              }
-+      }
-+
-+      return ret;
-+}
-+
-+int
-+dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,
-+      int len, bool down)
-+{
-+      char iovbuf[WLC_IOCTL_SMLEN];
-+      int ret = -1;
-+
-+      if (down) {
-+              if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)
-+                      CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret));
-+      }
-+
-+      if (cmd == WLC_SET_VAR) {
-+              bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));
-+              if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
-+                      CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
-+      } else {
-+              if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0)
-+                      CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret));
-+      }
-+
-+      return ret;
-+}
-+
-+int
-+dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)
-+{
-+      char iovbuf[WLC_IOCTL_SMLEN];
-+      int ret = -1;
-+
-+      if (cmd == WLC_GET_VAR) {
-+              if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
-+                      ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);
-+                      if (!ret) {
-+                              memcpy(buf, iovbuf, len);
-+                      } else {
-+                              CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
-+                      }
-+              } else {
-+                      CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name));
-+              }
-+      } else {
-+              ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);
-+              if (ret < 0)
-+                      CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret));
-+      }
-+
-+      return ret;
-+}
-+
-+uint
-+dhd_conf_get_band(dhd_pub_t *dhd)
-+{
-+      uint band = WLC_BAND_AUTO;
-+
-+      if (dhd && dhd->conf)
-+              band = dhd->conf->band;
-+      else
-+              CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
-+
-+      return band;
-+}
-+
-+int
-+dhd_conf_set_country(dhd_pub_t *dhd)
-+{
-+      int bcmerror = -1;
-+
-+      memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
-+      printf("%s: set country %s, revision %d\n", __FUNCTION__,
-+              dhd->conf->cspec.ccode, dhd->conf->cspec.rev);
-+      dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);
-+
-+      return bcmerror;
-+}
-+
-+int
-+dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
-+{
-+      int bcmerror = -1;
-+
-+      memset(cspec, 0, sizeof(wl_country_t));
-+      bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));
-+      if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0)
-+              CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror));
-+      else
-+              printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
-+
-+      return bcmerror;
-+}
-+
-+int
-+dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec)
-+{
-+      int bcmerror = -1, i;
-+      struct dhd_conf *conf = dhd->conf;
-+
-+      for (i = 0; i < conf->country_list.count; i++) {
-+              if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) {
-+                      memcpy(cspec->ccode,
-+                              conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ);
-+                      cspec->rev = conf->country_list.cspec[i].rev;
-+                      printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev);
-+                      return 0;
-+              }
-+      }
-+
-+      return bcmerror;
-+}
-+
-+int
-+dhd_conf_fix_country(dhd_pub_t *dhd)
-+{
-+      int bcmerror = -1;
-+      uint band;
-+      wl_uint32_list_t *list;
-+      u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
-+
-+      if (!(dhd && dhd->conf)) {
-+              return bcmerror;
-+      }
-+
-+      memset(valid_chan_list, 0, sizeof(valid_chan_list));
-       list = (wl_uint32_list_t *)(void *) valid_chan_list;
-       list->count = htod32(WL_NUMCHANNELS);
--      if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {\r
--              CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));\r
--      }\r
--\r
--      band = dhd_conf_get_band(dhd);\r
--\r
--      if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) &&\r
--                      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
--              }\r
--      }\r
--\r
--      return bcmerror;\r
--}\r
--\r
--bool\r
--dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)\r
--{\r
--      int i;\r
--      bool match = false;\r
--\r
--      if (dhd && dhd->conf) {\r
--              if (dhd->conf->channels.count == 0)\r
--                      return true;\r
--              for (i=0; i<dhd->conf->channels.count; i++) {\r
--                      if (channel == dhd->conf->channels.channel[i])\r
--                              match = true;\r
--              }\r
--      } else {\r
--              match = true;\r
--              CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\r
--      }\r
--\r
--      return match;\r
--}\r
--\r
--int\r
--dhd_conf_set_roam(dhd_pub_t *dhd)\r
--{\r
--      int bcmerror = -1;\r
--      struct dhd_conf *conf = dhd->conf;\r
--\r
--      dhd_roam_disable = conf->roam_off;\r
--      dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);\r
--\r
--      if (!conf->roam_off || !conf->roam_off_suspend) {\r
--              printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",\r
--                              (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);\r
--\r
--              printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",\r
--                              (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);\r
--\r
--              printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",\r
--                              (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);\r
--\r
--              dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);\r
--      }\r
--\r
--      return bcmerror;\r
--}\r
--\r
--void\r
--dhd_conf_set_bw_cap(dhd_pub_t *dhd)\r
--{\r
--      struct {\r
--              u32 band;\r
--              u32 bw_cap;\r
--      } param = {0, 0};\r
--\r
--      if (dhd->conf->bw_cap_2g >= 0) {\r
--              param.band = WLC_BAND_2G;\r
--              param.bw_cap = (uint)dhd->conf->bw_cap_2g;\r
--              printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);\r
--      }\r
--\r
--      if (dhd->conf->bw_cap_5g >= 0) {\r
--              param.band = WLC_BAND_5G;\r
--              param.bw_cap = (uint)dhd->conf->bw_cap_5g;\r
--              printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);\r
--      }\r
--}\r
--\r
--void\r
--dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp)\r
--{\r
--      int bcmerror = -1;\r
--      char iovbuf[WLC_IOCTL_SMLEN];\r
--      edcf_acparam_t *acparam;\r
--\r
--      bzero(iovbuf, sizeof(iovbuf));\r
--\r
--      /*\r
--       * Get current acparams, using buf as an input buffer.\r
--       * Return data is array of 4 ACs of wme params.\r
--       */\r
--      if (mode == 0)\r
--              bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));\r
--      else\r
--              bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf));\r
--      if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {\r
--              CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));\r
--              return;\r
--      }\r
--      memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);\r
--\r
--      acparam = &acp[AC_BK];\r
--      CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
--              __FUNCTION__,\r
--              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
--              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
--              acparam->TXOP));\r
--      acparam = &acp[AC_BE];\r
--      CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
--              __FUNCTION__,\r
--              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
--              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
--              acparam->TXOP));\r
--      acparam = &acp[AC_VI];\r
--      CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
--              __FUNCTION__,\r
--              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
--              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
--              acparam->TXOP));\r
--      acparam = &acp[AC_VO];\r
--      CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
--              __FUNCTION__,\r
--              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
--              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
--              acparam->TXOP));\r
--\r
--      return;\r
--}\r
--\r
--void\r
--dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci)\r
--{\r
--      int aifsn, ecwmin, ecwmax, txop;\r
--      edcf_acparam_t *acp;\r
--      struct dhd_conf *conf = dhd->conf;\r
--      wme_param_t *wme;\r
--\r
--      if (mode == 0)\r
--              wme = &conf->wme_sta;\r
--      else\r
--              wme = &conf->wme_ap;\r
--\r
--      /* Default value */\r
--      aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;\r
--      ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;\r
--      ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;\r
--      txop = acparam_cur->TXOP;\r
--\r
--      /* Modified value */\r
--      if (wme->aifsn[aci] > 0)\r
--              aifsn = wme->aifsn[aci];\r
--      if (wme->ecwmin[aci] > 0)\r
--              ecwmin = wme->ecwmin[aci];\r
--      if (wme->ecwmax[aci] > 0)\r
--              ecwmax = wme->ecwmax[aci];\r
--      if (wme->txop[aci] > 0)\r
--              txop = wme->txop[aci];\r
--\r
--      if (!(wme->aifsn[aci] || wme->ecwmin[aci] ||\r
--                      wme->ecwmax[aci] || wme->txop[aci]))\r
--              return;\r
--\r
--      /* Update */\r
--      acp = acparam_cur;\r
--      acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);\r
--      acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);\r
--      acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));\r
--      acp->TXOP = txop;\r
--\r
--      printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
--              __FUNCTION__, mode?"ap":"sta",\r
--              acp->ACI, acp->ACI&EDCF_AIFSN_MASK,\r
--              acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
--              acp->TXOP);\r
--\r
--      /*\r
--      * Now use buf as an output buffer.\r
--      * Put WME acparams after "wme_ac\0" in buf.\r
--      * NOTE: only one of the four ACs can be set at a time.\r
--      */\r
--      if (mode == 0)\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
--      else\r
--              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
--\r
--}\r
--\r
--void\r
--dhd_conf_set_wme(dhd_pub_t *dhd, int mode)\r
--{\r
--      edcf_acparam_t acparam_cur[AC_COUNT];\r
--\r
--      if (dhd && dhd->conf) {\r
--              if (!dhd->conf->force_wme_ac) {\r
--                      CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",\r
--                              __FUNCTION__, dhd->conf->force_wme_ac));\r
--                      return;\r
--              }\r
--\r
--              CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));\r
--              dhd_conf_get_wme(dhd, mode, acparam_cur);\r
--\r
--              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK);\r
--              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE);\r
--              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI);\r
--              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO);\r
--\r
--              CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));\r
--              dhd_conf_get_wme(dhd, mode, acparam_cur);\r
--      } else {\r
--              CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));\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
--#define MACS "%02x%02x%02x%02x%02x%02x"\r
--\r
--      /*\r
--       * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.\r
--       *   1) dhd_master_mode=0\r
--       *   2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
--       * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)\r
--       *   1) dhd_master_mode=1\r
--       *   2) pkt_filter_del=100, 102, 103, 104, 105\r
--       *   3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E\r
--       * 3. magic pkt: magic_pkt_filter_add=141 0 1 12\r
--       * 4. Filter out netbios pkt:\r
--       *   Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089\r
--       */\r
--      for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {\r
--              dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];\r
--              printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);\r
--      }\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
--              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
--              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
--              dhd->pktfilter_count += 1;\r
--      }\r
--}\r
--\r
--bool\r
--dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)\r
--{\r
--      int i;\r
--\r
--      if (dhd && dhd->conf) {\r
--              for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {\r
--                      if (id == dhd->conf->pkt_filter_del.id[i]) {\r
--                              printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);\r
--                              return true;\r
--                      }\r
--              }\r
--              return false;\r
--      }\r
--      return false;\r
--}\r
--\r
--void\r
--dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)\r
-+      if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {
-+              CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));
-+      }
-+
-+      band = dhd_conf_get_band(dhd);
-+
-+      if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) &&
-+                      dtoh32(list->count)<11)) {
-+              CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n",
-+                      __FUNCTION__, bcmerror, dtoh32(list->count)));
-+              if ((bcmerror = dhd_conf_set_country(dhd)) < 0) {
-+                      strcpy(dhd->conf->cspec.country_abbrev, "US");
-+                      dhd->conf->cspec.rev = 0;
-+                      strcpy(dhd->conf->cspec.ccode, "US");
-+                      dhd_conf_set_country(dhd);
-+              }
-+      }
-+
-+      return bcmerror;
-+}
-+
-+bool
-+dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel)
-+{
-+      int i;
-+      bool match = false;
-+
-+      if (dhd && dhd->conf) {
-+              if (dhd->conf->channels.count == 0)
-+                      return true;
-+              for (i=0; i<dhd->conf->channels.count; i++) {
-+                      if (channel == dhd->conf->channels.channel[i])
-+                              match = true;
-+              }
-+      } else {
-+              match = true;
-+              CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
-+      }
-+
-+      return match;
-+}
-+
-+int
-+dhd_conf_set_roam(dhd_pub_t *dhd)
- {
--      dhd->pktfilter_count = 6;\r
--      dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;\r
--      dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";\r
--      dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";\r
--      dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";\r
--      dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;\r
--      /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/\r
--      dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;\r
--\r
--      /* IPv4 broadcast address XXX.XXX.XXX.255 */\r
--      dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";\r
--      dhd->pktfilter_count++;\r
--      /* discard IPv4 multicast address 224.0.0.0/4 */\r
--      dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";\r
--      dhd->pktfilter_count++;\r
--      /* discard IPv6 multicast address FF00::/8 */\r
--      dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";\r
--      dhd->pktfilter_count++;\r
--      /* discard Netbios pkt */\r
--      dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";\r
--      dhd->pktfilter_count++;\r
--\r
--}\r
--#endif /* PKT_FILTER_SUPPORT */\r
--\r
--int\r
--dhd_conf_get_pm(dhd_pub_t *dhd)\r
--{\r
--      if (dhd && dhd->conf)\r
--              return dhd->conf->pm;\r
--      return -1;\r
--}\r
--\r
--#ifdef PROP_TXSTATUS\r
--int\r
--dhd_conf_get_disable_proptx(dhd_pub_t *dhd)\r
--{\r
--      struct dhd_conf *conf = dhd->conf;\r
--      int disable_proptx = -1;\r
--      int fw_proptx = 0;\r
--\r
--      /* check fw proptx priority:\r
--        * 1st: check fw support by wl cap\r
--        * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default\r
--        *        if you would like to disable it, please set disable_proptx=1 in config.txt\r
--        * 3th: disable when proptxstatus not support in wl cap\r
--        */\r
--      if (FW_SUPPORTED(dhd, proptxstatus)) {\r
--              fw_proptx = 1;\r
--      } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||\r
--                      dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
--              fw_proptx = 1;\r
--      } else {\r
--              fw_proptx = 0;\r
--      }\r
--\r
--      /* returned disable_proptx value:\r
--        * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)\r
--        * 0: depend on fw support\r
--        * 1: always disable proptx\r
--        */\r
--      if (conf->disable_proptx == 0) {\r
--              // check fw support as well\r
--              if (fw_proptx)\r
--                      disable_proptx = 0;\r
--              else\r
--                      disable_proptx = 1;\r
--      } else if (conf->disable_proptx >= 1) {\r
--              disable_proptx = 1;\r
--      } else {\r
--              // check fw support as well\r
--              if (fw_proptx)\r
--                      disable_proptx = -1;\r
--              else\r
--                      disable_proptx = 1;\r
--      }\r
--\r
--      printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx);\r
--\r
--      return disable_proptx;\r
--}\r
--#endif\r
--\r
--uint\r
--pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf)\r
--{\r
--      bool findNewline, changenewline=FALSE, pick=FALSE;\r
--      int column;\r
--      uint n, pick_column=0;\r
--\r
--      findNewline = FALSE;\r
--      column = 0;\r
--\r
--      if (start_pos >= len) {\r
--              CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__));\r
--              return 0;\r
--      }\r
--\r
--      for (n = start_pos; n < len; n++) {\r
--              if (varbuf[n] == '\r')\r
--                      continue;\r
--              if ((findNewline || changenewline) && varbuf[n] != '\n')\r
--                      continue;\r
--              findNewline = FALSE;\r
--              if (varbuf[n] == '#') {\r
--                      findNewline = TRUE;\r
--                      continue;\r
--              }\r
--              if (varbuf[n] == '\\') {\r
--                      changenewline = TRUE;\r
--                      continue;\r
--              }\r
--              if (!changenewline && varbuf[n] == '\n') {\r
--                      if (column == 0)\r
--                              continue;\r
--                      column = 0;\r
--                      continue;\r
--              }\r
--              if (changenewline && varbuf[n] == '\n') {\r
--                      changenewline = FALSE;\r
--                      continue;\r
--              }\r
--\r
--              if (column==0 && !pick) { // start to pick\r
--                      pick = TRUE;\r
--                      column++;\r
--                      pick_column = 0;\r
--              } else {\r
--                      if (pick && column==0) { // stop to pick\r
--                              pick = FALSE;\r
--                              break;\r
--                      } else\r
--                              column++;\r
--              }\r
--              if (pick) {\r
--                      if (varbuf[n] == 0x9)\r
--                              continue;\r
--                      if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ')\r
--                              continue;\r
--                      pickbuf[pick_column] = varbuf[n];\r
--                      pick_column++;\r
--              }\r
--      }\r
--\r
--      return n; // return current position\r
--}\r
--\r
--bool\r
--dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param)\r
--{\r
--      char *data = full_param+len_param;\r
--\r
--      if (!strncmp("dhd_msg_level=", full_param, len_param)) {\r
--              dhd_msg_level = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);\r
--      }\r
--#ifdef BCMSDIO\r
--      else if (!strncmp("sd_msglevel=", full_param, len_param)) {\r
--              sd_msglevel = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel);\r
--      }\r
--#endif\r
--      else if (!strncmp("android_msg_level=", full_param, len_param)) {\r
--              android_msg_level = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);\r
--      }\r
--      else if (!strncmp("config_msg_level=", full_param, len_param)) {\r
--              config_msg_level = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);\r
--      }\r
--#ifdef WL_CFG80211\r
--      else if (!strncmp("wl_dbg_level=", full_param, len_param)) {\r
--              wl_dbg_level = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);\r
--      }\r
--#endif\r
--#if defined(WL_WIRELESS_EXT)\r
--      else if (!strncmp("iw_msg_level=", full_param, len_param)) {\r
--              iw_msg_level = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);\r
--      }\r
--#endif\r
--#if defined(DHD_DEBUG)\r
--      else if (!strncmp("dhd_console_ms=", full_param, len_param)) {\r
--              dhd_console_ms = (int)simple_strtol(data, NULL, 0);\r
--              printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);\r
--      }\r
--#endif\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--
--void\r
--dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val)\r
--{\r
--      char *pick_tmp, *pch;\r
--\r
--      /* Process WMM parameters */\r
--      pick_tmp = pick;\r
--      pch = bcmstrstr(pick_tmp, "aifsn ");\r
--      if (pch) {\r
--              wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);\r
--              printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]);\r
--      }\r
--      pick_tmp = pick;\r
--      pch = bcmstrstr(pick_tmp, "ecwmin ");\r
--      if (pch) {\r
--              wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);\r
--              printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]);\r
--      }\r
--      pick_tmp = pick;\r
--      pch = bcmstrstr(pick_tmp, "ecwmax ");\r
--      if (pch) {\r
--              wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);\r
--              printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]);\r
--      }\r
--      pick_tmp = pick;\r
--      pch = bcmstrstr(pick_tmp, "txop ");\r
--      if (pch) {\r
--              wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);\r
--              printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]);\r
--      }\r
--\r
--}\r
--
--bool\r
--dhd_conf_read_wme_ac_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
--      // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e\r
--      // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e\r
--\r
--      /* Process WMM parameters */\r
--      if (!strncmp("force_wme_ac=", full_param, len_param)) {\r
--              conf->force_wme_ac = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);\r
--      }
--      else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE);\r
--      }\r
--      else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK);\r
--      }\r
--      else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI);\r
--      }\r
--      else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO);\r
--      }\r
--      else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE);\r
--      }\r
--      else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK);\r
--      }\r
--      else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI);\r
--      }\r
--      else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) {\r
--              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO);\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--bool\r
--dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)\r
--{\r
--      int i, j;\r
--      char *pch, *pick_tmp;\r
--      wl_mac_list_t *mac_list;\r
--      wl_mac_range_t *mac_range;\r
--      struct dhd_conf *conf = dhd->conf;\r
--      char *data = full_param+len_param;\r
--\r
--      /* Process fw_by_mac:\r
--       * fw_by_mac=[fw_mac_num] \\r
--       *  [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \\r
--       *                                    [oui1-1] [nic_start1-1] [nic_end1-1]... \\r
--       *                                    [oui1-n] [nic_start1-n] [nic_end1-n] \\r
--       *  [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \\r
--       *                                    [oui2-1] [nic_start2-1] [nic_end2-1]... \\r
--       *                                    [oui2-n] [nic_start2-n] [nic_end2-n] \\r
--       * Ex: fw_by_mac=2 \\r
--       *  fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \\r
--       *  fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \\r
--       *                           0x983B16 0x916157 0x916487\r
--       */\r
--\r
--      if (!strncmp("fw_by_mac=", full_param, len_param)) {\r
--              pick_tmp = data;\r
--              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--              conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);\r
--              if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) {\r
--                      conf->fw_by_mac.count = 0;\r
--                      CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
--              }\r
--              printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count);\r
--              conf->fw_by_mac.m_mac_list_head = mac_list;\r
--              for (i=0; i<conf->fw_by_mac.count; i++) {\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      strcpy(mac_list[i].name, pch);\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);\r
--                      printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,\r
--                              mac_list[i].name, mac_list[i].count);\r
--                      if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {\r
--                              mac_list[i].count = 0;\r
--                              CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
--                              break;\r
--                      }\r
--                      mac_list[i].mac = mac_range;\r
--                      for (j=0; j<mac_list[i].count; j++) {\r
--                              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                              mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);\r
--                              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                              mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);\r
--                              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                              mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);\r
--                              printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",\r
--                                      __FUNCTION__, mac_range[j].oui,\r
--                                      mac_range[j].nic_start, mac_range[j].nic_end);\r
--                      }\r
--              }\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--bool\r
--dhd_conf_read_nv_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)\r
--{\r
--      int i, j;\r
--      char *pch, *pick_tmp;\r
--      wl_mac_list_t *mac_list;\r
--      wl_mac_range_t *mac_range;\r
--      struct dhd_conf *conf = dhd->conf;\r
--      char *data = full_param+len_param;\r
--\r
--      /* Process nv_by_mac:\r
--       * [nv_by_mac]: The same format as fw_by_mac\r
--       */\r
--      if (!strncmp("nv_by_mac=", full_param, len_param)) {\r
--              pick_tmp = data;\r
--              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--              conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);\r
--              if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) {\r
--                      conf->nv_by_mac.count = 0;\r
--                      CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
--              }\r
--              printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count);\r
--              conf->nv_by_mac.m_mac_list_head = mac_list;\r
--              for (i=0; i<conf->nv_by_mac.count; i++) {\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      strcpy(mac_list[i].name, pch);\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);\r
--                      printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,\r
--                              mac_list[i].name, mac_list[i].count);\r
--                      if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {\r
--                              mac_list[i].count = 0;\r
--                              CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
--                              break;\r
--                      }\r
--                      mac_list[i].mac = mac_range;\r
--                      for (j=0; j<mac_list[i].count; j++) {\r
--                              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                              mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);\r
--                              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                              mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);\r
--                              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                              mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);\r
--                              printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",\r
--                                      __FUNCTION__, mac_range[j].oui,\r
--                                      mac_range[j].nic_start, mac_range[j].nic_end);\r
--                      }\r
--              }\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--bool\r
--dhd_conf_read_nv_by_chip(dhd_pub_t *dhd, char *full_param, uint len_param)\r
--{\r
--      int i;\r
--      char *pch, *pick_tmp;\r
--      wl_chip_nv_path_t *chip_nv_path;\r
--      struct dhd_conf *conf = dhd->conf;\r
--      char *data = full_param+len_param;\r
--\r
--      /* Process nv_by_chip:\r
--       * nv_by_chip=[nv_chip_num] \\r
--       *  [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \\r
--       * Ex: nv_by_chip=2 \\r
--       *  43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \\r
--       */\r
--      if (!strncmp("nv_by_chip=", full_param, len_param)) {\r
--              pick_tmp = data;\r
--              pch = bcmstrtok(&pick_tmp, " ", 0);\r
--              conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);\r
--              if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) {\r
--                      conf->nv_by_chip.count = 0;\r
--                      CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
--              }\r
--              printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count);\r
--              conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;\r
--              for (i=0; i<conf->nv_by_chip.count; i++) {\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);\r
--                      pch = bcmstrtok(&pick_tmp, " ", 0);\r
--                      strcpy(chip_nv_path[i].name, pch);\r
--                      printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__,\r
--                              chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);\r
--              }\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--bool\r
--dhd_conf_read_roam_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("roam_off=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->roam_off = 0;\r
--              else\r
--                      conf->roam_off = 1;\r
--              printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);\r
--      }\r
--      else if (!strncmp("roam_off_suspend=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->roam_off_suspend = 0;\r
--              else\r
--                      conf->roam_off_suspend = 1;\r
--              printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend);\r
--      }\r
--      else if (!strncmp("roam_trigger=", full_param, len_param)) {\r
--              conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: roam_trigger = %d\n", __FUNCTION__,\r
--                      conf->roam_trigger[0]);\r
--      }\r
--      else if (!strncmp("roam_scan_period=", full_param, len_param)) {\r
--              conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: roam_scan_period = %d\n", __FUNCTION__,\r
--                      conf->roam_scan_period[0]);\r
--      }\r
--      else if (!strncmp("roam_delta=", full_param, len_param)) {\r
--              conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);\r
--      }\r
--      else if (!strncmp("fullroamperiod=", full_param, len_param)) {\r
--              conf->fullroamperiod = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: fullroamperiod = %d\n", __FUNCTION__,\r
--                      conf->fullroamperiod);\r
--      } else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--bool\r
--dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)\r
--{\r
--      int i;\r
--      char *pch, *pick_tmp;\r
--      struct dhd_conf *conf = dhd->conf;\r
--      char *data = full_param+len_param;\r
--\r
--      /* Process country_list:\r
--       * country_list=[country1]:[ccode1]/[regrev1],\r
--       * [country2]:[ccode2]/[regrev2] \\r
--       * Ex: country_list=US:US/0, TW:TW/1\r
--       */\r
--      if (!strncmp("country_list=", 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
--                      strcpy(conf->country_list.cspec[i].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
--                      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
--                      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
--              }\r
--              printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--#ifdef PKT_FILTER_SUPPORT\r
--bool\r
--dhd_conf_read_pkt_filter(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
--      char *pch, *pick_tmp;\r
--      int i;\r
--\r
--      /* Process pkt filter:\r
--       * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
--       * 2) pkt_filter_del=100, 102, 103, 104, 105\r
--       * 3) magic_pkt_filter_add=141 0 1 12\r
--       */\r
--      if (!strncmp("dhd_master_mode=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      dhd_master_mode = FALSE;\r
--              else\r
--                      dhd_master_mode = TRUE;\r
--              printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);\r
--      }\r
--      else if (!strncmp("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->pkt_filter_add.filter[i][0], pch);\r
--                      printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);\r
--                      pch = bcmstrtok(&pick_tmp, ",.-", 0);\r
--                      i++;\r
--              }\r
--              conf->pkt_filter_add.count = i;\r
--      }\r
--      else if (!strncmp("pkt_filter_del=", 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
--                      conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);\r
--                      pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
--                      i++;\r
--              }\r
--              conf->pkt_filter_del.count = i;\r
--              printf("%s: pkt_filter_del id = ", __FUNCTION__);\r
--              for (i=0; i<conf->pkt_filter_del.count; i++)\r
--                      printf("%d ", conf->pkt_filter_del.id[i]);\r
--              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
--              }\r
--              conf->magic_pkt_filter_add.count = i;\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--#endif\r
--\r
--#ifdef IAPSTA_PREINIT\r
--/*\r
-- * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]\r
-- * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]\r
--               hidden [y|n] maxassoc [x]\r
--               amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\r
--               emode [none|wep|tkip|aes|tkipaes]\r
--               key [xxxxx]\r
-- * iapsta_enable=ifname [wlan0|wlan1]\r
--*/\r
--bool\r
--dhd_conf_read_iapsta(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("iapsta_init=", full_param, len_param)) {\r
--              sprintf(conf->iapsta_init, "iapsta_init %s", data);\r
--              printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);\r
--      }\r
--      else if (!strncmp("iapsta_config=", full_param, len_param)) {\r
--              sprintf(conf->iapsta_config, "iapsta_config %s", data);\r
--              printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);\r
--      }\r
--      else if (!strncmp("iapsta_enable=", full_param, len_param)) {\r
--              sprintf(conf->iapsta_enable, "iapsta_enable %s", data);\r
--              printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--#endif\r
--\r
--#ifdef IDHCPC\r
--bool\r
--dhd_conf_read_dhcp_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("dhcpc_enable=", full_param, len_param)) {\r
--              conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--#endif\r
--\r
--#ifdef BCMSDIO\r
--bool\r
--dhd_conf_read_sdio_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("dhd_doflow=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      dhd_doflow = FALSE;\r
--              else\r
--                      dhd_doflow = TRUE;\r
--              printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow);\r
--      }\r
--      else if (!strncmp("dhd_slpauto=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      dhd_slpauto = FALSE;\r
--              else\r
--                      dhd_slpauto = TRUE;\r
--              printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);\r
--      }\r
--      else if (!strncmp("kso_enable=", full_param, len_param)) {\r
--              if (!strncmp(data, "1", 1))\r
--                      dhd_slpauto = FALSE;\r
--              else\r
--                      dhd_slpauto = TRUE;\r
--              printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);\r
--      }\r
--      else if (!strncmp("bus:txglom=", full_param, len_param)) {\r
--              conf->bus_txglom = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);\r
--      }\r
--      else if (!strncmp("use_rxchain=", full_param, len_param)) {\r
--              conf->use_rxchain = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain);\r
--      }\r
--      else if (!strncmp("dhd_txminmax=", full_param, len_param)) {\r
--              conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax);\r
--      }\r
--      else if (!strncmp("txinrx_thres=", full_param, len_param)) {\r
--              conf->txinrx_thres = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres);\r
--      }\r
--      else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) {\r
--              conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);\r
--      }\r
--      else if (!strncmp("oob_enabled_later=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->oob_enabled_later = FALSE;\r
--              else\r
--                      conf->oob_enabled_later = TRUE;\r
--              printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);\r
--      }\r
--#if defined(BCMSDIOH_TXGLOM)\r
--      else if (!strncmp("txglomsize=", full_param, len_param)) {\r
--              conf->txglomsize = (uint)simple_strtol(data, NULL, 10);\r
--              if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)\r
--                      conf->txglomsize = SDPCM_MAXGLOM_SIZE;\r
--              printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize);\r
--      }\r
--      else if (!strncmp("swtxglom=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->swtxglom = FALSE;\r
--              else\r
--                      conf->swtxglom = TRUE;\r
--              printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom);\r
--      }\r
--      else if (!strncmp("txglom_ext=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->txglom_ext = FALSE;\r
--              else\r
--                      conf->txglom_ext = TRUE;\r
--              printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext);\r
--              if (conf->txglom_ext) {\r
--                      if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID))\r
--                              conf->txglom_bucket_size = 1680;\r
--                      else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
--                                      conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID)\r
--                              conf->txglom_bucket_size = 1684;\r
--              }\r
--              printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size);\r
--      }\r
--      else if (!strncmp("bus:rxglom=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->bus_rxglom = FALSE;\r
--              else\r
--                      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
--      }\r
--      else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->txctl_tmo_fix = FALSE;\r
--              else\r
--                      conf->txctl_tmo_fix = TRUE;\r
--              printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);\r
--      }\r
--      else if (!strncmp("tx_in_rx=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->tx_in_rx = FALSE;\r
--              else\r
--                      conf->tx_in_rx = TRUE;\r
--              printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);\r
--      }\r
--      else if (!strncmp("tx_max_offset=", full_param, len_param)) {\r
--              conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);\r
--      }\r
--      else if (!strncmp("txglom_mode=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->txglom_mode = FALSE;\r
--              else\r
--                      conf->txglom_mode = TRUE;\r
--              printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);\r
--      }\r
--#endif\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
--      struct dhd_conf *conf = dhd->conf;\r
--      char *data = full_param+len_param;\r
--\r
--      if (!strncmp("lpc=", full_param, len_param)) {\r
--              conf->lpc = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);\r
--      }\r
--      else if (!strncmp("deepsleep=", full_param, len_param)) {\r
--              if (!strncmp(data, "1", 1))\r
--                      conf->deepsleep = TRUE;\r
--              else\r
--                      conf->deepsleep = FALSE;\r
--              printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);\r
--      }\r
--      else if (!strncmp("PM=", full_param, len_param)) {\r
--              conf->pm = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: PM = %d\n", __FUNCTION__, conf->pm);\r
--      }\r
--      else if (!strncmp("pm_in_suspend=", full_param, len_param)) {\r
--              conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);\r
--      }\r
--      else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) {\r
--              conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);\r
--      }\r
--      else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {\r
--              if (!strncmp(data, "1", 1))\r
--                      conf->xmit_in_suspend = TRUE;\r
--              else\r
--                      conf->xmit_in_suspend = FALSE;\r
--              printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--bool\r
--dhd_conf_read_others(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
--      uint len_data = strlen(data);\r
--      char *pch, *pick_tmp;\r
--      int i;\r
--\r
--      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
--              if (!strcmp(data, "b"))\r
--                      conf->band = WLC_BAND_2G;\r
--              else if (!strcmp(data, "a"))\r
--                      conf->band = WLC_BAND_5G;\r
--              else\r
--                      conf->band = WLC_BAND_AUTO;\r
--              printf("%s: band = %d\n", __FUNCTION__, conf->band);\r
--      }\r
--      else if (!strncmp("mimo_bw_cap=", full_param, len_param)) {\r
--              conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);\r
--      }\r
--      else if (!strncmp("bw_cap_2g=", full_param, len_param)) {\r
--              conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0);\r
--              printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);\r
--      }\r
--      else if (!strncmp("bw_cap_5g=", full_param, len_param)) {\r
--              conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0);\r
--              printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g);\r
--      }\r
--      else if (!strncmp("ccode=", full_param, len_param)) {\r
--              memset(&conf->cspec, 0, sizeof(wl_country_t));\r
--              memcpy(conf->cspec.country_abbrev, data, len_data);\r
--              memcpy(conf->cspec.ccode, data, len_data);\r
--              printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode);\r
--      }\r
--      else if (!strncmp("regrev=", full_param, len_param)) {\r
--              conf->cspec.rev = (int32)simple_strtol(data, NULL, 10);\r
--              printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev);\r
--      }\r
--      else if (!strncmp("channels=", full_param, len_param)) {\r
--              pick_tmp = data;\r
--              pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
--              i=0;\r
--              while (pch != NULL && i<WL_NUMCHANNELS) {\r
--                      conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);\r
--                      pch = bcmstrtok(&pick_tmp, " ,.-", 0);\r
--                      i++;\r
--              }\r
--              conf->channels.count = i;\r
--              printf("%s: channels = ", __FUNCTION__);\r
--              for (i=0; i<conf->channels.count; i++)\r
--                      printf("%d ", conf->channels.channel[i]);\r
--              printf("\n");\r
--      }\r
--      else if (!strncmp("keep_alive_period=", full_param, len_param)) {\r
--              conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: keep_alive_period = %d\n", __FUNCTION__,\r
--                      conf->keep_alive_period);\r
--      }\r
--      else if (!strncmp("stbc=", full_param, len_param)) {\r
--              conf->stbc = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);\r
--      }\r
--      else if (!strncmp("phy_oclscdenable=", full_param, len_param)) {\r
--              conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable);\r
--      }\r
--      else if (!strncmp("srl=", full_param, len_param)) {\r
--              conf->srl = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: srl = %d\n", __FUNCTION__, conf->srl);\r
--      }\r
--      else if (!strncmp("lrl=", full_param, len_param)) {\r
--              conf->lrl = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);\r
--      }\r
--      else if (!strncmp("bcn_timeout=", full_param, len_param)) {\r
--              conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);\r
--      }\r
--      else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) {\r
--              conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);\r
--      }\r
--      else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) {\r
--              conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);\r
--      }\r
--      else if (!strncmp("spect=", full_param, len_param)) {\r
--              conf->spect = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: spect = %d\n", __FUNCTION__, conf->spect);\r
--      }\r
--      else if (!strncmp("txbf=", full_param, len_param)) {\r
--              conf->txbf = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);\r
--      }\r
--      else if (!strncmp("frameburst=", full_param, len_param)) {\r
--              conf->frameburst = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);\r
--      }\r
--      else if (!strncmp("disable_proptx=", full_param, len_param)) {\r
--              conf->disable_proptx = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx);\r
--      }\r
--#ifdef DHDTCPACK_SUPPRESS\r
--      else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) {\r
--              conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);\r
--      }\r
--#endif\r
--      else if (!strncmp("pktprio8021x=", full_param, len_param)) {\r
--              conf->pktprio8021x = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);\r
--      }\r
--      else if (!strncmp("dhd_txbound=", full_param, len_param)) {\r
--              dhd_txbound = (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound);\r
--      }\r
--      else if (!strncmp("dhd_rxbound=", full_param, len_param)) {\r
--              dhd_rxbound = (uint)simple_strtol(data, NULL, 10);\r
--              printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);\r
--      }\r
--      else if (!strncmp("rsdb_mode=", full_param, len_param)) {\r
--              conf->rsdb_mode = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode);\r
--      }\r
--      else if (!strncmp("vhtmode=", full_param, len_param)) {\r
--              if (!strncmp(data, "0", 1))\r
--                      conf->vhtmode = 0;\r
--              else\r
--                      conf->vhtmode = 1;\r
--              printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);\r
--      }\r
--      else if (!strncmp("num_different_channels=", full_param, len_param)) {\r
--              conf->num_different_channels = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);\r
--      }\r
--      else if (!strncmp("autocountry=", full_param, len_param)) {\r
--              conf->autocountry = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry);\r
--      }\r
--      else if (!strncmp("tsq=", full_param, len_param)) {\r
--              conf->tsq = (int)simple_strtol(data, NULL, 10);\r
--              printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);\r
--      }\r
--      else\r
--              return false;\r
--\r
--      return true;\r
--}\r
--\r
--int\r
--dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)\r
--{\r
--      int bcmerror = -1;\r
--      uint len, start_pos=0;\r
--      void * image = NULL;\r
--      char * memblock = NULL;\r
--      char *bufp, *pick = NULL, *pch;\r
--      bool conf_file_exists;\r
--      uint len_param;\r
--\r
--      conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));\r
--      if (!conf_file_exists) {\r
--              printf("%s: config path %s\n", __FUNCTION__, conf_path);\r
--              return (0);\r
--      }\r
--\r
--      if (conf_file_exists) {\r
--              image = dhd_os_open_image(conf_path);\r
--              if (image == NULL) {\r
--                      printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);\r
--                      goto err;\r
--              }\r
--      }\r
--\r
--      memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);\r
--      if (memblock == NULL) {\r
--              CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
--                      __FUNCTION__, MAXSZ_CONFIG));\r
--              goto err;\r
--      }\r
--\r
--      pick = MALLOC(dhd->osh, MAXSZ_BUF);\r
--      if (!pick) {\r
--              CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",\r
--                      __FUNCTION__, MAXSZ_BUF));\r
--              goto err;\r
--      }\r
--\r
--      /* Read variables */\r
--      if (conf_file_exists) {\r
--              len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);\r
--      }\r
--      if (len > 0 && len < MAXSZ_CONFIG) {\r
--              bufp = (char *)memblock;\r
--              bufp[len] = 0;\r
--\r
--              while (start_pos < len) {\r
--                      memset(pick, 0, MAXSZ_BUF);\r
--                      start_pos = pick_config_vars(bufp, len, start_pos, pick);\r
--                      pch = strchr(pick, '=');\r
--                      if (pch != NULL) {\r
--                              len_param = pch-pick+1;\r
--                              if (len_param == strlen(pick)) {\r
--                                      CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));\r
--                                      continue;\r
--                              }\r
--                      } else {\r
--                              CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));\r
--                              continue;\r
--                      }\r
--\r
--                      if (dhd_conf_read_log_level(dhd, pick, len_param))\r
--                              continue;\r
--                      else if (dhd_conf_read_roam_params(dhd, pick, len_param))\r
--                              continue;\r
--                      else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param))\r
--                              continue;\r
--                      else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param))\r
--                              continue;\r
--                      else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param))\r
--                              continue;\r
--                      else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param))\r
--                              continue;\r
--                      else if (dhd_conf_read_country_list(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
--#endif /* PKT_FILTER_SUPPORT */\r
--#ifdef IAPSTA_PREINIT\r
--                      else if (dhd_conf_read_iapsta(dhd, pick, len_param))\r
--                              continue;\r
--#endif /* IAPSTA_PREINIT */\r
--#ifdef IDHCPC\r
--                      else if (dhd_conf_read_dhcp_params(dhd, pick, len_param))\r
--                              continue;\r
--#endif /* IDHCPC */\r
--#ifdef BCMSDIO\r
--                      else if (dhd_conf_read_sdio_params(dhd, pick, len_param))\r
--                              continue;\r
--#endif /* BCMSDIO */\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
--                              continue;\r
-+      int bcmerror = -1;
-+      struct dhd_conf *conf = dhd->conf;
-+
-+      dhd_roam_disable = conf->roam_off;
-+      dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);
-+
-+      if (!conf->roam_off || !conf->roam_off_suspend) {
-+              printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]);
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",
-+                              (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);
-+
-+              printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]);
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",
-+                              (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);
-+
-+              printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]);
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",
-+                              (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);
-+
-+              dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);
-+      }
-+
-+      return bcmerror;
-+}
-+
-+void
-+dhd_conf_set_bw_cap(dhd_pub_t *dhd)
-+{
-+      struct {
-+              u32 band;
-+              u32 bw_cap;
-+      } param = {0, 0};
-+
-+      if (dhd->conf->bw_cap_2g >= 0) {
-+              param.band = WLC_BAND_2G;
-+              param.bw_cap = (uint)dhd->conf->bw_cap_2g;
-+              printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap);
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
-+      }
-+
-+      if (dhd->conf->bw_cap_5g >= 0) {
-+              param.band = WLC_BAND_5G;
-+              param.bw_cap = (uint)dhd->conf->bw_cap_5g;
-+              printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap);
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)&param, sizeof(param), TRUE);
-+      }
-+}
-+
-+void
-+dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp)
-+{
-+      int bcmerror = -1;
-+      char iovbuf[WLC_IOCTL_SMLEN];
-+      edcf_acparam_t *acparam;
-+
-+      bzero(iovbuf, sizeof(iovbuf));
-+
-+      /*
-+       * Get current acparams, using buf as an input buffer.
-+       * Return data is array of 4 ACs of wme params.
-+       */
-+      if (mode == 0)
-+              bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));
-+      else
-+              bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf));
-+      if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
-+              CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror));
-+              return;
-+      }
-+      memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);
-+
-+      acparam = &acp[AC_BK];
-+      CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
-+              __FUNCTION__,
-+              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
-+              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
-+              acparam->TXOP));
-+      acparam = &acp[AC_BE];
-+      CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
-+              __FUNCTION__,
-+              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
-+              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
-+              acparam->TXOP));
-+      acparam = &acp[AC_VI];
-+      CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
-+              __FUNCTION__,
-+              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
-+              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
-+              acparam->TXOP));
-+      acparam = &acp[AC_VO];
-+      CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
-+              __FUNCTION__,
-+              acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
-+              acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
-+              acparam->TXOP));
-+
-+      return;
-+}
-+
-+void
-+dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci)
-+{
-+      int aifsn, ecwmin, ecwmax, txop;
-+      edcf_acparam_t *acp;
-+      struct dhd_conf *conf = dhd->conf;
-+      wme_param_t *wme;
-+
-+      if (mode == 0)
-+              wme = &conf->wme_sta;
-+      else
-+              wme = &conf->wme_ap;
-+
-+      /* Default value */
-+      aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;
-+      ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;
-+      ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;
-+      txop = acparam_cur->TXOP;
-+
-+      /* Modified value */
-+      if (wme->aifsn[aci] > 0)
-+              aifsn = wme->aifsn[aci];
-+      if (wme->ecwmin[aci] > 0)
-+              ecwmin = wme->ecwmin[aci];
-+      if (wme->ecwmax[aci] > 0)
-+              ecwmax = wme->ecwmax[aci];
-+      if (wme->txop[aci] > 0)
-+              txop = wme->txop[aci];
-+
-+      if (!(wme->aifsn[aci] || wme->ecwmin[aci] ||
-+                      wme->ecwmax[aci] || wme->txop[aci]))
-+              return;
-+
-+      /* Update */
-+      acp = acparam_cur;
-+      acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);
-+      acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);
-+      acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));
-+      acp->TXOP = txop;
-+
-+      printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
-+              __FUNCTION__, mode?"ap":"sta",
-+              acp->ACI, acp->ACI&EDCF_AIFSN_MASK,
-+              acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
-+              acp->TXOP);
-+
-+      /*
-+      * Now use buf as an output buffer.
-+      * Put WME acparams after "wme_ac\0" in buf.
-+      * NOTE: only one of the four ACs can be set at a time.
-+      */
-+      if (mode == 0)
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);
-+      else
-+              dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE);
-+
-+}
-+
-+void
-+dhd_conf_set_wme(dhd_pub_t *dhd, int mode)
-+{
-+      edcf_acparam_t acparam_cur[AC_COUNT];
-+
-+      if (dhd && dhd->conf) {
-+              if (!dhd->conf->force_wme_ac) {
-+                      CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n",
-+                              __FUNCTION__, dhd->conf->force_wme_ac));
-+                      return;
-+              }
-+
-+              CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__));
-+              dhd_conf_get_wme(dhd, mode, acparam_cur);
-+
-+              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK);
-+              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE);
-+              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI);
-+              dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO);
-+
-+              CONFIG_TRACE(("%s: After change:\n", __FUNCTION__));
-+              dhd_conf_get_wme(dhd, mode, acparam_cur);
-+      } else {
-+              CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__));
-+      }
-+
-+      return;
-+}
-+
-+#ifdef PKT_FILTER_SUPPORT
-+void
-+dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
-+{
-+      int i, j;
-+      char str[12];
-+#define MACS "%02x%02x%02x%02x%02x%02x"
-+
-+      /*
-+       * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well.
-+       *   1) dhd_master_mode=0
-+       *   2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
-+       * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E)
-+       *   1) dhd_master_mode=1
-+       *   2) pkt_filter_del=100, 102, 103, 104, 105
-+       *   3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E
-+       * 3. magic pkt: magic_pkt_filter_add=141 0 1 12
-+       * 4. Filter out netbios pkt:
-+       *   Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089
-+       */
-+      for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {
-+              dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];
-+              printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]);
-+      }
-+      dhd->pktfilter_count += i;
-+
-+      for(i=0; i<dhd->conf->magic_pkt_filter_add.count; i++) {
-+              strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
-+              strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
-+              for (j=0; j<16; j++)
-+                      strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
-+              strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x");
-+              strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF");
-+              sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));
-+              for (j=0; j<16; j++)
-+                      strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str);
-+              dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i];
-+              dhd->pktfilter_count += 1;
-+      }
-+}
-+
-+bool
-+dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)
-+{
-+      int i;
-+
-+      if (dhd && dhd->conf) {
-+              for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {
-+                      if (id == dhd->conf->pkt_filter_del.id[i]) {
-+                              printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]);
-+                              return true;
-+                      }
-+              }
-+              return false;
-+      }
-+      return false;
-+}
-+
-+void
-+dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)
-+{
-+      dhd->pktfilter_count = 6;
-+      dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;
-+      dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
-+      dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";
-+      dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";
-+      dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
-+      /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/
-+      dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;
-+
-+      /* IPv4 broadcast address XXX.XXX.XXX.255 */
-+      dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";
-+      dhd->pktfilter_count++;
-+      /* discard IPv4 multicast address 224.0.0.0/4 */
-+      dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";
-+      dhd->pktfilter_count++;
-+      /* discard IPv6 multicast address FF00::/8 */
-+      dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";
-+      dhd->pktfilter_count++;
-+      /* discard Netbios pkt */
-+      dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";
-+      dhd->pktfilter_count++;
-+
-+}
-+#endif /* PKT_FILTER_SUPPORT */
-+
-+int
-+dhd_conf_get_pm(dhd_pub_t *dhd)
-+{
-+      if (dhd && dhd->conf)
-+              return dhd->conf->pm;
-+      return -1;
-+}
-+
-+#ifdef PROP_TXSTATUS
-+int
-+dhd_conf_get_disable_proptx(dhd_pub_t *dhd)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      int disable_proptx = -1;
-+      int fw_proptx = 0;
-+
-+      /* check fw proptx priority:
-+        * 1st: check fw support by wl cap
-+        * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default
-+        *        if you would like to disable it, please set disable_proptx=1 in config.txt
-+        * 3th: disable when proptxstatus not support in wl cap
-+        */
-+      if (FW_SUPPORTED(dhd, proptxstatus)) {
-+              fw_proptx = 1;
-+      } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
-+                      dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
-+              fw_proptx = 1;
-+      } else {
-+              fw_proptx = 0;
-+      }
-+
-+      /* returned disable_proptx value:
-+        * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)
-+        * 0: depend on fw support
-+        * 1: always disable proptx
-+        */
-+      if (conf->disable_proptx == 0) {
-+              // check fw support as well
-+              if (fw_proptx)
-+                      disable_proptx = 0;
-+              else
-+                      disable_proptx = 1;
-+      } else if (conf->disable_proptx >= 1) {
-+              disable_proptx = 1;
-+      } else {
-+              // check fw support as well
-+              if (fw_proptx)
-+                      disable_proptx = -1;
-+              else
-+                      disable_proptx = 1;
-+      }
-+
-+      printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx);
-+
-+      return disable_proptx;
-+}
-+#endif
-+
-+uint
-+pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf)
-+{
-+      bool findNewline, changenewline=FALSE, pick=FALSE;
-+      int column;
-+      uint n, pick_column=0;
-+
-+      findNewline = FALSE;
-+      column = 0;
-+
-+      if (start_pos >= len) {
-+              CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__));
-+              return 0;
-+      }
-+
-+      for (n = start_pos; n < len; n++) {
-+              if (varbuf[n] == '\r')
-+                      continue;
-+              if ((findNewline || changenewline) && varbuf[n] != '\n')
-+                      continue;
-+              findNewline = FALSE;
-+              if (varbuf[n] == '#') {
-+                      findNewline = TRUE;
-+                      continue;
-+              }
-+              if (varbuf[n] == '\\') {
-+                      changenewline = TRUE;
-+                      continue;
-+              }
-+              if (!changenewline && varbuf[n] == '\n') {
-+                      if (column == 0)
-+                              continue;
-+                      column = 0;
-+                      continue;
-+              }
-+              if (changenewline && varbuf[n] == '\n') {
-+                      changenewline = FALSE;
-+                      continue;
-+              }
-+
-+              if (column==0 && !pick) { // start to pick
-+                      pick = TRUE;
-+                      column++;
-+                      pick_column = 0;
-+              } else {
-+                      if (pick && column==0) { // stop to pick
-+                              pick = FALSE;
-+                              break;
-+                      } else
-+                              column++;
-+              }
-+              if (pick) {
-+                      if (varbuf[n] == 0x9)
-+                              continue;
-+                      if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ')
-+                              continue;
-+                      pickbuf[pick_column] = varbuf[n];
-+                      pick_column++;
-+              }
-+      }
-+
-+      return n; // return current position
-+}
-+
-+bool
-+dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      char *data = full_param+len_param;
-+
-+      if (!strncmp("dhd_msg_level=", full_param, len_param)) {
-+              dhd_msg_level = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level);
-+      }
-+#ifdef BCMSDIO
-+      else if (!strncmp("sd_msglevel=", full_param, len_param)) {
-+              sd_msglevel = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel);
-+      }
-+#endif
-+      else if (!strncmp("android_msg_level=", full_param, len_param)) {
-+              android_msg_level = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level);
-+      }
-+      else if (!strncmp("config_msg_level=", full_param, len_param)) {
-+              config_msg_level = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level);
-+      }
-+#ifdef WL_CFG80211
-+      else if (!strncmp("wl_dbg_level=", full_param, len_param)) {
-+              wl_dbg_level = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level);
-+      }
-+#endif
-+#if defined(WL_WIRELESS_EXT)
-+      else if (!strncmp("iw_msg_level=", full_param, len_param)) {
-+              iw_msg_level = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level);
-+      }
-+#endif
-+#if defined(DHD_DEBUG)
-+      else if (!strncmp("dhd_console_ms=", full_param, len_param)) {
-+              dhd_console_ms = (int)simple_strtol(data, NULL, 0);
-+              printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);
-+      }
-+#endif
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+void
-+dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val)
-+{
-+      char *pick_tmp, *pch;
-+
-+      /* Process WMM parameters */
-+      pick_tmp = pick;
-+      pch = bcmstrstr(pick_tmp, "aifsn ");
-+      if (pch) {
-+              wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);
-+              printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]);
-+      }
-+      pick_tmp = pick;
-+      pch = bcmstrstr(pick_tmp, "ecwmin ");
-+      if (pch) {
-+              wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);
-+              printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]);
-+      }
-+      pick_tmp = pick;
-+      pch = bcmstrstr(pick_tmp, "ecwmax ");
-+      if (pch) {
-+              wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);
-+              printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]);
-+      }
-+      pick_tmp = pick;
-+      pch = bcmstrstr(pick_tmp, "txop ");
-+      if (pch) {
-+              wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);
-+              printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]);
-+      }
-+
-+}
-+
-+bool
-+dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e
-+      // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e
-+
-+      /* Process WMM parameters */
-+      if (!strncmp("force_wme_ac=", full_param, len_param)) {
-+              conf->force_wme_ac = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);
-+      }
-+      else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE);
-+      }
-+      else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK);
-+      }
-+      else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI);
-+      }
-+      else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO);
-+      }
-+      else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE);
-+      }
-+      else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK);
-+      }
-+      else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI);
-+      }
-+      else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) {
-+              dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO);
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+bool
-+dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      int i, j;
-+      char *pch, *pick_tmp;
-+      wl_mac_list_t *mac_list;
-+      wl_mac_range_t *mac_range;
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      /* Process fw_by_mac:
-+       * fw_by_mac=[fw_mac_num] \
-+       *  [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \
-+       *                                    [oui1-1] [nic_start1-1] [nic_end1-1]... \
-+       *                                    [oui1-n] [nic_start1-n] [nic_end1-n] \
-+       *  [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \
-+       *                                    [oui2-1] [nic_start2-1] [nic_end2-1]... \
-+       *                                    [oui2-n] [nic_start2-n] [nic_end2-n] \
-+       * Ex: fw_by_mac=2 \
-+       *  fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
-+       *  fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
-+       *                           0x983B16 0x916157 0x916487
-+       */
-+
-+      if (!strncmp("fw_by_mac=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, " ", 0);
-+              conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
-+              if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) {
-+                      conf->fw_by_mac.count = 0;
-+                      CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
-+              }
-+              printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count);
-+              conf->fw_by_mac.m_mac_list_head = mac_list;
-+              for (i=0; i<conf->fw_by_mac.count; i++) {
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      strcpy(mac_list[i].name, pch);
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
-+                      printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,
-+                              mac_list[i].name, mac_list[i].count);
-+                      if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {
-+                              mac_list[i].count = 0;
-+                              CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
-+                              break;
-+                      }
-+                      mac_list[i].mac = mac_range;
-+                      for (j=0; j<mac_list[i].count; j++) {
-+                              pch = bcmstrtok(&pick_tmp, " ", 0);
-+                              mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
-+                              pch = bcmstrtok(&pick_tmp, " ", 0);
-+                              mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
-+                              pch = bcmstrtok(&pick_tmp, " ", 0);
-+                              mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
-+                              printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
-+                                      __FUNCTION__, mac_range[j].oui,
-+                                      mac_range[j].nic_start, mac_range[j].nic_end);
-+                      }
-+              }
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+bool
-+dhd_conf_read_nv_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      int i, j;
-+      char *pch, *pick_tmp;
-+      wl_mac_list_t *mac_list;
-+      wl_mac_range_t *mac_range;
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      /* Process nv_by_mac:
-+       * [nv_by_mac]: The same format as fw_by_mac
-+       */
-+      if (!strncmp("nv_by_mac=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, " ", 0);
-+              conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
-+              if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) {
-+                      conf->nv_by_mac.count = 0;
-+                      CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
-+              }
-+              printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count);
-+              conf->nv_by_mac.m_mac_list_head = mac_list;
-+              for (i=0; i<conf->nv_by_mac.count; i++) {
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      strcpy(mac_list[i].name, pch);
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
-+                      printf("%s: name=%s, mac_count=%d\n", __FUNCTION__,
-+                              mac_list[i].name, mac_list[i].count);
-+                      if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) {
-+                              mac_list[i].count = 0;
-+                              CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
-+                              break;
-+                      }
-+                      mac_list[i].mac = mac_range;
-+                      for (j=0; j<mac_list[i].count; j++) {
-+                              pch = bcmstrtok(&pick_tmp, " ", 0);
-+                              mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
-+                              pch = bcmstrtok(&pick_tmp, " ", 0);
-+                              mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
-+                              pch = bcmstrtok(&pick_tmp, " ", 0);
-+                              mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
-+                              printf("%s: oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
-+                                      __FUNCTION__, mac_range[j].oui,
-+                                      mac_range[j].nic_start, mac_range[j].nic_end);
-+                      }
-+              }
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+bool
-+dhd_conf_read_nv_by_chip(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      int i;
-+      char *pch, *pick_tmp;
-+      wl_chip_nv_path_t *chip_nv_path;
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      /* Process nv_by_chip:
-+       * nv_by_chip=[nv_chip_num] \
-+       *  [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \
-+       * Ex: nv_by_chip=2 \
-+       *  43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \
-+       */
-+      if (!strncmp("nv_by_chip=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, " ", 0);
-+              conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);
-+              if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) {
-+                      conf->nv_by_chip.count = 0;
-+                      CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
-+              }
-+              printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count);
-+              conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;
-+              for (i=0; i<conf->nv_by_chip.count; i++) {
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);
-+                      pch = bcmstrtok(&pick_tmp, " ", 0);
-+                      strcpy(chip_nv_path[i].name, pch);
-+                      printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__,
-+                              chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);
-+              }
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+bool
-+dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      if (!strncmp("roam_off=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->roam_off = 0;
-+              else
-+                      conf->roam_off = 1;
-+              printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off);
-+      }
-+      else if (!strncmp("roam_off_suspend=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->roam_off_suspend = 0;
-+              else
-+                      conf->roam_off_suspend = 1;
-+              printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend);
-+      }
-+      else if (!strncmp("roam_trigger=", full_param, len_param)) {
-+              conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: roam_trigger = %d\n", __FUNCTION__,
-+                      conf->roam_trigger[0]);
-+      }
-+      else if (!strncmp("roam_scan_period=", full_param, len_param)) {
-+              conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: roam_scan_period = %d\n", __FUNCTION__,
-+                      conf->roam_scan_period[0]);
-+      }
-+      else if (!strncmp("roam_delta=", full_param, len_param)) {
-+              conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]);
-+      }
-+      else if (!strncmp("fullroamperiod=", full_param, len_param)) {
-+              conf->fullroamperiod = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: fullroamperiod = %d\n", __FUNCTION__,
-+                      conf->fullroamperiod);
-+      } else
-+              return false;
-+
-+      return true;
-+}
-+
-+bool
-+dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      int i;
-+      char *pch, *pick_tmp;
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      /* Process country_list:
-+       * country_list=[country1]:[ccode1]/[regrev1],
-+       * [country2]:[ccode2]/[regrev2] \
-+       * Ex: country_list=US:US/0, TW:TW/1
-+       */
-+      if (!strncmp("country_list=", full_param, len_param)) {
-+              pick_tmp = data;
-+              for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {
-+                      /* Process country code */
-+                      pch = bcmstrtok(&pick_tmp, ":", 0);
-+                      if (!pch)
-+                              break;
-+                      strcpy(conf->country_list.cspec[i].country_abbrev, pch);
-+                      pch = bcmstrtok(&pick_tmp, "/", 0);
-+                      if (!pch)
-+                              break;
-+                      memcpy(conf->country_list.cspec[i].ccode, pch, 2);
-+                      pch = bcmstrtok(&pick_tmp, ", ", 0);
-+                      if (!pch)
-+                              break;
-+                      conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10);
-+                      conf->country_list.count ++;
-+                      CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__,
-+                              conf->country_list.cspec[i].country_abbrev,
-+                              conf->country_list.cspec[i].ccode,
-+                              conf->country_list.cspec[i].rev));
-+              }
-+              printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count);
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+#ifdef PKT_FILTER_SUPPORT
-+bool
-+dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+      char *pch, *pick_tmp;
-+      int i;
-+
-+      /* Process pkt filter:
-+       * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
-+       * 2) pkt_filter_del=100, 102, 103, 104, 105
-+       * 3) magic_pkt_filter_add=141 0 1 12
-+       */
-+      if (!strncmp("dhd_master_mode=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      dhd_master_mode = FALSE;
-+              else
-+                      dhd_master_mode = TRUE;
-+              printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode);
-+      }
-+      else if (!strncmp("pkt_filter_add=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, ",.-", 0);
-+              i=0;
-+              while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
-+                      strcpy(&conf->pkt_filter_add.filter[i][0], pch);
-+                      printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]);
-+                      pch = bcmstrtok(&pick_tmp, ",.-", 0);
-+                      i++;
-+              }
-+              conf->pkt_filter_add.count = i;
-+      }
-+      else if (!strncmp("pkt_filter_del=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, " ,.-", 0);
-+              i=0;
-+              while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
-+                      conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);
-+                      pch = bcmstrtok(&pick_tmp, " ,.-", 0);
-+                      i++;
-+              }
-+              conf->pkt_filter_del.count = i;
-+              printf("%s: pkt_filter_del id = ", __FUNCTION__);
-+              for (i=0; i<conf->pkt_filter_del.count; i++)
-+                      printf("%d ", conf->pkt_filter_del.id[i]);
-+              printf("\n");
-+      }
-+      else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, ",.-", 0);
-+              i=0;
-+              while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
-+                      strcpy(&conf->magic_pkt_filter_add.filter[i][0], pch);
-+                      printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]);
-+                      pch = bcmstrtok(&pick_tmp, ",.-", 0);
-+                      i++;
-+              }
-+              conf->magic_pkt_filter_add.count = i;
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+#endif
-+
-+#ifdef IAPSTA_PREINIT
-+/*
-+ * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1]
-+ * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]
-+               hidden [y|n] maxassoc [x]
-+               amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]
-+               emode [none|wep|tkip|aes|tkipaes]
-+               key [xxxxx]
-+ * iapsta_enable=ifname [wlan0|wlan1]
-+*/
-+bool
-+dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      if (!strncmp("iapsta_init=", full_param, len_param)) {
-+              sprintf(conf->iapsta_init, "iapsta_init %s", data);
-+              printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);
-+      }
-+      else if (!strncmp("iapsta_config=", full_param, len_param)) {
-+              sprintf(conf->iapsta_config, "iapsta_config %s", data);
-+              printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);
-+      }
-+      else if (!strncmp("iapsta_enable=", full_param, len_param)) {
-+              sprintf(conf->iapsta_enable, "iapsta_enable %s", data);
-+              printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+#endif
-+
-+#ifdef IDHCPC
-+bool
-+dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      if (!strncmp("dhcpc_enable=", full_param, len_param)) {
-+              conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+#endif
-+
-+#ifdef BCMSDIO
-+bool
-+dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      if (!strncmp("dhd_doflow=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      dhd_doflow = FALSE;
-+              else
-+                      dhd_doflow = TRUE;
-+              printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow);
-+      }
-+      else if (!strncmp("dhd_slpauto=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      dhd_slpauto = FALSE;
-+              else
-+                      dhd_slpauto = TRUE;
-+              printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);
-+      }
-+      else if (!strncmp("kso_enable=", full_param, len_param)) {
-+              if (!strncmp(data, "1", 1))
-+                      dhd_slpauto = FALSE;
-+              else
-+                      dhd_slpauto = TRUE;
-+              printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);
-+      }
-+      else if (!strncmp("bus:txglom=", full_param, len_param)) {
-+              conf->bus_txglom = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);
-+      }
-+      else if (!strncmp("use_rxchain=", full_param, len_param)) {
-+              conf->use_rxchain = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain);
-+      }
-+      else if (!strncmp("dhd_txminmax=", full_param, len_param)) {
-+              conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax);
-+      }
-+      else if (!strncmp("txinrx_thres=", full_param, len_param)) {
-+              conf->txinrx_thres = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres);
-+      }
-+      else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) {
-+              conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);
-+      }
-+      else if (!strncmp("oob_enabled_later=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->oob_enabled_later = FALSE;
-+              else
-+                      conf->oob_enabled_later = TRUE;
-+              printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);
-+      }
-+#if defined(BCMSDIOH_TXGLOM)
-+      else if (!strncmp("txglomsize=", full_param, len_param)) {
-+              conf->txglomsize = (uint)simple_strtol(data, NULL, 10);
-+              if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
-+                      conf->txglomsize = SDPCM_MAXGLOM_SIZE;
-+              printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize);
-+      }
-+      else if (!strncmp("swtxglom=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->swtxglom = FALSE;
-+              else
-+                      conf->swtxglom = TRUE;
-+              printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom);
-+      }
-+      else if (!strncmp("txglom_ext=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->txglom_ext = FALSE;
-+              else
-+                      conf->txglom_ext = TRUE;
-+              printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext);
-+              if (conf->txglom_ext) {
-+                      if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID))
-+                              conf->txglom_bucket_size = 1680;
-+                      else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
-+                                      conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID)
-+                              conf->txglom_bucket_size = 1684;
-+              }
-+              printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size);
-+      }
-+      else if (!strncmp("bus:rxglom=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->bus_rxglom = FALSE;
-+              else
-+                      conf->bus_rxglom = TRUE;
-+              printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);
-+      }
-+      else if (!strncmp("dhd_poll=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->dhd_poll = 0;
-+              else
-+                      conf->dhd_poll = 1;
-+              printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);
-+      }
-+      else if (!strncmp("deferred_tx_len=", full_param, len_param)) {
-+              conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);
-+      }
-+      else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->txctl_tmo_fix = FALSE;
-+              else
-+                      conf->txctl_tmo_fix = TRUE;
-+              printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);
-+      }
-+      else if (!strncmp("tx_in_rx=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->tx_in_rx = FALSE;
-+              else
-+                      conf->tx_in_rx = TRUE;
-+              printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);
-+      }
-+      else if (!strncmp("tx_max_offset=", full_param, len_param)) {
-+              conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);
-+      }
-+      else if (!strncmp("txglom_mode=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->txglom_mode = FALSE;
-+              else
-+                      conf->txglom_mode = TRUE;
-+              printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);
-+      }
-+#endif
-+      else
-+              return false;
-+
-+      return true;
-+}
-+#endif
-+
-+bool
-+dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+
-+      if (!strncmp("lpc=", full_param, len_param)) {
-+              conf->lpc = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);
-+      }
-+      else if (!strncmp("deepsleep=", full_param, len_param)) {
-+              if (!strncmp(data, "1", 1))
-+                      conf->deepsleep = TRUE;
-+              else
-+                      conf->deepsleep = FALSE;
-+              printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);
-+      }
-+      else if (!strncmp("PM=", full_param, len_param)) {
-+              conf->pm = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: PM = %d\n", __FUNCTION__, conf->pm);
-+      }
-+      else if (!strncmp("pm_in_suspend=", full_param, len_param)) {
-+              conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);
-+      }
-+      else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) {
-+              conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);
-+      }
-+      else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {
-+              if (!strncmp(data, "1", 1))
-+                      conf->xmit_in_suspend = TRUE;
-+              else
-+                      conf->xmit_in_suspend = FALSE;
-+              printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+bool
-+dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+      char *data = full_param+len_param;
-+      uint len_data = strlen(data);
-+      char *pch, *pick_tmp;
-+      int i;
-+
-+      if (!strncmp("band=", full_param, len_param)) {
-+              /* Process band:
-+               * band=a for 5GHz only and band=b for 2.4GHz only
-+               */
-+              if (!strcmp(data, "b"))
-+                      conf->band = WLC_BAND_2G;
-+              else if (!strcmp(data, "a"))
-+                      conf->band = WLC_BAND_5G;
-+              else
-+                      conf->band = WLC_BAND_AUTO;
-+              printf("%s: band = %d\n", __FUNCTION__, conf->band);
-+      }
-+      else if (!strncmp("mimo_bw_cap=", full_param, len_param)) {
-+              conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);
-+      }
-+      else if (!strncmp("bw_cap_2g=", full_param, len_param)) {
-+              conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0);
-+              printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);
-+      }
-+      else if (!strncmp("bw_cap_5g=", full_param, len_param)) {
-+              conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0);
-+              printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g);
-+      }
-+      else if (!strncmp("ccode=", full_param, len_param)) {
-+              memset(&conf->cspec, 0, sizeof(wl_country_t));
-+              memcpy(conf->cspec.country_abbrev, data, len_data);
-+              memcpy(conf->cspec.ccode, data, len_data);
-+              printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode);
-+      }
-+      else if (!strncmp("regrev=", full_param, len_param)) {
-+              conf->cspec.rev = (int32)simple_strtol(data, NULL, 10);
-+              printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev);
-+      }
-+      else if (!strncmp("channels=", full_param, len_param)) {
-+              pick_tmp = data;
-+              pch = bcmstrtok(&pick_tmp, " ,.-", 0);
-+              i=0;
-+              while (pch != NULL && i<WL_NUMCHANNELS) {
-+                      conf->channels.channel[i] = (uint32)simple_strtol(pch, NULL, 10);
-+                      pch = bcmstrtok(&pick_tmp, " ,.-", 0);
-+                      i++;
-+              }
-+              conf->channels.count = i;
-+              printf("%s: channels = ", __FUNCTION__);
-+              for (i=0; i<conf->channels.count; i++)
-+                      printf("%d ", conf->channels.channel[i]);
-+              printf("\n");
-+      }
-+      else if (!strncmp("keep_alive_period=", full_param, len_param)) {
-+              conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: keep_alive_period = %d\n", __FUNCTION__,
-+                      conf->keep_alive_period);
-+      }
-+      else if (!strncmp("stbc=", full_param, len_param)) {
-+              conf->stbc = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc);
-+      }
-+      else if (!strncmp("phy_oclscdenable=", full_param, len_param)) {
-+              conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable);
-+      }
-+      else if (!strncmp("srl=", full_param, len_param)) {
-+              conf->srl = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: srl = %d\n", __FUNCTION__, conf->srl);
-+      }
-+      else if (!strncmp("lrl=", full_param, len_param)) {
-+              conf->lrl = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl);
-+      }
-+      else if (!strncmp("bcn_timeout=", full_param, len_param)) {
-+              conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);
-+      }
-+      else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) {
-+              conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);
-+      }
-+      else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) {
-+              conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);
-+      }
-+      else if (!strncmp("spect=", full_param, len_param)) {
-+              conf->spect = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: spect = %d\n", __FUNCTION__, conf->spect);
-+      }
-+      else if (!strncmp("txbf=", full_param, len_param)) {
-+              conf->txbf = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf);
-+      }
-+      else if (!strncmp("frameburst=", full_param, len_param)) {
-+              conf->frameburst = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst);
-+      }
-+      else if (!strncmp("disable_proptx=", full_param, len_param)) {
-+              conf->disable_proptx = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx);
-+      }
-+#ifdef DHDTCPACK_SUPPRESS
-+      else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) {
-+              conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);
-+      }
-+#endif
-+      else if (!strncmp("pktprio8021x=", full_param, len_param)) {
-+              conf->pktprio8021x = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);
-+      }
-+      else if (!strncmp("dhd_txbound=", full_param, len_param)) {
-+              dhd_txbound = (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound);
-+      }
-+      else if (!strncmp("dhd_rxbound=", full_param, len_param)) {
-+              dhd_rxbound = (uint)simple_strtol(data, NULL, 10);
-+              printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);
-+      }
-+      else if (!strncmp("rsdb_mode=", full_param, len_param)) {
-+              conf->rsdb_mode = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode);
-+      }
-+      else if (!strncmp("vhtmode=", full_param, len_param)) {
-+              if (!strncmp(data, "0", 1))
-+                      conf->vhtmode = 0;
-+              else
-+                      conf->vhtmode = 1;
-+              printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);
-+      }
-+      else if (!strncmp("num_different_channels=", full_param, len_param)) {
-+              conf->num_different_channels = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);
-+      }
-+      else if (!strncmp("autocountry=", full_param, len_param)) {
-+              conf->autocountry = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry);
-+      }
-+      else if (!strncmp("tsq=", full_param, len_param)) {
-+              conf->tsq = (int)simple_strtol(data, NULL, 10);
-+              printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);
-+      }
-+      else
-+              return false;
-+
-+      return true;
-+}
-+
-+int
-+dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
-+{
-+      int bcmerror = -1;
-+      uint len, start_pos=0;
-+      void * image = NULL;
-+      char * memblock = NULL;
-+      char *bufp, *pick = NULL, *pch;
-+      bool conf_file_exists;
-+      uint len_param;
-+
-+      conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));
-+      if (!conf_file_exists) {
-+              printf("%s: config path %s\n", __FUNCTION__, conf_path);
-+              return (0);
-+      }
-+
-+      if (conf_file_exists) {
-+              image = dhd_os_open_image(conf_path);
-+              if (image == NULL) {
-+                      printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path);
-+                      goto err;
-+              }
-+      }
-+
-+      memblock = MALLOC(dhd->osh, MAXSZ_CONFIG);
-+      if (memblock == NULL) {
-+              CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
-+                      __FUNCTION__, MAXSZ_CONFIG));
-+              goto err;
-+      }
-+
-+      pick = MALLOC(dhd->osh, MAXSZ_BUF);
-+      if (!pick) {
-+              CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n",
-+                      __FUNCTION__, MAXSZ_BUF));
-+              goto err;
-+      }
-+
-+      /* Read variables */
-+      if (conf_file_exists) {
-+              len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image);
-+      }
-+      if (len > 0 && len < MAXSZ_CONFIG) {
-+              bufp = (char *)memblock;
-+              bufp[len] = 0;
-+
-+              while (start_pos < len) {
-+                      memset(pick, 0, MAXSZ_BUF);
-+                      start_pos = pick_config_vars(bufp, len, start_pos, pick);
-+                      pch = strchr(pick, '=');
-+                      if (pch != NULL) {
-+                              len_param = pch-pick+1;
-+                              if (len_param == strlen(pick)) {
-+                                      CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));
-+                                      continue;
-+                              }
-+                      } else {
-+                              CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick));
-+                              continue;
-+                      }
-+
-+                      if (dhd_conf_read_log_level(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_roam_params(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_country_list(dhd, pick, len_param))
-+                              continue;
-+#ifdef PKT_FILTER_SUPPORT
-+                      else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))
-+                              continue;
-+#endif /* PKT_FILTER_SUPPORT */
-+#ifdef IAPSTA_PREINIT
-+                      else if (dhd_conf_read_iapsta(dhd, pick, len_param))
-+                              continue;
-+#endif /* IAPSTA_PREINIT */
-+#ifdef IDHCPC
-+                      else if (dhd_conf_read_dhcp_params(dhd, pick, len_param))
-+                              continue;
-+#endif /* IDHCPC */
-+#ifdef BCMSDIO
-+                      else if (dhd_conf_read_sdio_params(dhd, pick, len_param))
-+                              continue;
-+#endif /* BCMSDIO */
-+                      else if (dhd_conf_read_pm_params(dhd, pick, len_param))
-+                              continue;
-+                      else if (dhd_conf_read_others(dhd, pick, len_param))
-+                              continue;
-                       else
--                              continue;\r
--              }\r
--\r
--              bcmerror = 0;\r
--      } else {\r
--              CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));\r
--              bcmerror = BCME_SDIO_ERROR;\r
--      }\r
--\r
--err:\r
--      if (pick)\r
--              MFREE(dhd->osh, pick, MAXSZ_BUF);\r
--\r
--      if (memblock)\r
--              MFREE(dhd->osh, memblock, MAXSZ_CONFIG);\r
--\r
--      if (image)\r
--              dhd_os_close_image(image);\r
--\r
--      return bcmerror;\r
--}\r
--\r
--int\r
--dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)\r
--{\r
--      printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);\r
--      dhd->conf->chip = chip;\r
--      dhd->conf->chiprev = chiprev;\r
--      return 0;\r
--}\r
--\r
--uint\r
--dhd_conf_get_chip(void *context)\r
--{\r
--      dhd_pub_t *dhd = context;\r
--\r
--      if (dhd && dhd->conf)\r
--              return dhd->conf->chip;\r
--      return 0;\r
--}\r
--\r
--uint\r
--dhd_conf_get_chiprev(void *context)\r
--{\r
--      dhd_pub_t *dhd = context;\r
--\r
--      if (dhd && dhd->conf)\r
--              return dhd->conf->chiprev;\r
--      return 0;\r
--}\r
--\r
--#ifdef BCMSDIO\r
--void\r
--dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)\r
--{\r
--      struct dhd_conf *conf = dhd->conf;\r
--\r
--      if (enable) {\r
--#if defined(SWTXGLOM)\r
--              if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
--                              conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
--                              conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
--                      // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom\r
--                      conf->swtxglom = TRUE;\r
--                      conf->txglom_ext = TRUE;\r
--              }\r
--              if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) {\r
--                      conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only\r
--              }\r
--#elif defined(BCMSDIOH_TXGLOM_EXT)\r
--              if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
--                              conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
--                              conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
--                      conf->txglom_mode = SDPCM_TXGLOM_CPY;\r
--              }\r
--#endif\r
--              // other parameters set in preinit or config.txt\r
--      } else {\r
--              // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt\r
--              conf->txglom_ext = FALSE;\r
--              conf->txglom_bucket_size = 0;\r
--              conf->txglomsize = 0;\r
--              conf->deferred_tx_len = 0;\r
--      }\r
--      printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__,\r
--              conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size);\r
--      printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__,\r
--              conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom);\r
--      printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,\r
--              conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax);\r
--      printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__,\r
--              conf->tx_max_offset, conf->txctl_tmo_fix);\r
--\r
--}\r
--#endif\r
--\r
--int\r
--dhd_conf_preinit(dhd_pub_t *dhd)\r
--{\r
--      struct dhd_conf *conf = dhd->conf;\r
--\r
--      CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
--\r
--#ifdef BCMSDIO\r
--      dhd_conf_free_mac_list(&conf->fw_by_mac);\r
--      dhd_conf_free_mac_list(&conf->nv_by_mac);\r
--      dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);\r
--#endif\r
--      memset(&conf->country_list, 0, sizeof(conf_country_list_t));\r
--      conf->band = WLC_BAND_AUTO;\r
--      conf->mimo_bw_cap = -1;\r
--      conf->bw_cap_2g = -1;\r
--      conf->bw_cap_5g = -1;\r
--      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {\r
--              strcpy(conf->cspec.country_abbrev, "ALL");\r
--              strcpy(conf->cspec.ccode, "ALL");\r
--              conf->cspec.rev = 0;\r
--      } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID ||\r
--                      conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||\r
--                      conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID ||\r
--                      conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) {\r
--              strcpy(conf->cspec.country_abbrev, "CN");\r
--              strcpy(conf->cspec.ccode, "CN");\r
--              conf->cspec.rev = 38;\r
--      } else {\r
--              strcpy(conf->cspec.country_abbrev, "CN");\r
--              strcpy(conf->cspec.ccode, "CN");\r
--              conf->cspec.rev = 0;\r
--      }\r
--      memset(&conf->channels, 0, sizeof(wl_channel_list_t));\r
--      conf->roam_off = 1;\r
--      conf->roam_off_suspend = 1;\r
--#ifdef CUSTOM_ROAM_TRIGGER_SETTING\r
--      conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;\r
--#else\r
--      conf->roam_trigger[0] = -65;\r
--#endif\r
--      conf->roam_trigger[1] = WLC_BAND_ALL;\r
--      conf->roam_scan_period[0] = 10;\r
--      conf->roam_scan_period[1] = WLC_BAND_ALL;\r
--#ifdef CUSTOM_ROAM_DELTA_SETTING\r
--      conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;\r
--#else\r
--      conf->roam_delta[0] = 15;\r
--#endif\r
--      conf->roam_delta[1] = WLC_BAND_ALL;\r
-+                              continue;
-+              }
-+
-+              bcmerror = 0;
-+      } else {
-+              CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));
-+              bcmerror = BCME_SDIO_ERROR;
-+      }
-+
-+err:
-+      if (pick)
-+              MFREE(dhd->osh, pick, MAXSZ_BUF);
-+
-+      if (memblock)
-+              MFREE(dhd->osh, memblock, MAXSZ_CONFIG);
-+
-+      if (image)
-+              dhd_os_close_image(image);
-+
-+      return bcmerror;
-+}
-+
-+int
-+dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)
-+{
-+      printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev);
-+      dhd->conf->chip = chip;
-+      dhd->conf->chiprev = chiprev;
-+      return 0;
-+}
-+
-+uint
-+dhd_conf_get_chip(void *context)
-+{
-+      dhd_pub_t *dhd = context;
-+
-+      if (dhd && dhd->conf)
-+              return dhd->conf->chip;
-+      return 0;
-+}
-+
-+uint
-+dhd_conf_get_chiprev(void *context)
-+{
-+      dhd_pub_t *dhd = context;
-+
-+      if (dhd && dhd->conf)
-+              return dhd->conf->chiprev;
-+      return 0;
-+}
-+
-+#ifdef BCMSDIO
-+void
-+dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+
-+      if (enable) {
-+#if defined(SWTXGLOM)
-+              if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
-+                              conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
-+                              conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
-+                      // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom
-+                      conf->swtxglom = TRUE;
-+                      conf->txglom_ext = TRUE;
-+              }
-+              if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) {
-+                      conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only
-+              }
-+#elif defined(BCMSDIOH_TXGLOM_EXT)
-+              if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
-+                              conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
-+                              conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
-+                      conf->txglom_mode = SDPCM_TXGLOM_CPY;
-+              }
-+#endif
-+              // other parameters set in preinit or config.txt
-+      } else {
-+              // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt
-+              conf->txglom_ext = FALSE;
-+              conf->txglom_bucket_size = 0;
-+              conf->txglomsize = 0;
-+              conf->deferred_tx_len = 0;
-+      }
-+      printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__,
-+              conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size);
-+      printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__,
-+              conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom);
-+      printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__,
-+              conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax);
-+      printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__,
-+              conf->tx_max_offset, conf->txctl_tmo_fix);
-+
-+}
-+#endif
-+
-+int
-+dhd_conf_preinit(dhd_pub_t *dhd)
-+{
-+      struct dhd_conf *conf = dhd->conf;
-+
-+      CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
-+
-+#ifdef BCMSDIO
-+      dhd_conf_free_mac_list(&conf->fw_by_mac);
-+      dhd_conf_free_mac_list(&conf->nv_by_mac);
-+      dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
-+#endif
-+      memset(&conf->country_list, 0, sizeof(conf_country_list_t));
-+      conf->band = WLC_BAND_AUTO;
-+      conf->mimo_bw_cap = -1;
-+      conf->bw_cap_2g = -1;
-+      conf->bw_cap_5g = -1;
-+      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {
-+              strcpy(conf->cspec.country_abbrev, "ALL");
-+              strcpy(conf->cspec.ccode, "ALL");
-+              conf->cspec.rev = 0;
-+      } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID ||
-+                      conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
-+                      conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID ||
-+                      conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) {
-+              strcpy(conf->cspec.country_abbrev, "CN");
-+              strcpy(conf->cspec.ccode, "CN");
-+              conf->cspec.rev = 38;
-+      } else {
-+              strcpy(conf->cspec.country_abbrev, "CN");
-+              strcpy(conf->cspec.ccode, "CN");
-+              conf->cspec.rev = 0;
-+      }
-+      memset(&conf->channels, 0, sizeof(wl_channel_list_t));
-+      conf->roam_off = 1;
-+      conf->roam_off_suspend = 1;
-+#ifdef CUSTOM_ROAM_TRIGGER_SETTING
-+      conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING;
-+#else
-+      conf->roam_trigger[0] = -65;
-+#endif
-+      conf->roam_trigger[1] = WLC_BAND_ALL;
-+      conf->roam_scan_period[0] = 10;
-+      conf->roam_scan_period[1] = WLC_BAND_ALL;
-+#ifdef CUSTOM_ROAM_DELTA_SETTING
-+      conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING;
-+#else
-+      conf->roam_delta[0] = 15;
-+#endif
-+      conf->roam_delta[1] = WLC_BAND_ALL;
- #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
--      conf->fullroamperiod = 60;\r
-+      conf->fullroamperiod = 60;
- #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
--      conf->fullroamperiod = 120;\r
--#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */\r
--#ifdef CUSTOM_KEEP_ALIVE_SETTING\r
--      conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;\r
--#else\r
--      conf->keep_alive_period = 28000;\r
--#endif\r
--      conf->force_wme_ac = 0;\r
--      memset(&conf->wme_sta, 0, sizeof(wme_param_t));\r
--      memset(&conf->wme_ap, 0, sizeof(wme_param_t));\r
--      conf->stbc = -1;\r
--      conf->phy_oclscdenable = -1;\r
--#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
--      conf->bcn_timeout = 15;\r
--      conf->spect = -1;\r
--      conf->txbf = -1;\r
--      conf->lpc = -1;\r
--      conf->disable_proptx = -1;\r
--#ifdef BCMSDIO\r
--      conf->bus_txglom = -1;\r
--      conf->use_rxchain = 0;\r
--      conf->bus_rxglom = TRUE;\r
--      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 = FALSE;\r
--      conf->tx_in_rx = TRUE;\r
--      conf->txglom_mode = SDPCM_TXGLOM_MDESC;\r
--      conf->deferred_tx_len = 0;\r
--      conf->dhd_txminmax = 1;\r
--      conf->txinrx_thres = -1;\r
--      conf->sd_f2_blocksize = 0;\r
--      conf->oob_enabled_later = FALSE;\r
--#endif\r
--      conf->ampdu_ba_wsize = 0;\r
--      conf->ampdu_hostreorder = -1;\r
--      conf->dpc_cpucore = -1;\r
--      conf->rxf_cpucore = -1;\r
--      conf->frameburst = -1;\r
--      conf->deepsleep = FALSE;\r
--      conf->pm = -1;\r
--      conf->pm_in_suspend = -1;\r
--      conf->pm2_sleep_ret = -1;\r
--      conf->num_different_channels = -1;\r
--      conf->xmit_in_suspend = TRUE;\r
--#ifdef IDHCPC\r
--      conf->dhcpc_enable = -1;\r
--#endif\r
--      conf->tsq = 0;\r
-+      conf->fullroamperiod = 120;
-+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
-+#ifdef CUSTOM_KEEP_ALIVE_SETTING
-+      conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING;
-+#else
-+      conf->keep_alive_period = 28000;
-+#endif
-+      conf->force_wme_ac = 0;
-+      memset(&conf->wme_sta, 0, sizeof(wme_param_t));
-+      memset(&conf->wme_ap, 0, sizeof(wme_param_t));
-+      conf->stbc = -1;
-+      conf->phy_oclscdenable = -1;
-+#ifdef PKT_FILTER_SUPPORT
-+      memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));
-+      memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));
-+      memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t));
-+#endif
-+      conf->srl = -1;
-+      conf->lrl = -1;
-+      conf->bcn_timeout = 15;
-+      conf->spect = -1;
-+      conf->txbf = -1;
-+      conf->lpc = -1;
-+      conf->disable_proptx = -1;
-+#ifdef BCMSDIO
-+      conf->bus_txglom = -1;
-+      conf->use_rxchain = 0;
-+      conf->bus_rxglom = TRUE;
-+      conf->txglom_ext = FALSE;
-+      conf->tx_max_offset = 0;
-+      conf->txglomsize = SDPCM_DEFGLOM_SIZE;
-+      conf->dhd_poll = -1;
-+      conf->txctl_tmo_fix = FALSE;
-+      conf->tx_in_rx = TRUE;
-+      conf->txglom_mode = SDPCM_TXGLOM_MDESC;
-+      conf->deferred_tx_len = 0;
-+      conf->dhd_txminmax = 1;
-+      conf->txinrx_thres = -1;
-+      conf->sd_f2_blocksize = 0;
-+      conf->oob_enabled_later = FALSE;
-+#endif
-+      conf->ampdu_ba_wsize = 0;
-+      conf->ampdu_hostreorder = -1;
-+      conf->dpc_cpucore = -1;
-+      conf->rxf_cpucore = -1;
-+      conf->frameburst = -1;
-+      conf->deepsleep = FALSE;
-+      conf->pm = -1;
-+      conf->pm_in_suspend = -1;
-+      conf->pm2_sleep_ret = -1;
-+      conf->num_different_channels = -1;
-+      conf->xmit_in_suspend = TRUE;
-+#ifdef IDHCPC
-+      conf->dhcpc_enable = -1;
-+#endif
-+      conf->tsq = 0;
-+#ifdef DHDTCPACK_SUPPRESS
-+      conf->tcpack_sup_mode = TCPACK_SUP_OFF;
-+#endif
-+      conf->pktprio8021x = -1;
-+      conf->rsdb_mode = -2;
-+      conf->vhtmode = -1;
-+      conf->autocountry = -1;
-+#ifdef IAPSTA_PREINIT
-+      memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init));
-+      memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config));
-+      memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable));
-+#endif
-+#ifdef BCMSDIO
-+      if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) {
-+              conf->txctl_tmo_fix = 1;
-+      }
-+#endif
-+      if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||
-+                      conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID ||
-+                      conf->chip == BCM4359_CHIP_ID) {
- #ifdef DHDTCPACK_SUPPRESS
--      conf->tcpack_sup_mode = TCPACK_SUP_OFF;\r
--#endif\r
--      conf->pktprio8021x = -1;\r
--      conf->rsdb_mode = -2;\r
--      conf->vhtmode = -1;\r
--      conf->autocountry = -1;\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
--#ifdef BCMSDIO\r
--      if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) {\r
--              conf->txctl_tmo_fix = 1;\r
--      }\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
--              conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;\r
--#endif\r
--              dhd_rxbound = 64;\r
--              dhd_txbound = 64;\r
--              conf->txbf = 1;\r
--              conf->frameburst = 1;\r
--#ifdef BCMSDIO\r
--              conf->dhd_txminmax = -1;\r
--              conf->txinrx_thres = 128;\r
--              conf->sd_f2_blocksize = 256;\r
--              conf->oob_enabled_later = TRUE;\r
--#endif\r
--      }\r
--\r
--#ifdef BCMSDIO\r
--#if defined(SWTXGLOM)\r
--      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
--                      conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
--                      conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
--              conf->swtxglom = FALSE; // disabled by default\r
--              conf->txglom_ext = TRUE; // enabled by default\r
--              conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled\r
--              conf->txglomsize = 16;\r
--      } else {\r
--              conf->swtxglom = FALSE; // use 1.201.59.x txglom by default\r
--              conf->txglom_ext = FALSE;\r
--      }\r
--\r
--      if (conf->chip == BCM43362_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1680; // fixed value, don't change\r
--              conf->tx_in_rx = FALSE;\r
--              conf->tx_max_offset = 1;\r
--      }\r
--      if (conf->chip == BCM4330_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1680; // fixed value, don't change\r
--              conf->tx_in_rx = FALSE;\r
--              conf->tx_max_offset = 0;\r
--      }\r
--      if (conf->chip == BCM4334_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1684; // fixed value, don't change\r
--              conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle\r
--              conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110\r
--      }\r
--      if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1684; // fixed value, don't change\r
--              conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle\r
--              conf->tx_max_offset = 1;\r
--      }\r
--      if (conf->chip == BCM4324_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1684; // fixed value, don't change\r
--              conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle\r
--              conf->tx_max_offset = 0;\r
--      }\r
--#endif\r
--#if defined(BCMSDIOH_TXGLOM_EXT)\r
--      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||\r
--                      conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||\r
--                      conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
--              conf->txglom_ext = TRUE;\r
--              conf->use_rxchain = 0;\r
--              conf->tx_in_rx = TRUE;\r
--              conf->tx_max_offset = 1;\r
--      } else {\r
--              conf->txglom_ext = FALSE;\r
--      }\r
--      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1680; // fixed value, don't change\r
--              conf->txglomsize = 6;\r
--      }\r
--      if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||\r
--                      conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {\r
--              conf->txglom_bucket_size = 1684; // fixed value, don't change\r
--              conf->txglomsize = 16;\r
--      }\r
--#endif\r
--      if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)\r
--              conf->txglomsize = SDPCM_MAXGLOM_SIZE;\r
--      conf->deferred_tx_len = conf->txglomsize;\r
--#endif\r
--\r
--      return 0;\r
--}\r
--\r
--int\r
--dhd_conf_reset(dhd_pub_t *dhd)\r
--{\r
--#ifdef BCMSDIO\r
--      dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);\r
--      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
--      memset(dhd->conf, 0, sizeof(dhd_conf_t));\r
--      return 0;\r
--}\r
--\r
--int\r
--dhd_conf_attach(dhd_pub_t *dhd)\r
--{\r
--      dhd_conf_t *conf;\r
--\r
--      CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
--\r
--      if (dhd->conf != NULL) {\r
--              printf("%s: config is attached before!\n", __FUNCTION__);\r
--              return 0;\r
--      }\r
--      /* Allocate private bus interface state */\r
--      if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {\r
--              CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));\r
--              goto fail;\r
--      }\r
--      memset(conf, 0, sizeof(dhd_conf_t));\r
--\r
--      dhd->conf = conf;\r
--\r
--      return 0;\r
--\r
--fail:\r
--      if (conf != NULL)\r
--              MFREE(dhd->osh, conf, sizeof(dhd_conf_t));\r
--      return BCME_NOMEM;\r
--}\r
--\r
--void\r
--dhd_conf_detach(dhd_pub_t *dhd)\r
--{\r
--      CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));\r
--\r
--      if (dhd->conf) {\r
--#ifdef BCMSDIO\r
--              dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);\r
--              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
--              MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));\r
--      }\r
--      dhd->conf = NULL;\r
--}\r
-+              conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;
-+#endif
-+              dhd_rxbound = 64;
-+              dhd_txbound = 64;
-+              conf->txbf = 1;
-+              conf->frameburst = 1;
-+#ifdef BCMSDIO
-+              conf->dhd_txminmax = -1;
-+              conf->txinrx_thres = 128;
-+              conf->sd_f2_blocksize = 256;
-+              conf->oob_enabled_later = TRUE;
-+#endif
-+      }
-+
-+#ifdef BCMSDIO
-+#if defined(SWTXGLOM)
-+      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
-+                      conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
-+                      conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
-+              conf->swtxglom = FALSE; // disabled by default
-+              conf->txglom_ext = TRUE; // enabled by default
-+              conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled
-+              conf->txglomsize = 16;
-+      } else {
-+              conf->swtxglom = FALSE; // use 1.201.59.x txglom by default
-+              conf->txglom_ext = FALSE;
-+      }
-+
-+      if (conf->chip == BCM43362_CHIP_ID) {
-+              conf->txglom_bucket_size = 1680; // fixed value, don't change
-+              conf->tx_in_rx = FALSE;
-+              conf->tx_max_offset = 1;
-+      }
-+      if (conf->chip == BCM4330_CHIP_ID) {
-+              conf->txglom_bucket_size = 1680; // fixed value, don't change
-+              conf->tx_in_rx = FALSE;
-+              conf->tx_max_offset = 0;
-+      }
-+      if (conf->chip == BCM4334_CHIP_ID) {
-+              conf->txglom_bucket_size = 1684; // fixed value, don't change
-+              conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
-+              conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110
-+      }
-+      if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) {
-+              conf->txglom_bucket_size = 1684; // fixed value, don't change
-+              conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
-+              conf->tx_max_offset = 1;
-+      }
-+      if (conf->chip == BCM4324_CHIP_ID) {
-+              conf->txglom_bucket_size = 1684; // fixed value, don't change
-+              conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle
-+              conf->tx_max_offset = 0;
-+      }
-+#endif
-+#if defined(BCMSDIOH_TXGLOM_EXT)
-+      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID ||
-+                      conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID ||
-+                      conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
-+              conf->txglom_ext = TRUE;
-+              conf->use_rxchain = 0;
-+              conf->tx_in_rx = TRUE;
-+              conf->tx_max_offset = 1;
-+      } else {
-+              conf->txglom_ext = FALSE;
-+      }
-+      if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) {
-+              conf->txglom_bucket_size = 1680; // fixed value, don't change
-+              conf->txglomsize = 6;
-+      }
-+      if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID ||
-+                      conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) {
-+              conf->txglom_bucket_size = 1684; // fixed value, don't change
-+              conf->txglomsize = 16;
-+      }
-+#endif
-+      if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
-+              conf->txglomsize = SDPCM_MAXGLOM_SIZE;
-+      conf->deferred_tx_len = 0;
-+#endif
-+
-+      return 0;
-+}
-+
-+int
-+dhd_conf_reset(dhd_pub_t *dhd)
-+{
-+#ifdef BCMSDIO
-+      dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);
-+      dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
-+      dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
-+#endif
-+      memset(dhd->conf, 0, sizeof(dhd_conf_t));
-+      return 0;
-+}
-+
-+int
-+dhd_conf_attach(dhd_pub_t *dhd)
-+{
-+      dhd_conf_t *conf;
-+
-+      CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
-+
-+      if (dhd->conf != NULL) {
-+              printf("%s: config is attached before!\n", __FUNCTION__);
-+              return 0;
-+      }
-+      /* Allocate private bus interface state */
-+      if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {
-+              CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__));
-+              goto fail;
-+      }
-+      memset(conf, 0, sizeof(dhd_conf_t));
-+
-+      dhd->conf = conf;
-+
-+      return 0;
-+
-+fail:
-+      if (conf != NULL)
-+              MFREE(dhd->osh, conf, sizeof(dhd_conf_t));
-+      return BCME_NOMEM;
-+}
-+
-+void
-+dhd_conf_detach(dhd_pub_t *dhd)
-+{
-+      CONFIG_TRACE(("%s: Enter\n", __FUNCTION__));
-+
-+      if (dhd->conf) {
-+#ifdef BCMSDIO
-+              dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);
-+              dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);
-+              dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);
-+#endif
-+              MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));
-+      }
-+      dhd->conf = NULL;
-+}
index 750a2830fb555dd3c055aadc2110ae04685a87b5..4d02895c61d52c82d8e29da931b40106308014dc 100644 (file)
-\r
-#ifndef _dhd_config_\r
-#define _dhd_config_\r
-\r
-#include <bcmdevs.h>\r
-#include <dngl_stats.h>\r
-#include <dhd.h>\r
-#include <wlioctl.h>\r
-#include <proto/802.11.h>\r
-\r
-#define FW_PATH_AUTO_SELECT 1\r
-//#define CONFIG_PATH_AUTO_SELECT\r
-extern char firmware_path[MOD_PARAM_PATHLEN];\r
+
+#ifndef _dhd_config_
+#define _dhd_config_
+
+#include <bcmdevs.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <wlioctl.h>
+#include <proto/802.11.h>
+
+#define FW_PATH_AUTO_SELECT 1
+//#define CONFIG_PATH_AUTO_SELECT
+extern char firmware_path[MOD_PARAM_PATHLEN];
 extern uint dhd_rxbound;
-extern uint dhd_txbound;\r
-#ifdef BCMSDIO\r
-#define TXGLOM_RECV_OFFSET 8\r
-extern uint dhd_doflow;\r
-extern uint dhd_slpauto;\r
-\r
-#define BCM43362A0_CHIP_REV     0\r
-#define BCM43362A2_CHIP_REV     1\r
-#define BCM43430A0_CHIP_REV     0\r
-#define BCM43430A1_CHIP_REV     1\r
-#define BCM43430A2_CHIP_REV     2\r
-#define BCM43012B0_CHIP_REV     1\r
-#define BCM4330B2_CHIP_REV      4\r
-#define BCM4334B1_CHIP_REV      3\r
-#define BCM43341B0_CHIP_REV     2\r
-#define BCM43241B4_CHIP_REV     5\r
-#define BCM4335A0_CHIP_REV      2\r
-#define BCM4339A0_CHIP_REV      1\r
-#define BCM43455C0_CHIP_REV     6\r
-#define BCM43455C5_CHIP_REV     9\r
-#define BCM4354A1_CHIP_REV      1\r
-#define BCM4359B1_CHIP_REV      5\r
-#define BCM4359C0_CHIP_REV      9\r
-#endif\r
-#define BCM4356A2_CHIP_REV      2\r
-#define BCM4358A3_CHIP_REV      3\r
-\r
-/* mac range */\r
-typedef struct wl_mac_range {\r
-       uint32 oui;\r
-       uint32 nic_start;\r
-       uint32 nic_end;\r
-} wl_mac_range_t;\r
-\r
-/* mac list */\r
-typedef struct wl_mac_list {\r
-       int count;\r
-       wl_mac_range_t *mac;\r
-       char name[MOD_PARAM_PATHLEN];           /* path */\r
-} wl_mac_list_t;\r
-\r
-/* mac list head */\r
-typedef struct wl_mac_list_ctrl {\r
-       int count;\r
-       struct wl_mac_list *m_mac_list_head;\r
-} wl_mac_list_ctrl_t;\r
-\r
-/* chip_nv_path */\r
-typedef struct wl_chip_nv_path {\r
-       uint chip;\r
-       uint chiprev;\r
-       char name[MOD_PARAM_PATHLEN];           /* path */\r
-} wl_chip_nv_path_t;\r
-\r
-/* chip_nv_path list head */\r
-typedef struct wl_chip_nv_path_list_ctrl {\r
-       int count;\r
-       struct wl_chip_nv_path *m_chip_nv_path_head;\r
-} wl_chip_nv_path_list_ctrl_t;\r
-\r
-/* channel list */\r
-typedef struct wl_channel_list {\r
-       /* in - # of channels, out - # of entries */\r
-       uint32 count;\r
-       /* variable length channel list */\r
-       uint32 channel[WL_NUMCHANNELS];\r
-} wl_channel_list_t;\r
-\r
-typedef struct wmes_param {\r
-       int aifsn[AC_COUNT];\r
-       int ecwmin[AC_COUNT];\r
-       int ecwmax[AC_COUNT];\r
-       int txop[AC_COUNT];\r
-} wme_param_t;\r
-\r
-#ifdef PKT_FILTER_SUPPORT\r
-#define DHD_CONF_FILTER_MAX    8\r
-/* filter list */\r
-#define PKT_FILTER_LEN 300\r
-typedef struct conf_pkt_filter_add {\r
-       /* in - # of channels, out - # of entries */\r
-       uint32 count;\r
-       /* variable length filter list */\r
-       char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];\r
-} conf_pkt_filter_add_t;\r
-\r
-/* pkt_filter_del list */\r
-typedef struct conf_pkt_filter_del {\r
-       /* in - # of channels, out - # of entries */\r
-       uint32 count;\r
-       /* variable length filter list */\r
-       uint32 id[DHD_CONF_FILTER_MAX];\r
-} conf_pkt_filter_del_t;\r
-#endif\r
-\r
-#define CONFIG_COUNTRY_LIST_SIZE 100\r
-/* country list */\r
-typedef struct conf_country_list {\r
-       uint32 count;\r
-       wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE];\r
-} conf_country_list_t;\r
-\r
-typedef struct dhd_conf {\r
-       uint    chip;                   /* chip number */
-       uint    chiprev;                /* chip revision */\r
-       wl_mac_list_ctrl_t fw_by_mac;   /* Firmware auto selection by MAC */\r
-       wl_mac_list_ctrl_t nv_by_mac;   /* NVRAM auto selection by MAC */\r
-       wl_chip_nv_path_list_ctrl_t nv_by_chip; /* NVRAM auto selection by chip */\r
-       conf_country_list_t country_list; /* Country list */\r
-       int band;                       /* Band, b:2.4G only, otherwise for auto */\r
-       int mimo_bw_cap;                        /* Bandwidth, 0:HT20ALL, 1: HT40ALL, 2:HT20IN2G_HT40PIN5G */\r
-       int bw_cap_2g;                  /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */\r
-       int bw_cap_5g;                  /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */\r
-       wl_country_t cspec;             /* Country */\r
-       wl_channel_list_t channels;     /* Support channels */\r
-       uint roam_off;          /* Roaming, 0:enable, 1:disable */\r
-       uint roam_off_suspend;          /* Roaming in suspend, 0:enable, 1:disable */\r
-       int roam_trigger[2];            /* The RSSI threshold to trigger roaming */\r
-       int roam_scan_period[2];        /* Roaming scan period */\r
-       int roam_delta[2];                      /* Roaming candidate qualification delta */\r
-       int fullroamperiod;                     /* Full Roaming period */\r
-       uint keep_alive_period;         /* The perioid in ms to send keep alive packet */\r
-       int force_wme_ac;\r
-       wme_param_t wme_sta;    /* WME parameters */\r
-       wme_param_t wme_ap;     /* WME parameters */\r
-       int stbc;                       /* STBC for Tx/Rx */\r
-       int phy_oclscdenable;           /* phy_oclscdenable */\r
-#ifdef PKT_FILTER_SUPPORT\r
-       conf_pkt_filter_add_t pkt_filter_add;           /* Packet filter add */\r
-       conf_pkt_filter_del_t pkt_filter_del;           /* Packet filter add */\r
-       conf_pkt_filter_add_t magic_pkt_filter_add;             /* Magic Packet filter add */\r
-#endif\r
-       int srl;        /* short retry limit */\r
-       int lrl;        /* long retry limit */\r
-       uint bcn_timeout;       /* beacon timeout */\r
-       int spect;\r
-       int txbf;\r
-       int lpc;\r
-       int disable_proptx;\r
-#ifdef BCMSDIO\r
-       int bus_txglom; /* bus:txglom */\r
-       int use_rxchain;\r
-       bool bus_rxglom; /* bus:rxglom */\r
+extern uint dhd_txbound;
+#ifdef BCMSDIO
+#define TXGLOM_RECV_OFFSET 8
+extern uint dhd_doflow;
+extern uint dhd_slpauto;
+
+#define BCM43362A0_CHIP_REV     0
+#define BCM43362A2_CHIP_REV     1
+#define BCM43430A0_CHIP_REV     0
+#define BCM43430A1_CHIP_REV     1
+#define BCM43430A2_CHIP_REV     2
+#define BCM43012B0_CHIP_REV     1
+#define BCM4330B2_CHIP_REV      4
+#define BCM4334B1_CHIP_REV      3
+#define BCM43341B0_CHIP_REV     2
+#define BCM43241B4_CHIP_REV     5
+#define BCM4335A0_CHIP_REV      2
+#define BCM4339A0_CHIP_REV      1
+#define BCM43455C0_CHIP_REV     6
+#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
+
+typedef struct wl_mac_range {
+       uint32 oui;
+       uint32 nic_start;
+       uint32 nic_end;
+} wl_mac_range_t;
+
+typedef struct wl_mac_list {
+       int count;
+       wl_mac_range_t *mac;
+       char name[MOD_PARAM_PATHLEN];
+} wl_mac_list_t;
+
+typedef struct wl_mac_list_ctrl {
+       int count;
+       struct wl_mac_list *m_mac_list_head;
+} wl_mac_list_ctrl_t;
+
+typedef struct wl_chip_nv_path {
+       uint chip;
+       uint chiprev;
+       char name[MOD_PARAM_PATHLEN];
+} wl_chip_nv_path_t;
+
+typedef struct wl_chip_nv_path_list_ctrl {
+       int count;
+       struct wl_chip_nv_path *m_chip_nv_path_head;
+} wl_chip_nv_path_list_ctrl_t;
+
+typedef struct wl_channel_list {
+       uint32 count;
+       uint32 channel[WL_NUMCHANNELS];
+} wl_channel_list_t;
+
+typedef struct wmes_param {
+       int aifsn[AC_COUNT];
+       int ecwmin[AC_COUNT];
+       int ecwmax[AC_COUNT];
+       int txop[AC_COUNT];
+} wme_param_t;
+
+#ifdef PKT_FILTER_SUPPORT
+#define DHD_CONF_FILTER_MAX    8
+#define PKT_FILTER_LEN 300
+typedef struct conf_pkt_filter_add {
+       uint32 count;
+       char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];
+} conf_pkt_filter_add_t;
+
+typedef struct conf_pkt_filter_del {
+       uint32 count;
+       uint32 id[DHD_CONF_FILTER_MAX];
+} conf_pkt_filter_del_t;
+#endif
+
+#define CONFIG_COUNTRY_LIST_SIZE 100
+typedef struct conf_country_list {
+       uint32 count;
+       wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE];
+} conf_country_list_t;
+
+typedef struct dhd_conf {
+       uint chip;
+       uint chiprev;
+       wl_mac_list_ctrl_t fw_by_mac;
+       wl_mac_list_ctrl_t nv_by_mac;
+       wl_chip_nv_path_list_ctrl_t nv_by_chip;
+       conf_country_list_t country_list;
+       int band;
+       int mimo_bw_cap;
+       int bw_cap_2g;
+       int bw_cap_5g;
+       wl_country_t cspec;
+       wl_channel_list_t channels;
+       uint roam_off;
+       uint roam_off_suspend;
+       int roam_trigger[2];
+       int roam_scan_period[2];
+       int roam_delta[2];
+       int fullroamperiod;
+       uint keep_alive_period;
+       int force_wme_ac;
+       wme_param_t wme_sta;
+       wme_param_t wme_ap;
+       int stbc;
+       int phy_oclscdenable;
+#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;
+#endif
+       int srl;
+       int lrl;
+       uint bcn_timeout;
+       int spect;
+       int txbf;
+       int lpc;
+       int disable_proptx;
+#ifdef BCMSDIO
+       int bus_txglom;
+       int use_rxchain;
+       bool bus_rxglom;
        bool txglom_ext; /* Only for 43362/4330/43340/43341/43241 */
-       /* terence 20161011:\r
-           1) conf->tx_max_offset = 1 to fix credict issue in adaptivity testing\r
-           2) conf->tx_max_offset = 1 will cause to UDP Tx not work in rxglom supported,\r
-               but not happened in sw txglom\r
-       */\r
-       int tx_max_offset;\r
-       uint txglomsize;\r
-       int dhd_poll;\r
-       /* terence 20161011: conf->txctl_tmo_fix = 1 to fix for "sched: RT throttling activated, "\r
-            this issue happened in tx tput. and tx cmd at the same time in inband interrupt mode\r
-       */\r
-       bool txctl_tmo_fix;\r
-       bool tx_in_rx; // Skip tx before rx, in order to get more glomed in tx\r
-       bool txglom_mode;\r
-       uint deferred_tx_len;\r
-       bool swtxglom; /* SW TXGLOM */\r
+       /* terence 20161011:
+           1) conf->tx_max_offset = 1 to fix credict issue in adaptivity testing
+           2) conf->tx_max_offset = 1 will cause to UDP Tx not work in rxglom supported,
+               but not happened in sw txglom
+       */
+       int tx_max_offset;
+       uint txglomsize;
+       int dhd_poll;
+       bool txctl_tmo_fix;
+       bool tx_in_rx;
+       bool txglom_mode;
+       uint deferred_tx_len;
+       bool swtxglom; /* SW TXGLOM */
        /*txglom_bucket_size:
         * 43362/4330: 1680
         * 43340/43341/43241: 1684
-        */\r
-       int txglom_bucket_size;\r
-       int txinrx_thres;\r
-       int dhd_txminmax; // -1=DATABUFCNT(bus)\r
-       uint sd_f2_blocksize;\r
-       bool oob_enabled_later;\r
-#endif\r
-       int ampdu_ba_wsize;\r
-       int ampdu_hostreorder;\r
-       int dpc_cpucore;\r
-       int rxf_cpucore;\r
-       int frameburst;\r
-       bool deepsleep;\r
-       int pm;\r
-       int pm_in_suspend;\r
-       int pm2_sleep_ret;\r
-#ifdef DHDTCPACK_SUPPRESS\r
-       uint8 tcpack_sup_mode;\r
-#endif\r
-       int pktprio8021x;\r
-       int rsdb_mode;\r
-       int vhtmode;\r
-       int num_different_channels;\r
-       int xmit_in_suspend;\r
-#ifdef IDHCPC\r
-       int dhcpc_enable;\r
-#endif\r
-#ifdef IAPSTA_PREINIT\r
-       char iapsta_init[50];\r
-       char iapsta_config[300];\r
-       char iapsta_enable[50];\r
-#endif\r
-       int autocountry;\r
-       int tsq;\r
-} dhd_conf_t;\r
-\r
-#ifdef BCMSDIO\r
-int dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac);\r
-void dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path);\r
-void dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path);\r
-#if defined(HW_OOB) || defined(FORCE_WOWLAN)\r
-void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip);\r
-#endif\r
-void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable);\r
-#endif\r
-void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path);\r
-void dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path);\r
-void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path);\r
-void dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path);\r
-#ifdef CONFIG_PATH_AUTO_SELECT\r
-void dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path);\r
-#endif\r
-int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def, bool down);\r
-int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx);\r
-uint dhd_conf_get_band(dhd_pub_t *dhd);\r
-int dhd_conf_set_country(dhd_pub_t *dhd);\r
-int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);\r
-int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec);\r
-int dhd_conf_fix_country(dhd_pub_t *dhd);\r
-bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel);\r
-int dhd_conf_set_roam(dhd_pub_t *dhd);\r
-void dhd_conf_set_bw_cap(dhd_pub_t *dhd);\r
-void dhd_conf_set_wme(dhd_pub_t *dhd, int mode);\r
-void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);\r
-bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);\r
-void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);\r
-int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);\r
-int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);\r
-uint dhd_conf_get_chip(void *context);\r
-uint dhd_conf_get_chiprev(void *context);\r
-int dhd_conf_get_pm(dhd_pub_t *dhd);\r
-#ifdef PROP_TXSTATUS\r
-int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);\r
-#endif\r
-int dhd_conf_preinit(dhd_pub_t *dhd);\r
-int dhd_conf_reset(dhd_pub_t *dhd);\r
-int dhd_conf_attach(dhd_pub_t *dhd);\r
-void dhd_conf_detach(dhd_pub_t *dhd);\r
-void *dhd_get_pub(struct net_device *dev);\r
-void *dhd_get_conf(struct net_device *dev);\r
-#endif /* _dhd_config_ */\r
+        */
+       int txglom_bucket_size;
+       int txinrx_thres;
+       int dhd_txminmax; // -1=DATABUFCNT(bus)
+       uint sd_f2_blocksize;
+       bool oob_enabled_later;
+#endif
+       int ampdu_ba_wsize;
+       int ampdu_hostreorder;
+       int dpc_cpucore;
+       int rxf_cpucore;
+       int frameburst;
+       bool deepsleep;
+       int pm;
+       int pm_in_suspend;
+       int pm2_sleep_ret;
+#ifdef DHDTCPACK_SUPPRESS
+       uint8 tcpack_sup_mode;
+#endif
+       int pktprio8021x;
+       int rsdb_mode;
+       int vhtmode;
+       int num_different_channels;
+       int xmit_in_suspend;
+       int ap_in_suspend;
+#ifdef SUSPEND_EVENT
+       bool suspend_eventmask_enable;
+       char suspend_eventmask[WL_EVENTING_MASK_LEN];
+       char resume_eventmask[WL_EVENTING_MASK_LEN];
+#endif
+#ifdef IDHCP
+       int dhcpc_enable;
+       int dhcpd_enable;
+       struct ipv4_addr dhcpd_ip_addr;
+       struct ipv4_addr dhcpd_ip_mask;
+       struct ipv4_addr dhcpd_ip_start;
+       struct ipv4_addr dhcpd_ip_end;
+#endif
+#ifdef IAPSTA_PREINIT
+       char iapsta_init[50];
+       char iapsta_config[300];
+       char iapsta_enable[50];
+#endif
+       int autocountry;
+       int tsq;
+} dhd_conf_t;
+
+#ifdef BCMSDIO
+int dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac);
+void dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path);
+void dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path);
+#if defined(HW_OOB) || defined(FORCE_WOWLAN)
+void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip);
+#endif
+void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable);
+#endif
+void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path);
+void dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path);
+void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path);
+void dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path);
+#ifdef CONFIG_PATH_AUTO_SELECT
+void dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path);
+#endif
+int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def, bool down);
+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_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_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_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);
+int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);
+int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);
+uint dhd_conf_get_chip(void *context);
+uint dhd_conf_get_chiprev(void *context);
+int dhd_conf_get_pm(dhd_pub_t *dhd);
+#ifdef PROP_TXSTATUS
+int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
+#endif
+int dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd);
+int dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend);
+int dhd_conf_preinit(dhd_pub_t *dhd);
+int dhd_conf_reset(dhd_pub_t *dhd);
+int dhd_conf_attach(dhd_pub_t *dhd);
+void dhd_conf_detach(dhd_pub_t *dhd);
+void *dhd_get_pub(struct net_device *dev);
+void *dhd_get_conf(struct net_device *dev);
+#endif /* _dhd_config_ */
index db3b45df23bfc8531a58da0f84139b970783890e..8b9c66510a2a83696ea822beb20fe439ed528fe5 100644 (file)
@@ -175,6 +175,22 @@ static int dhd_wlan_get_mac_addr(unsigned char *buf)
                bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
        }
 #endif /* EXAMPLE_GET_MAC */
+#ifdef EXAMPLE_GET_MAC_VER2
+       /* EXAMPLE code */
+       {
+                       char mac[6] = {0x00,0x11,0x22,0x33,0x44,0xFF};
+                       char macpad[56]= {
+                       0x00,0xaa,0x9c,0x84,0xc7,0xbc,0x9b,0xf6,
+                       0x02,0x33,0xa9,0x4d,0x5c,0xb4,0x0a,0x5d,
+                       0xa8,0xef,0xb0,0xcf,0x8e,0xbf,0x24,0x8a,
+                       0x87,0x0f,0x6f,0x0d,0xeb,0x83,0x6a,0x70,
+                       0x4a,0xeb,0xf6,0xe6,0x3c,0xe7,0x5f,0xfc,
+                       0x0e,0xa7,0xb3,0x0f,0x00,0xe4,0x4a,0xaf,
+                       0x87,0x08,0x16,0x6d,0x3a,0xe3,0xc7,0x80};
+                       bcopy(mac, buf, sizeof(mac));
+                       bcopy(macpad, buf+6, sizeof(macpad));
+       }
+#endif /* EXAMPLE_GET_MAC_VER2 */
        bcopy((char *)wifi_get_mac(), buf, sizeof(struct ether_addr));
        if (buf[0] == 0xff) {
                printf("custom wifi mac is not set\n");
index 71bef8fe34c301c51332a6c53f7e5815a999af7c..c04d1850f8ced6400ab8873282e589262838e360 100644 (file)
@@ -821,11 +821,11 @@ module_param(dhd_watchdog_prio, int, 0);
 
 /* DPC thread priority */
 int dhd_dpc_prio = CUSTOM_DPC_PRIO_SETTING;
-module_param(dhd_dpc_prio, int, 0644);
+module_param(dhd_dpc_prio, int, 0);
 
 /* RX frame thread priority */
 int dhd_rxf_prio = CUSTOM_RXF_PRIO_SETTING;
-module_param(dhd_rxf_prio, int, 0644);
+module_param(dhd_rxf_prio, int, 0);
 
 int passive_channel_skip = 0;
 module_param(passive_channel_skip, int, (S_IRUSR|S_IWUSR));
@@ -2720,7 +2720,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                        }
 #endif /* DYNAMIC_SWOOB_DURATION */
 #endif /* DHD_USE_EARLYSUSPEND */
+                       dhd_conf_set_ap_in_suspend(dhd, value);
                } else {
+                       dhd_conf_set_ap_in_suspend(dhd, value);
 #ifdef PKT_FILTER_SUPPORT
                        dhd->early_suspended = 0;
 #endif
@@ -2830,7 +2832,7 @@ static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force)
        /* Set flag when early suspend was called */
        dhdp->in_suspend = val;
        if ((force || !dhdp->suspend_disable_flag) &&
-               dhd_support_sta_mode(dhdp))
+               (dhd_support_sta_mode(dhdp) || dhd_conf_get_ap_mode_in_suspend(dhdp)))
        {
                ret = dhd_set_suspend(val, dhdp);
        }
@@ -4949,17 +4951,17 @@ dhd_dpc_thread(void *data)
 
 #ifdef CUSTOM_DPC_CPUCORE
        set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_DPC_CPUCORE));
-#else
-       if (dhd->pub.conf->dpc_cpucore >= 0) {
-               printf("%s: set dpc_cpucore %d from config.txt\n", __FUNCTION__, dhd->pub.conf->dpc_cpucore);
-               set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->dpc_cpucore));
-       }
 #endif
 #ifdef CUSTOM_SET_CPUCORE
        dhd->pub.current_dpc = current;
 #endif /* CUSTOM_SET_CPUCORE */
        /* Run until signal received */
        while (1) {
+               if (dhd->pub.conf->dpc_cpucore >= 0) {
+                       printf("%s: set dpc_cpucore %d\n", __FUNCTION__, dhd->pub.conf->dpc_cpucore);
+                       set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->dpc_cpucore));
+                       dhd->pub.conf->dpc_cpucore = -1;
+               }
                if (!binary_sema_down(tsk)) {
 #ifdef ENABLE_ADAPTIVE_SCHED
                        dhd_sched_policy(dhd_dpc_prio);
@@ -5030,11 +5032,6 @@ dhd_rxf_thread(void *data)
 #ifdef CUSTOM_RXF_CPUCORE
        /* change rxf thread to other cpu core */
        set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_RXF_CPUCORE));
-#else
-       if (dhd->pub.conf->rxf_cpucore >= 0) {
-               printf("%s: set rxf_cpucore %d from config.txt\n", __FUNCTION__, dhd->pub.conf->rxf_cpucore);
-               set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->rxf_cpucore));
-       }
 #endif
 
        /*  signal: thread has started */
@@ -5044,6 +5041,11 @@ dhd_rxf_thread(void *data)
 #endif /* CUSTOM_SET_CPUCORE */
        /* Run until signal received */
        while (1) {
+               if (dhd->pub.conf->rxf_cpucore >= 0) {
+                       printf("%s: set rxf_cpucore %d\n", __FUNCTION__, dhd->pub.conf->rxf_cpucore);
+                       set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->rxf_cpucore));
+                       dhd->pub.conf->rxf_cpucore = -1;
+               }
                if (down_interruptible(&tsk->sema) == 0) {
                        void *skb;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
@@ -5758,13 +5760,11 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
        if (is_compat_task())
 #endif
        {
-
                compat_wl_ioctl_t compat_ioc;
                if (copy_from_user(&compat_ioc, ifr->ifr_data, sizeof(compat_wl_ioctl_t))) {
                        ret = BCME_BADADDR;
                        goto done;
                }
-
                ioc.cmd = compat_ioc.cmd;
                ioc.buf = (uint64 *)compat_ioc.buf;
                ioc.len = compat_ioc.len;
@@ -7296,7 +7296,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        }
 #ifdef WL_ESCAN
        wl_escan_attach(net, (void *)&dhd->pub);
-#endif
+#endif /* WL_ESCAN */
 #endif /* defined(WL_WIRELESS_EXT) */
 
 #ifdef SHOW_LOGTRACE
@@ -8260,6 +8260,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* (defined(AP) || defined(WLP2P)) && !defined(SOFTAP_AND_GC) */
 #ifdef GET_CUSTOM_MAC_ENABLE
        struct ether_addr ea_addr;
+       char hw_ether[62];
 #endif /* GET_CUSTOM_MAC_ENABLE */
 
 #ifdef DISABLE_11N
@@ -8330,15 +8331,33 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                DHD_INFO(("%s : Set IOCTL response time.\n", __FUNCTION__));
        }
 #ifdef GET_CUSTOM_MAC_ENABLE
-       ret = wifi_platform_get_mac_addr(dhd->info->adapter, ea_addr.octet);
+       ret = wifi_platform_get_mac_addr(dhd->info->adapter, hw_ether);
        if (!ret) {
                memset(buf, 0, sizeof(buf));
+               bcopy(hw_ether, ea_addr.octet, sizeof(struct ether_addr));
                bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf));
                ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
                if (ret < 0) {
-                       DHD_ERROR(("%s: can't set MAC address MAC="MACDBG", error=%d\n",
-                               __FUNCTION__, MAC2STRDBG(ea_addr.octet), ret));
+                       memset(buf, 0, sizeof(buf));
+                       bcm_mkiovar("hw_ether", hw_ether, sizeof(hw_ether), buf, sizeof(buf));
+                       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+                       if (ret) {
+                               int i;
+                               DHD_ERROR(("%s: can't set MAC address MAC="MACDBG", error=%d\n",
+                                       __FUNCTION__, MAC2STRDBG(hw_ether), ret));
+                               for (i=0; i<sizeof(hw_ether)-ETHER_ADDR_LEN; i++) {
+                                       printf("0x%02x,", hw_ether[i+ETHER_ADDR_LEN]);
+                                       if ((i+1)%8 == 0)
+                                               printf("\n");
+                               }
+                               ret = BCME_NOTUP;
+                               goto done;
+                       }
                }
+       } else {
+               DHD_ERROR(("%s: can't get custom MAC address, ret=%d\n", __FUNCTION__, ret));
+               ret = BCME_NOTUP;
+               goto done;
        }
 #endif /* GET_CUSTOM_MAC_ENABLE */
        /* Get the default device MAC address directly from firmware */
@@ -8625,7 +8644,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                }
        }
 #endif /* DHD_ENABLE_LPC */
-       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "lpc", dhd->conf->lpc, 0, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "lpc", dhd->conf->lpc, 0, TRUE);
 
        /* Set PowerSave mode */
        if (dhd->conf->pm >= 0)
@@ -8670,7 +8689,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
 #endif /* defined(AP) && !defined(WLP2P) */
        /*  0:HT20 in ALL, 1:HT40 in ALL, 2: HT20 in 2G HT40 in 5G */
-       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mimo_bw_cap", dhd->conf->mimo_bw_cap, 1, TRUE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mimo_bw_cap", dhd->conf->mimo_bw_cap, 0, TRUE);
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "force_wme_ac", dhd->conf->force_wme_ac, 1, FALSE);
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "stbc_tx", dhd->conf->stbc, 0, FALSE);
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "stbc_rx", dhd->conf->stbc, 0, FALSE);
@@ -8679,8 +8698,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_conf_set_intiovar(dhd, WLC_SET_SPECT_MANAGMENT, "WLC_SET_SPECT_MANAGMENT", dhd->conf->spect, 0, FALSE);
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "rsdb_mode", dhd->conf->rsdb_mode, -1, TRUE);
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "vhtmode", dhd->conf->vhtmode, 0, TRUE);
-#ifdef IDHCPC
+#ifdef IDHCP
        dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "dhcpc_enable", dhd->conf->dhcpc_enable, 0, FALSE);
+       if (dhd->conf->dhcpd_enable >= 0) {
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_addr", (char *)&dhd->conf->dhcpd_ip_addr, sizeof(dhd->conf->dhcpd_ip_addr), FALSE);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_mask", (char *)&dhd->conf->dhcpd_ip_mask, sizeof(dhd->conf->dhcpd_ip_mask), FALSE);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_start", (char *)&dhd->conf->dhcpd_ip_start, sizeof(dhd->conf->dhcpd_ip_start), FALSE);
+               dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_end", (char *)&dhd->conf->dhcpd_ip_end, sizeof(dhd->conf->dhcpd_ip_end), FALSE);
+               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "dhcpd_enable", dhd->conf->dhcpd_enable, 0, FALSE);
+       }
 #endif
        dhd_conf_set_bw_cap(dhd);
 
@@ -8886,7 +8912,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* WLTDLS */
 #ifdef WL_ESCAN
        setbit(eventmask, WLC_E_ESCAN_RESULT);
-#endif
+#endif /* WL_ESCAN */
 #ifdef WL_CFG80211
        setbit(eventmask, WLC_E_ESCAN_RESULT);
        setbit(eventmask, WLC_E_AP_STARTED);
@@ -8919,6 +8945,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
 #endif /* defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING) */
 
+#ifdef SUSPEND_EVENT
+       bcopy(eventmask, dhd->conf->resume_eventmask, WL_EVENTING_MASK_LEN);
+#endif
        /* Write updated Event mask */
        bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
        if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
@@ -9803,7 +9832,7 @@ void dhd_detach(dhd_pub_t *dhdp)
        }
 #ifdef WL_ESCAN
        wl_escan_detach();
-#endif
+#endif /* WL_ESCAN */
 #endif /* defined(WL_WIRELESS_EXT) */
 
        /* delete all interfaces, start with virtual  */
index a5059f9bd21f89d21d50508ab7048efc848f2d5b..b9b3512bc536b0bf45f4674a87208f3f768ec649 100644 (file)
@@ -936,7 +936,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);
index 36cca5b32551a36fe250d2c6a973f20c89dc32f2..42cef002925032c0289d131c4c1eca38cc656224 100644 (file)
@@ -255,6 +255,7 @@ static int dhd_init_wlan_mem(void)
                pr_err("Failed to alloc wlan_static_if_flow_lkup\n");\r
                goto err_mem_alloc;\r
        }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_IF_FLOW_LKUP, DHD_PREALLOC_IF_FLOW_LKUP_SIZE);\r
 #endif /* CONFIG_BCMDHD_PCIE */\r
 \r
        return 0;\r
index 81cf51fcc4ee8c289eb9649ce86d00567e5ef7ab..b790c8d15fdeb1d025e670a53147bf7047d17c9b 100644 (file)
@@ -2812,7 +2812,11 @@ static void
 _dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len)
 {
        if (info_len) {
-               if (info_buf) {
+               /* Check copy length to avoid buffer overrun. In case of length exceeding
+               *  WLHOST_REORDERDATA_TOTLEN, return failure instead sending incomplete result
+               *  of length WLHOST_REORDERDATA_TOTLEN
+               */
+               if ((info_buf) && (len <= WLHOST_REORDERDATA_TOTLEN)) {
                        bcopy(val, info_buf, len);
                        *info_len = len;
                } else {
index 931576e9eb021eaa96127365293a41e93cfb07b6..dfa3aff501c05e531ce9613ef54952f9280b7083 100644 (file)
@@ -46,6 +46,6 @@
 #define EPI_VERSION_DEV                1.363.59
 
 /* Driver Version String, ASCII, 32 chars max */
-#define        EPI_VERSION_STR         "1.363.59.144.9 (r)"
+#define        EPI_VERSION_STR         "1.363.59.144.10 (r)"
 
 #endif /* _epivers_h_ */
index 278fecf6fba048b517406ddabc6447a7f7549280..d560feca11e8094b00631490721cfa3ae231b769 100644 (file)
@@ -448,8 +448,6 @@ extern int osl_error(int bcmerror);
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) && defined(TSQ_MULTIPLIER)
 #define PKTORPHAN(skb, tsq)          osl_pkt_orphan_partial(skb, tsq)
 extern void osl_pkt_orphan_partial(struct sk_buff *skb, int tsq);
-#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
-#define PKTORPHAN(skb, tsq)          skb_orphan(skb, tsq)
 #else
 #define PKTORPHAN(skb, tsq)          ({BCM_REFERENCE(skb); 0;})
 #endif /* LINUX VERSION >= 3.6 */
index 001a261acdc56112af12e45fc7124d670d071987..a02faee86e2a97b2c4850cdfa174dd40482044b1 100644 (file)
@@ -7998,6 +7998,15 @@ typedef enum {
 } ulb_bw_type_t;
 #endif /* WL11ULB */
 
+#ifdef MFP
+/* values for IOV_MFP arg */
+enum {
+    WL_MFP_NONE = 0,
+    WL_MFP_CAPABLE,
+    WL_MFP_REQUIRED
+};
+#endif /* MFP */
+
 #if defined(WLRCC)
 #define MAX_ROAM_CHANNEL      20
 
index d8dac6c48420cef02b11efe38855dc946a827281..2b5ccbf2b44b04e856f9f36e87a19ef8d6a3e448 100644 (file)
@@ -33,6 +33,8 @@
 #include <bcmendian.h>
 #include <linuxver.h>
 #include <bcmdefs.h>
+#include <dngl_stats.h>
+#include <dhd.h>
 
 
 #if !defined(STBLINUX)
@@ -465,7 +467,7 @@ int osl_static_mem_init(osl_t *osh, void *adapter)
 #ifdef CONFIG_DHD_USE_STATIC_BUF
                if (!bcm_static_buf && adapter) {
                        if (!(bcm_static_buf = (bcm_static_buf_t *)wifi_platform_prealloc(adapter,
-                               3, STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) {
+                               DHD_PREALLOC_OSL_BUF, STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) {
                                printk("can not alloc static buf!\n");
                                bcm_static_skb = NULL;
                                ASSERT(osh->magic == OS_HANDLE_MAGIC);
@@ -484,7 +486,7 @@ int osl_static_mem_init(osl_t *osh, void *adapter)
                        int i;
                        void *skb_buff_ptr = 0;
                        bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048);
-                       skb_buff_ptr = wifi_platform_prealloc(adapter, 4, 0);
+                       skb_buff_ptr = wifi_platform_prealloc(adapter, DHD_PREALLOC_SKB_BUF, 0);
                        if (!skb_buff_ptr) {
                                printk("cannot alloc static buf!\n");
                                bcm_static_buf = NULL;
index 1961e6a7795cfcc751c518879168de588c5738b0..810f8f8c6d6f09bdf692f9de7aeb26b53446a9b9 100644 (file)
@@ -1653,6 +1653,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
        u8 *reqbuf = NULL;
        uint32 band = WLC_BAND_2G;
        uint32 buf_size;
+       char *pos = command;
 
        if (cmd_str) {
                ANDROID_INFO(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str)));
@@ -1734,7 +1735,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
                goto done2;
        }
 
-       buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE;
+       buf_size = CHANSPEC_BUF_SIZE;
        ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf,
                buf_size, true);
        if (ret < 0) {
@@ -1764,6 +1765,18 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
                        chosen = dtoh32(chosen);
                }
 
+               if ((ret == 0) && (dtoh32(chosen) != 0)) {
+                       uint chip;
+                       chip = dhd_conf_get_chip(dhd_get_pub(dev));
+                       if (chip != BCM43362_CHIP_ID && chip != BCM4330_CHIP_ID) {
+                               u32 chanspec = 0;
+                               chanspec = wl_chspec_driver_to_host(chosen);
+                               ANDROID_INFO(("selected chanspec = 0x%x\n", chanspec));
+                               chosen = wf_chspec_ctlchan(chanspec);
+                               ANDROID_INFO(("selected chosen = 0x%x\n", chosen));
+                       }
+               }
+
                if (chosen) {
                        int chosen_band;
                        int apcs_band;
@@ -1778,9 +1791,12 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
 #endif /* D11AC_IOTYPES */
                        apcs_band = (band == WLC_BAND_AUTO) ? WLC_BAND_2G : band;
                        chosen_band = (channel <= CH_MAX_2G_CHANNEL) ? WLC_BAND_2G : WLC_BAND_5G;
-                       if (apcs_band == chosen_band) {
+                       if (band == WLC_BAND_AUTO) {
                                ANDROID_ERROR(("selected channel = %d\n", channel));
                                break;
+                       } else if (apcs_band == chosen_band) {
+                               printf("%s: selected channel = %d\n", __FUNCTION__, channel);
+                               break;
                        }
                }
                ANDROID_INFO(("%d tried, ret = %d, chosen = 0x%x\n",
@@ -1810,7 +1826,11 @@ done2:
        }
 
        if (channel) {
-               snprintf(command, 4, "%d", channel);
+               if (channel < 15)
+                       pos += snprintf(pos, total_len, "2g=");
+               else
+                       pos += snprintf(pos, total_len, "5g=");
+               pos += snprintf(pos, total_len, "%d", channel);
                ANDROID_INFO(("command result is %s \n", command));
                return strlen(command);
        } else {
index cf40743f009672acc1eeb19d321e7898c4bf13a7..3fd2bfae285708a8f5c94cc494e90e7bcd6d418c 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 IDHCPC\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,1875 @@ 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;
+
+       if (apsta_params->init) {
+               ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));
+               return -1;
+       }
+
+       dhd = dhd_get_pub(dev);
+       memset(apsta_params, 0, sizeof(struct wl_apsta_params));
+
+       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+
+       pick_tmp = command;
+       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init
+       param = bcmstrtok(&pick_tmp, " ", 0);
+       while (param != NULL) {
+               if (!strcmp(param, "mode")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch) {
+                               if (!strcmp(pch, "sta")) {
+                                       apsta_params->apstamode = ISTAONLY_MODE;
+                               } else if (!strcmp(pch, "ap")) {
+                                       apsta_params->apstamode = IAPONLY_MODE;
+                               } else if (!strcmp(pch, "apsta")) {
+                                       apsta_params->apstamode = IAPSTA_MODE;
+                               } else if (!strcmp(pch, "dualap")) {
+                                       apsta_params->apstamode = IDUALAP_MODE;
+                               } else if (!strcmp(pch, "gosta")) {
+                                       if (!FW_SUPPORTED(dhd, p2p)) {
+                                               return -1;
+                                       }
+                                       apsta_params->apstamode = IGOSTA_MODE;
+                               } else if (!strcmp(pch, "gcsta")) {
+                                       if (!FW_SUPPORTED(dhd, p2p)) {
+                                               return -1;
+                                       }
+                                       apsta_params->apstamode = IGCSTA_MODE;
+                               } else {
+                                       ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
+                                       return -1;
+                               }
+                       }
+               } else if (!strcmp(param, "vifname")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch)
+                               strcpy(apsta_params->vif.ifname, pch);
+                       else {
+                               ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__));
+                               return -1;
+                       }
+               }
+               param = bcmstrtok(&pick_tmp, " ", 0);
+       }
+
+       if (apsta_params->apstamode == 0) {
+               ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__));
+               return -1;
+       }
+
+       apsta_params->pif.dev = dev;
+       apsta_params->pif.bssidx = 0;
+       strcpy(apsta_params->pif.ifname, dev->name);
+       strcpy(apsta_params->pif.ssid, "tttp");
+       apsta_params->pif.maxassoc = -1;
+       apsta_params->pif.channel = 1;
+
+       if (!strlen(apsta_params->vif.ifname))
+               strcpy(apsta_params->vif.ifname, "wlan1");
+       strcpy(apsta_params->vif.ssid, "tttv");
+       apsta_params->vif.maxassoc = -1;
+       apsta_params->vif.channel = 1;
+
+       if (apsta_params->apstamode == ISTAONLY_MODE) {
+               apsta_params->pif.ifmode = ISTA_MODE;
+               apsta_params->pif.ifstate = IF_STATE_INIT;
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+               wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls
+               // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off
+               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+       } else if (apsta_params->apstamode == IAPONLY_MODE) {
+               apsta_params->pif.ifmode = IAP_MODE;
+               apsta_params->pif.ifstate = IF_STATE_INIT;
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
 #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;
+               wl_ext_iovar_setint(dev, "mpc", 0);
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+               wl_ext_iovar_setint(dev, "apsta", 1);
+               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+               if (FW_SUPPORTED(dhd, rsdb)) {
+                       bzero(&iface, sizeof(wl_interface_create_t));
+                       iface.ver = WL_INTERFACE_CREATE_VER;
+                       iface.flags = WL_INTERFACE_CREATE_AP;
+                       wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf,
+                               WLC_IOCTL_SMLEN, 1, NULL);
+               } else {
+                       wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf,
+                               WLC_IOCTL_SMLEN, 1, NULL);
+               }
+       }
+       else if (apsta_params->apstamode == IDUALAP_MODE) {
+               apsta_params->pif.ifmode = IAP_MODE;
+               apsta_params->pif.ifstate = IF_STATE_INIT;
+               apsta_params->vif.ifmode = IAP_MODE;
+               apsta_params->vif.ifstate = IF_STATE_INIT;
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
+               wl_ext_iovar_setint(dev, "apsta", 0);
+               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);
+               val = 1;
+               wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1);
+               /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */
 #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_iapsta_config(struct net_device *dev, char *command, int total_len)
+{
+       int i;
+       char *pch, *pick_tmp, *param;
+       struct wl_apsta_params *apsta_params = &g_apsta_params;
+       char ifname[IFNAMSIZ+1];
+       struct wl_if_info *cur_if = &apsta_params->pif;
+
+       if (!apsta_params->init) {
+               ANDROID_ERROR(("%s: please init first\n", __FUNCTION__));
+               return -1;
+       }
+
+       ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
+
+       pick_tmp = command;
+       param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config
+       param = bcmstrtok(&pick_tmp, " ", 0);
+
+       if (param != NULL) {
+               if (strcmp(param, "ifname")) {
+                       ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__));
+                       return -1;
+               }
+       }
+
+       while (param != NULL) {
+               if (!strcmp(param, "ifname")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch)
+                               strcpy(ifname, pch);
+                       else {
+                               ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__));
+                               return -1;
+                       }
+                       if (!strcmp(apsta_params->pif.dev->name, ifname)) {
+                               cur_if = &apsta_params->pif;
+                       } else if (!strcmp(apsta_params->vif.ifname, ifname)) {
+                               cur_if = &apsta_params->vif;
+                       } else {
+                               ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__,
+                                       ifname, apsta_params->apstamode));
+                               return -1;
+                       }
+               } else if (!strcmp(param, "ssid")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch)
+                               strcpy(cur_if->ssid, pch);
+               } else if (!strcmp(param, "bssid")) {
+                       pch = bcmstrtok(&pick_tmp, ": ", 0);
+                       for (i=0; i<6 && pch; i++) {
+                               ((u8 *)&cur_if->bssid)[i] = (int)simple_strtol(pch, NULL, 16);
+                               pch = bcmstrtok(&pick_tmp, ": ", 0);
+                       }
+               } else if (!strcmp(param, "bgnmode")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch) {
+                               if (!strcmp(pch, "b"))
+                                       cur_if->bgnmode = IEEE80211B;
+                               else if (!strcmp(pch, "g"))
+                                       cur_if->bgnmode = IEEE80211G;
+                               else if (!strcmp(pch, "bg"))
+                                       cur_if->bgnmode = IEEE80211BG;
+                               else if (!strcmp(pch, "bgn"))
+                                       cur_if->bgnmode = IEEE80211BGN;
+                               else if (!strcmp(pch, "bgnac"))
+                                       cur_if->bgnmode = IEEE80211BGNAC;
+                               else {
+                                       ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__));
+                                       return -1;
+                               }
+                       }
+               } else if (!strcmp(param, "hidden")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch) {
+                               if (!strcmp(pch, "n"))
+                                       cur_if->hidden = 0;
+                               else if (!strcmp(pch, "y"))
+                                       cur_if->hidden = 1;
+                               else {
+                                       ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__));
+                                       return -1;
+                               }
+                       }
+               } else if (!strcmp(param, "maxassoc")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch)
+                               cur_if->maxassoc = (int)simple_strtol(pch, NULL, 10);
+               } else if (!strcmp(param, "chan")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch)
+                               cur_if->channel = (int)simple_strtol(pch, NULL, 10);
+               } else if (!strcmp(param, "amode")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch) {
+                               if (!strcmp(pch, "open"))
+                                       cur_if->amode = AUTH_OPEN;
+                               else if (!strcmp(pch, "shared"))
+                                       cur_if->amode = AUTH_SHARED;
+                               else if (!strcmp(pch, "wpapsk"))
+                                       cur_if->amode = AUTH_WPAPSK;
+                               else if (!strcmp(pch, "wpa2psk"))
+                                       cur_if->amode = AUTH_WPA2PSK;
+                               else if (!strcmp(pch, "wpawpa2psk"))
+                                       cur_if->amode = AUTH_WPAWPA2PSK;
+                               else {
+                                       ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n",
+                                               __FUNCTION__));
+                                       return -1;
+                               }
+                       }
+               } else if (!strcmp(param, "emode")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch) {
+                               if (!strcmp(pch, "none"))
+                                       cur_if->emode = ENC_NONE;
+                               else if (!strcmp(pch, "wep"))
+                                       cur_if->emode = ENC_WEP;
+                               else if (!strcmp(pch, "tkip"))
+                                       cur_if->emode = ENC_TKIP;
+                               else if (!strcmp(pch, "aes"))
+                                       cur_if->emode = ENC_AES;
+                               else if (!strcmp(pch, "tkipaes"))
+                                       cur_if->emode = ENC_TKIPAES;
+                               else {
+                                       ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n",
+                                               __FUNCTION__));
+                                       return -1;
+                               }
+                       }
+               } else if (!strcmp(param, "key")) {
+                       pch = bcmstrtok(&pick_tmp, " ", 0);
+                       if (pch) {
+                               strcpy(cur_if->key, pch);
+                       }
+               }
+               param = bcmstrtok(&pick_tmp, " ", 0);
+       }
+
+       return 0;
+}
+
+static int
+wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
+{
+       char *pch, *pick_tmp, *param;
+       s8 iovar_buf[WLC_IOCTL_SMLEN];
+       wlc_ssid_t ssid = { 0, {0} };
+       scb_val_t scbval;
+       struct {
+               s32 tmp;
                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 IDHCPC\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 IDHCPC\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 12ae90396ddd7180516f3bd913b399c133b9903e..8dc9edf84733fac91a4a15ea643a51572d2a2a10 100644 (file)
@@ -616,6 +616,9 @@ static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, const u8 *ie_stream,
 static s32 wl_mrg_ie(struct bcm_cfg80211 *cfg, u8 *ie_stream, u16 ie_size);
 static s32 wl_cp_ie(struct bcm_cfg80211 *cfg, u8 *dst, u16 dst_size);
 static u32 wl_get_ielen(struct bcm_cfg80211 *cfg);
+#ifdef MFP
+static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa);
+#endif
 
 #ifdef WL11U
 bcm_tlv_t *
@@ -1487,12 +1490,12 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
 #ifdef WL_VIRTUAL_APSTA
        bcm_struct_cfgdev *new_cfgdev;
 #endif /* WL_VIRTUAL_APSTA */
+       dhd_pub_t *dhd;
 #ifdef PROP_TXSTATUS_VSDB
 #if defined(BCMSDIO)
        s32 up = 1;
        bool enabled;
 #endif 
-       dhd_pub_t *dhd;
 #endif /* PROP_TXSTATUS_VSDB */
 #if defined(SUPPORT_AP_POWERSAVE)
        dhd_pub_t *dhd;
@@ -1582,12 +1585,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
        if (cfg->p2p_supported && (wlif_type != -1)) {
                ASSERT(cfg->p2p); /* ensure expectation of p2p initialization */
 
-#ifdef PROP_TXSTATUS_VSDB
-#if defined(BCMSDIO)
                if (!dhd)
                        return ERR_PTR(-ENODEV);
-#endif 
-#endif /* PROP_TXSTATUS_VSDB */
                if (!cfg->p2p)
                        return ERR_PTR(-ENODEV);
 
@@ -2423,7 +2422,7 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req
                ptr = (char*)params + offset;
                for (i = 0; i < n_ssids; i++) {
                        memset(&ssid, 0, sizeof(wlc_ssid_t));
-                       ssid.SSID_len = request->ssids[i].ssid_len;
+                       ssid.SSID_len = MIN(request->ssids[i].ssid_len, DOT11_MAX_SSID_LEN);
                        memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len);
                        if (!ssid.SSID_len)
                                WL_SCAN(("%d: Broadcast scan\n", i));
@@ -3786,7 +3785,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        WL_TRACE(("In\n"));
        RETURN_EIO_IF_NOT_UP(cfg);
        WL_INFORM(("JOIN BSSID:" MACDBG "\n", MAC2STRDBG(params->bssid)));
-       if (!params->ssid || params->ssid_len <= 0) {
+       if (!params->ssid || params->ssid_len <= 0 ||
+                       params->ssid_len > DOT11_MAX_SSID_LEN) {
                WL_ERR(("Invalid parameter\n"));
                return -EINVAL;
        }
@@ -3955,6 +3955,43 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
        return err;
 }
 
+#ifdef MFP
+static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa)
+{
+       u16 suite_count;
+       wpa_suite_mcast_t *mcast;
+       wpa_suite_ucast_t *ucast;
+       u16 len;
+       wpa_suite_auth_key_mgmt_t *mgmt;
+
+       if (!wpa2ie)
+               return -1;
+
+       len = wpa2ie->len;
+       mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
+       if ((len -= WPA_SUITE_LEN) <= 0)
+               return BCME_BADLEN;
+       ucast = (wpa_suite_ucast_t *)&mcast[1];
+       suite_count = ltoh16_ua(&ucast->count);
+       if ((suite_count > NL80211_MAX_NR_CIPHER_SUITES) ||
+                       (len -= (WPA_IE_SUITE_COUNT_LEN +
+                                        (WPA_SUITE_LEN * suite_count))) <= 0)
+               return BCME_BADLEN;
+
+       mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count];
+       suite_count = ltoh16_ua(&mgmt->count);
+
+       if ((suite_count > NL80211_MAX_NR_CIPHER_SUITES) ||
+                       (len -= (WPA_IE_SUITE_COUNT_LEN +
+                                        (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) {
+               capa[0] = *(u8 *)&mgmt->list[suite_count];
+               capa[1] = *((u8 *)&mgmt->list[suite_count] + 1);
+       } else
+               return BCME_BADLEN;
+
+       return 0;
+}
+#endif /* MFP */
 
 static s32
 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
@@ -4131,6 +4168,11 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
        s32 val = 0;
        s32 err = 0;
        s32 bssidx;
+#ifdef MFP
+       s32 mfp = WL_MFP_NONE;
+       bcm_tlv_t *wpa2_ie;
+       u8 rsn_cap[2];
+#endif /* MFP */
 
        if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) {
                WL_ERR(("Find p2p index from wdev(%p) failed\n", dev->ieee80211_ptr));
@@ -4163,6 +4205,14 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
                        case WLAN_AKM_SUITE_8021X:
                                val = WPA2_AUTH_UNSPECIFIED;
                                break;
+#ifdef MFP
+                       case WL_AKM_SUITE_SHA256_1X:
+                               val = WPA2_AUTH_UNSPECIFIED;
+                               break;
+                       case WL_AKM_SUITE_SHA256_PSK:
+                               val = WPA2_AUTH_PSK;
+                               break;
+#endif /* MFP */
                        case WLAN_AKM_SUITE_PSK:
                                val = WPA2_AUTH_PSK;
                                break;
@@ -4173,6 +4223,33 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
                        }
                }
 
+#ifdef MFP
+               if (((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
+                               DOT11_MNG_RSN_ID)) != NULL) &&
+                               (wl_cfg80211_get_rsn_capa(wpa2_ie, rsn_cap) == 0)) {
+                       /* Check for MFP cap in the RSN capability field */
+                       if (rsn_cap[0] & RSN_CAP_MFPR) {
+                               mfp = WL_MFP_REQUIRED;
+                       } else if (rsn_cap[0] & RSN_CAP_MFPC) {
+                               mfp = WL_MFP_CAPABLE;
+                       }
+               }
+               err = wldev_iovar_setint(dev, "mfp", mfp);
+               if (unlikely(err)) {
+                       if (!mfp && (err == BCME_UNSUPPORTED)) {
+                               /* For non-mfp cases, if firmware doesn't support MFP
+                                * ignore the failure and proceed ahead.
+                                */
+                               WL_DBG(("fw doesn't support mfp \n"));
+                               err = 0;
+                       } else {
+                               WL_ERR(("mfp set failed ret:%d \n", err));
+                               return err;
+                       }
+               } else {
+                       WL_DBG(("mfp set to 0x%x \n", mfp));
+               }
+#endif /* MFP */
 
                WL_DBG(("setting wpa_auth to 0x%x\n", val));
 
@@ -5125,8 +5202,10 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
                return BCME_ERROR;
        }
 
+#ifndef MFP
        if ((key_idx >= DOT11_MAX_DEFAULT_KEYS) && (key_idx < DOT11_MAX_DEFAULT_KEYS+2))
                return -EINVAL;
+#endif
 
        RETURN_EIO_IF_NOT_UP(cfg);
        memset(&key, 0, sizeof(key));
@@ -5223,8 +5302,12 @@ static s32
 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
        struct net_device *dev, u8 key_idx)
 {
+#ifdef MFP
+       return 0;
+#else
        WL_INFORM(("Not supported\n"));
        return -EOPNOTSUPP;
+#endif /* MFP */
 }
 
 #if defined(RSSIAVG)
@@ -6551,6 +6634,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
 
        WL_DBG(("Enter \n"));
 
+       if (len > ACTION_FRAME_SIZE) {
+               WL_ERR(("bad length:%zu\n", len));
+               return BCME_BADLEN;
+       }
+
        dev = cfgdev_to_wlc_ndev(cfgdev, cfg);
 
        if (!dev) {
@@ -6951,6 +7039,10 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
        wpa_suite_auth_key_mgmt_t *mgmt;
        wpa_pmkid_list_t *pmkid;
        int cnt = 0;
+#ifdef MFP
+       int mfp = 0;
+       struct bcm_cfg80211 *cfg = g_bcm_cfg;
+#endif /* MFP */
 
        u16 suite_count;
        u8 rsn_cap[2];
@@ -7023,6 +7115,16 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
                case RSN_AKM_PSK:
                                wpa_auth |= WPA2_AUTH_PSK;
                                break;
+#ifdef MFP
+               case RSN_AKM_MFP_PSK:
+                       wpa_auth |= WPA2_AUTH_PSK;
+                       wsec |= MFP_SHA256;
+                       break;
+               case RSN_AKM_MFP_1X:
+                       wpa_auth |= WPA2_AUTH_UNSPECIFIED;
+                       wsec |= MFP_SHA256;
+                       break;
+#endif /* MFP */
                default:
                        WL_ERR(("No Key Mgmt Info\n"));
                }
@@ -7038,6 +7140,15 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
                        wme_bss_disable = 1;
                }
 
+#ifdef MFP
+               if (rsn_cap[0] & RSN_CAP_MFPR) {
+                       WL_DBG(("MFP Required \n"));
+                       mfp = WL_MFP_REQUIRED;
+               } else if (rsn_cap[0] & RSN_CAP_MFPC) {
+                       WL_DBG(("MFP Capable \n"));
+                       mfp = WL_MFP_CAPABLE;
+               }
+#endif /* MFP */
 
                /* set wme_bss_disable to sync RSN Capabilities */
                err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx);
@@ -7061,6 +7172,19 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
                /* so don't bother to send down this info to firmware */
        }
 
+#ifdef MFP
+       len -= WPA2_PMKID_COUNT_LEN;
+       if (len >= WPA_SUITE_LEN) {
+               err = wldev_iovar_setbuf_bsscfg(dev, "bip",
+                       (void *)((u8 *)&mgmt->list[suite_count] + RSN_CAP_LEN + WPA2_PMKID_COUNT_LEN),
+                       WPA_SUITE_LEN,
+                       cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync);
+               if (err < 0) {
+                       WL_ERR(("bip set error %d\n", err));
+                       return BCME_ERROR;
+               }
+       }
+#endif
 
        /* set auth */
        err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
@@ -7076,6 +7200,17 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
                return BCME_ERROR;
        }
 
+#ifdef MFP
+       if (mfp) {
+               /* This needs to go after wsec otherwise the wsec command will
+                * overwrite the values set by MFP
+                */
+               if ((err = wldev_iovar_setint_bsscfg(dev, "mfp", mfp, bssidx)) < 0) {
+                       WL_ERR(("MFP Setting failed. ret = %d \n", err));
+                       return err;
+               }
+       }
+#endif /* MFP */
 
        /* set upper-layer auth */
        err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
@@ -7592,17 +7727,17 @@ static s32 wl_cfg80211_bcn_set_params(
        }
 
        if ((info->ssid) && (info->ssid_len > 0) &&
-               (info->ssid_len <= 32)) {
+               (info->ssid_len <= DOT11_MAX_SSID_LEN)) {
                WL_DBG(("SSID (%s) len:%zd \n", info->ssid, info->ssid_len));
                if (dev_role == NL80211_IFTYPE_AP) {
                        /* Store the hostapd SSID */
-                       memset(cfg->hostapd_ssid.SSID, 0x00, 32);
+                       memset(cfg->hostapd_ssid.SSID, 0x00, DOT11_MAX_SSID_LEN);
                        memcpy(cfg->hostapd_ssid.SSID, info->ssid, info->ssid_len);
                        cfg->hostapd_ssid.SSID_len = info->ssid_len;
                } else {
                                /* P2P GO */
-                       memset(cfg->p2p->ssid.SSID, 0x00, 32);
-                       memcpy(cfg->p2p->ssid.SSID, info->ssid, info->ssid_len);
+                       memset(cfg->p2p->ssid.SSID, 0x00, DOT11_MAX_SSID_LEN);
+                       memcpy(cfg->p2p->ssid.SSID, info->ssid, cfg->p2p->ssid.SSID_len);
                        cfg->p2p->ssid.SSID_len = info->ssid_len;
                }
        }
@@ -7815,9 +7950,11 @@ wl_cfg80211_bcn_bringup_ap(
                memset(&join_params, 0, sizeof(join_params));
                /* join parameters starts with ssid */
                join_params_size = sizeof(join_params.ssid);
+               join_params.ssid.SSID_len = min(cfg->hostapd_ssid.SSID_len,
+                       (uint32)DOT11_MAX_SSID_LEN);
                memcpy(join_params.ssid.SSID, cfg->hostapd_ssid.SSID,
-                       cfg->hostapd_ssid.SSID_len);
-               join_params.ssid.SSID_len = htod32(cfg->hostapd_ssid.SSID_len);
+                       join_params.ssid.SSID_len);
+               join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
 
                /* create softap */
                if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
@@ -8507,33 +8644,44 @@ wl_cfg80211_stop_ap(
                 * Don't do a down or "WLC_SET_AP 0" since the shared
                 * interface may be still running
                 */
-               if (is_rsdb_supported) {
-                       if ((err = wl_cfg80211_add_del_bss(cfg, dev,
-                               bssidx, NL80211_IFTYPE_STATION, 0, NULL)) < 0) {
-                               if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32),
-                                       true)) < 0) {
+               if (bssidx == 0) {
+                       if (is_rsdb_supported) {
+                               if ((err = wl_cfg80211_add_del_bss(cfg, dev,
+                                       bssidx, NL80211_IFTYPE_STATION, 0, NULL)) < 0) {
+                                       if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32),
+                                               true)) < 0) {
+                                               WL_ERR(("setting AP mode failed %d \n", err));
+                                               err = -ENOTSUPP;
+                                               goto exit;
+                                       }
+                               }
+                       } else if (is_rsdb_supported == 0) {
+                               // terence 20160426: fix softap issue
+                               if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
                                        WL_ERR(("setting AP mode failed %d \n", err));
                                        err = -ENOTSUPP;
                                        goto exit;
                                }
+                               err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+                               if (err < 0) {
+                                       WL_ERR(("SET INFRA error %d\n", err));
+                                       err = -ENOTSUPP;
+                                       goto exit;
+                               }
+                               err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
+                               if (unlikely(err)) {
+                                       WL_ERR(("WLC_UP error (%d)\n", err));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                        }
-               } else if (is_rsdb_supported == 0) {
-                       // terence 20160426: fix softap issue
-                       if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
-                               WL_ERR(("setting AP mode failed %d \n", err));
-                               err = -ENOTSUPP;
-                               goto exit;
-                       }
-                       err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
-                       if (err < 0) {
-                               WL_ERR(("SET INFRA error %d\n", err));
-                               err = -ENOTSUPP;
-                               goto exit;
-                       }
-                       err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
-                       if (unlikely(err)) {
-                               WL_ERR(("WLC_UP error (%d)\n", err));
-                               err = -EINVAL;
+               } else if (cfg->cfgdev_bssidx && (bssidx == cfg->cfgdev_bssidx)) {
+
+                       WL_ERR(("Stop SoftAP on virtual Interface bssidx:%d \n", bssidx));
+
+                       if ((err = wl_cfg80211_add_del_bss(cfg, dev,
+                               bssidx, NL80211_IFTYPE_AP, 1, NULL)) < 0) {
+                               WL_ERR(("wl bss ap returned error:%d\n", err));
                                goto exit;
                        }
                }
@@ -8696,14 +8844,16 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                DOT11_MNG_SSID_ID)) != NULL) {
                if (dev_role == NL80211_IFTYPE_AP) {
                        /* Store the hostapd SSID */
-                       memset(&cfg->hostapd_ssid.SSID[0], 0x00, 32);
-                       memcpy(&cfg->hostapd_ssid.SSID[0], ssid_ie->data, ssid_ie->len);
-                       cfg->hostapd_ssid.SSID_len = ssid_ie->len;
+                       memset(&cfg->hostapd_ssid.SSID[0], 0x00, DOT11_MAX_SSID_LEN);
+                       cfg->hostapd_ssid.SSID_len = MIN(ssid_ie->len, DOT11_MAX_SSID_LEN);
+                       memcpy(&cfg->hostapd_ssid.SSID[0], ssid_ie->data,
+                               cfg->hostapd_ssid.SSID_len);
                } else {
-                               /* P2P GO */
-                       memset(&cfg->p2p->ssid.SSID[0], 0x00, 32);
-                       memcpy(cfg->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len);
-                       cfg->p2p->ssid.SSID_len = ssid_ie->len;
+                       /* P2P GO */
+                       memset(&cfg->p2p->ssid.SSID[0], 0x00, DOT11_MAX_SSID_LEN);
+                       cfg->p2p->ssid.SSID_len = MIN(ssid_ie->len, DOT11_MAX_SSID_LEN);
+                       memcpy(cfg->p2p->ssid.SSID, ssid_ie->data,
+                               cfg->p2p->ssid.SSID_len);
                }
        }
 
@@ -8877,8 +9027,10 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy,
                ssid = &request->match_sets[i].ssid;
                /* No need to include null ssid */
                if (ssid->ssid_len) {
-                       memcpy(ssids_local[ssid_cnt].SSID, ssid->ssid, ssid->ssid_len);
-                       ssids_local[ssid_cnt].SSID_len = ssid->ssid_len;
+                       ssids_local[ssid_cnt].SSID_len = min(ssid->ssid_len,
+                               (u8)DOT11_MAX_SSID_LEN);
+                       memcpy(ssids_local[ssid_cnt].SSID, ssid->ssid,
+                               ssids_local[ssid_cnt].SSID_len);
                        if (is_ssid_in_list(ssid, hidden_ssid_list, request->n_ssids)) {
                                ssids_local[ssid_cnt].hidden = TRUE;
                                WL_PNO((">>> PNO hidden SSID (%s) \n", ssid->ssid));
@@ -9289,24 +9441,17 @@ static const struct wiphy_wowlan_support brcm_wowlan_support = {
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */
 };
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */
-
-/* terence 20161107: remove to fix:
- * PC is at kfree+0x174/0x180
- * LR is at nl80211_set_wowlan+0x55c/0x614 [cfg80211]
- */
-#if 0
-static struct cfg80211_wowlan brcm_wowlan_config = {
-       .disconnect = true,
-       .gtk_rekey_failure = true,
-       .eap_identity_req = true,
-       .four_way_handshake = true,
-};
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */
 #endif /* CONFIG_PM */
 
 static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev, dhd_pub_t *context)
 {
        s32 err = 0;
+#ifdef CONFIG_PM
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
+       struct cfg80211_wowlan *brcm_wowlan_config = NULL;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */
+#endif /* CONFIG_PM */
+
 //#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
        dhd_pub_t *dhd = (dhd_pub_t *)context;
        BCM_REFERENCE(dhd);
@@ -9443,11 +9588,23 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
        /* If this is not provided cfg stack will get disconnect
         * during suspend.
         */
-       /* terence 20161107: remove to fix:
-        * PC is at kfree+0x174/0x180
-        * LR is at nl80211_set_wowlan+0x55c/0x614 [cfg80211]
-        */
-//     wdev->wiphy->wowlan_config = &brcm_wowlan_config;
+       brcm_wowlan_config = kmalloc(sizeof(struct cfg80211_wowlan), GFP_KERNEL);
+       if (brcm_wowlan_config) {
+               brcm_wowlan_config->disconnect = true;
+               brcm_wowlan_config->gtk_rekey_failure = true;
+               brcm_wowlan_config->eap_identity_req = true;
+               brcm_wowlan_config->four_way_handshake = true;
+               brcm_wowlan_config->patterns = NULL;
+               brcm_wowlan_config->n_patterns = 0;
+               brcm_wowlan_config->tcp = NULL;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+               brcm_wowlan_config->nd_config = NULL;
+#endif
+       } else {
+               WL_ERR(("Can not allocate memory for brcm_wowlan_config,"
+                       " So wiphy->wowlan_config is set to NULL\n"));
+       }
+       wdev->wiphy->wowlan_config = brcm_wowlan_config;
 #else
        wdev->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
        wdev->wiphy->wowlan.n_patterns = WL_WOWLAN_MAX_PATTERNS;
@@ -9507,7 +9664,6 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg)
                /* Reset wowlan & wowlan_config before Unregister to avoid  Kernel Panic */
                WL_DBG(("wl_free_wdev Clearing wowlan Config \n"));
                wdev->wiphy->wowlan = NULL;
-               wdev->wiphy->wowlan_config = NULL;
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */
 #endif /* CONFIG_PM && WL_CFG80211_P2P_DEV_IF */
                wiphy_unregister(wdev->wiphy);
@@ -10581,13 +10737,12 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                                if (!memcmp(ndev->name, WL_P2P_INTERFACE_PREFIX, strlen(WL_P2P_INTERFACE_PREFIX))) {
                                        // terence 20130703: Fix for wrong group_capab (timing issue)
                                        cfg->p2p_disconnected = 1;
+                               }
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
-                                       if (wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
-                                               CFG80211_DISCONNECTED(ndev, reason, NULL, 0,
-                                                               false, GFP_KERNEL);
-                                       }
-#endif
+                               if (wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
+                                       CFG80211_DISCONNECTED(ndev, reason, NULL, 0, false, GFP_KERNEL);
                                }
+#endif
                                memcpy(&cfg->disconnected_bssid, curbssid, ETHER_ADDR_LEN);
                                wl_clr_drv_status(cfg, CONNECTED, ndev);
                                if (! wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
@@ -12719,7 +12874,7 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                else
                        band = bcmcfg_to_wiphy(cfg)->bands[IEEE80211_BAND_5GHZ];
                if (!band) {
-                       WL_ERR(("No valid band\n"));
+                       WL_ERR(("No valid band, channel=%d\n", channel));
                        goto exit;
                }
                if (!dhd_conf_match_channel(cfg->pub, channel))
@@ -14734,8 +14889,8 @@ wl_update_prof(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                ssid = (const wlc_ssid_t *) data;
                memset(profile->ssid.SSID, 0,
                        sizeof(profile->ssid.SSID));
-               memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
-               profile->ssid.SSID_len = ssid->SSID_len;
+               profile->ssid.SSID_len = MIN(ssid->SSID_len, DOT11_MAX_SSID_LEN);
+               memcpy(profile->ssid.SSID, ssid->SSID, profile->ssid.SSID_len);
                break;
        case WL_PROF_BSSID:
                if (data)
@@ -14819,6 +14974,8 @@ static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, const u8 *ie_stream,
        bool roam)
 {
        u8 *ssidie;
+       int32 ssid_len = MIN(bi->SSID_len, DOT11_MAX_SSID_LEN);
+       int32 remaining_ie_buf_len, available_buffer_len;
        /* cfg80211_find_ie defined in kernel returning const u8 */
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
        4 && __GNUC_MINOR__ >= 6))
@@ -14830,26 +14987,41 @@ _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
        4 && __GNUC_MINOR__ >= 6))
 _Pragma("GCC diagnostic pop")
 #endif
-       if (!ssidie)
+       /* ERROR out if
+        * 1. No ssid IE is FOUND or
+        * 2. New ssid length is > what was allocated for existing ssid (as
+        * we do not want to overwrite the rest of the IEs) or
+        * 3. If in case of erroneous buffer input where ssid length doesnt match the space
+        * allocated to it.
+        */
+       if (!ssidie) {
+               return;
+       }
+       available_buffer_len = ((int)(*ie_size)) - (ssidie + 2 - ie_stream);
+       remaining_ie_buf_len = available_buffer_len - (int)ssidie[1];
+       if ((ssid_len > ssidie[1]) ||
+               (ssidie[1] > available_buffer_len)) {
                return;
-       if (ssidie[1] != bi->SSID_len) {
+       }
+
+       if (ssidie[1] != ssid_len) {
                if (ssidie[1]) {
                        WL_ERR(("%s: Wrong SSID len: %d != %d\n",
                                __FUNCTION__, ssidie[1], bi->SSID_len));
                }
                if (roam) {
                        WL_ERR(("Changing the SSID Info.\n"));
-                       memmove(ssidie + bi->SSID_len + 2,
+                       memmove(ssidie + ssid_len + 2,
                                (ssidie + 2) + ssidie[1],
-                               *ie_size - (ssidie + 2 + ssidie[1] - ie_stream));
-                       memcpy(ssidie + 2, bi->SSID, bi->SSID_len);
-                       *ie_size = *ie_size + bi->SSID_len - ssidie[1];
-                       ssidie[1] = bi->SSID_len;
+                               remaining_ie_buf_len);
+                       memcpy(ssidie + 2, bi->SSID, ssid_len);
+                       *ie_size = *ie_size + ssid_len - ssidie[1];
+                       ssidie[1] = ssid_len;
                }
                return;
        }
        if (*(ssidie + 2) == '\0')
-                memcpy(ssidie + 2, bi->SSID, bi->SSID_len);
+                memcpy(ssidie + 2, bi->SSID, ssid_len);
        return;
 }
 
@@ -15483,7 +15655,7 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen,
                                chanspec = wl_chspec_driver_to_host(chosen);
                                printf("selected chanspec = 0x%x\n", chanspec);
                                ctl_chan = wf_chspec_ctlchan(chanspec);
-                               printf("selected ctl_chan = 0x%x\n", ctl_chan);
+                               printf("selected ctl_chan = %d\n", ctl_chan);
                                *channel = (u16)(ctl_chan & 0x00FF);
                        } else
                                *channel = (u16)(chosen & 0x00FF);
@@ -15499,6 +15671,7 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen,
                *channel = 0;
                ret = BCME_ERROR;
        }
+       WL_INFORM(("selected channel = %d\n", *channel));
 
 done:
        return ret;
@@ -15579,17 +15752,19 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len)
                }
 
                if (CHANNEL_IS_2G(channel)) {
+#if 0
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && !defined(WL_COMPAT_WIRELESS)
                        channel = ieee80211_channel_to_frequency(channel);
 #else
                        channel = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
+#endif
 #endif
                } else {
                        WL_ERR(("invalid 2.4GHz channel, channel = %d\n", channel));
                        channel = 0;
                }
+               pos += snprintf(pos, total_len, "2g=%d ", channel);
        }
-       pos += snprintf(pos, total_len, "%04d ", channel);
 
        if (band_cur != WLC_BAND_2G) {
                // terence 20140120: fix for some chipsets only return 2.4GHz channel (4330b2/43341b0/4339a0)
@@ -15613,10 +15788,12 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len)
                }
 
                if (CHANNEL_IS_5G(channel)) {
+#if 0
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && !defined(WL_COMPAT_WIRELESS)
                        channel = ieee80211_channel_to_frequency(channel);
 #else
                        channel = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
+#endif
 #endif
                } else {
                        WL_ERR(("invalid 5GHz channel, channel = %d\n", channel));
@@ -15626,11 +15803,8 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len)
                ret = wldev_ioctl(dev, WLC_SET_BAND, &band_cur, sizeof(band_cur), true);
                if (ret < 0)
                        WL_ERR(("WLC_SET_BAND error %d\n", ret));
+               pos += snprintf(pos, total_len, "5g=%d ", channel);
        }
-       pos += snprintf(pos, total_len, "%04d ", channel);
-
-       /* Set overall best channel same as 5GHz best channel. */
-       pos += snprintf(pos, total_len, "%04d ", channel);
 
 done:
        if (NULL != buf) {
@@ -15643,7 +15817,7 @@ done:
                WL_ERR(("can't restore auto channel scan state, error = %d\n", ret));
        }
 
-       printf("%s: channel %s\n", __FUNCTION__, cmd);
+       printf("%s: %s\n", __FUNCTION__, cmd);
 
        return (pos - cmd);
 }
index 75dd87722f17ceec6c09d1a6e4d8450c8ae58b1e..acb78aac0b967002ec36a09bd304add9a2c88234 100644 (file)
@@ -753,13 +753,16 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
        gscan_swc_params_t *significant_params;
        int tmp, tmp1, tmp2, type, j = 0;
        const struct nlattr *outer, *inner, *iter;
-       uint8 flush = 0;
-       wl_pfn_significant_bssid_t *bssid;
+       bool flush = FALSE;
+       wl_pfn_significant_bssid_t *pbssid;
+       uint16 num_bssid = 0;
+       uint16 max_buf_size = sizeof(gscan_swc_params_t) +
+               sizeof(wl_pfn_significant_bssid_t) * (PFN_SWC_MAX_NUM_APS - 1);
 
-       significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL);
+       significant_params = kzalloc(max_buf_size, GFP_KERNEL);
        if (!significant_params) {
-               WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len));
-               return -ENOMEM;
+               WL_ERR(("Cannot Malloc mem size:%d\n", len));
+               return BCME_NOMEM;
        }
 
        nla_for_each_attr(iter, data, len, tmp2) {
@@ -767,7 +770,7 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
 
                switch (type) {
                        case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH:
-                       flush = nla_get_u8(iter);
+                       flush = (bool) nla_get_u8(iter);
                        break;
                        case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE:
                                significant_params->rssi_window = nla_get_u16(iter);
@@ -778,23 +781,41 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
                        case GSCAN_ATTRIBUTE_MIN_BREACHING:
                                significant_params->swc_threshold = nla_get_u16(iter);
                                break;
+                       case GSCAN_ATTRIBUTE_NUM_BSSID:
+                               num_bssid = nla_get_u16(iter);
+                               if (num_bssid > PFN_SWC_MAX_NUM_APS) {
+                                       WL_ERR(("ovar max SWC bssids:%d\n",
+                                               num_bssid));
+                                       err = BCME_BADARG;
+                                       goto exit;
+                               }
+                               break;
                        case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS:
-                               bssid = significant_params->bssid_elem_list;
+                               if (num_bssid == 0) {
+                                       WL_ERR(("num_bssid : 0\n"));
+                                       err = BCME_BADARG;
+                                       goto exit;
+                               }
+                               pbssid = significant_params->bssid_elem_list;
                                nla_for_each_nested(outer, iter, tmp) {
+                                       if (j >= num_bssid) {
+                                               j++;
+                                               break;
+                                       }
                                        nla_for_each_nested(inner, outer, tmp1) {
                                                        switch (nla_type(inner)) {
                                                                case GSCAN_ATTRIBUTE_BSSID:
-                                                                       memcpy(&(bssid[j].macaddr),
-                                                                              nla_data(inner),
-                                                                              ETHER_ADDR_LEN);
+                                                                       memcpy(&(pbssid[j].macaddr),
+                                                                            nla_data(inner),
+                                                                            ETHER_ADDR_LEN);
                                                                        break;
                                                                case GSCAN_ATTRIBUTE_RSSI_HIGH:
-                                                                       bssid[j].rssi_high_threshold
-                                                                        = (int8) nla_get_u8(inner);
+                                                                       pbssid[j].rssi_high_threshold =
+                                                                              (int8) nla_get_u8(inner);
                                                                        break;
                                                                case GSCAN_ATTRIBUTE_RSSI_LOW:
-                                                                       bssid[j].rssi_low_threshold
-                                                                        = (int8) nla_get_u8(inner);
+                                                                       pbssid[j].rssi_low_threshold =
+                                                                             (int8) nla_get_u8(inner);
                                                                        break;
                                                                default:
                                                                        WL_ERR(("ATTR unknown %d\n",
@@ -810,13 +831,19 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
                                break;
                }
        }
+       if (j != num_bssid) {
+               WL_ERR(("swc bssids count:%d not matched to num_bssid:%d\n",
+                       j, num_bssid));
+               err = BCME_BADARG;
+               goto exit;
+       }
        significant_params->nbssid = j;
 
        if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg),
                      DHD_PNO_SIGNIFICANT_SCAN_CFG_ID,
                      significant_params, flush) < 0) {
                WL_ERR(("Could not set GSCAN significant cfg\n"));
-               err = -EINVAL;
+               err = BCME_ERROR;
                goto exit;
        }
 exit: