net: wireless: rockchip_wlan: update bcmdhd driver 1.363.59.144
authorzzc <zzc@rock-chips.com>
Thu, 20 Apr 2017 11:48:45 +0000 (19:48 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Fri, 21 Apr 2017 00:40:04 +0000 (08:40 +0800)
Change-Id: Ia654d6374f9be950a30adf4b912bd7df941ef532
Signed-off-by: zzc <zzc@rock-chips.com>
42 files changed:
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/aiutils.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_linux.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/bcmsdh_sdmmc_linux.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/circularbuf.c [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_custom_gpio.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_gpio.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux_platdev.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie_linux.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pno.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_static_buf.c [changed mode: 0755->0644]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_wlfc.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/Makefile [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdbus.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmsdh_sdmmc.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmwifi_channels.h [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmwifi_rates.h [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/circularbuf.h [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h.in [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.sh [deleted file]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/linux_osl.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/sdiovar.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/linux_osl.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c [new file with mode: 0644]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c [changed mode: 0755->0644]
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfgp2p.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_escan.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wldev_common.c [changed mode: 0755->0644]

index 75725ee86f0877d5212cedfecd17171fbb03c35d..a6a4be363d684ed9be90d61ea7ca820564ad89fc 100644 (file)
@@ -6,15 +6,17 @@ MODULE_NAME = bcmdhd
 CONFIG_BCMDHD_SDIO := y
 #CONFIG_BCMDHD_PCIE := y
 CONFIG_BCMDHD_OOB := y
+CONFIG_BCMDHD_PROPTXSTATUS := y
 CONFIG_BCMDHD_AG := y
 
 DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER -DSDTEST       \
        -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DBCMFILEIMAGE            \
        -DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DBCMDBG -DGET_OTP_MAC_ENABLE   \
        -DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY             \
-       -DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DPNO_SUPPORT                       \
+       -DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DPNO_SUPPORT -DDHDTCPACK_SUPPRESS  \
        -DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DRXFRAME_THREAD          \
-       -DSWTXGLOM                                                            \
+       -DTSQ_MULTIPLIER                                                      \
+       -DBCMSDIOH_TXGLOM_EXT -DWL_EXT_IAPSTA                                 \
        -DENABLE_INSMOD_NO_FW_LOAD                                            \
        -Idrivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd \
        -Idrivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include
@@ -23,19 +25,19 @@ DHDOFILES = aiutils.o siutils.o sbutils.o bcmutils.o bcmwifi_channels.o \
        dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o \
        dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o \
        bcmevent.o hndpmu.o linux_osl.o wldev_common.o wl_android.o \
-       hnd_pktq.o hnd_pktpool.o dhd_config.o
+       hnd_pktq.o hnd_pktpool.o dhd_config.o wl_android_ext.o
 
 ifneq ($(CONFIG_BCMDHD_SDIO),)
 DHDCFLAGS += \
        -DBCMSDIO -DMMC_SDIO_ABORT -DBCMLXSDMMC -DUSE_SDIOFIFO_IOVAR          \
-       -DBDC -DPROP_TXSTATUS -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM           \
-       -DCUSTOM_SDIO_F2_BLKSIZE=128
+       -DBDC -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM                           \
+       -DCUSTOM_SDIO_F2_BLKSIZE=256
 
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \
        dhd_sdio.o dhd_cdc.o dhd_wlfc.o
 
 ifeq ($(CONFIG_BCMDHD_OOB),y)
-DHDCFLAGS += -DOOB_INTR_ONLY -DHW_OOB -DCUSTOMER_OOB
+DHDCFLAGS += -DOOB_INTR_ONLY -DCUSTOMER_OOB -DHW_OOB
 ifeq ($(CONFIG_BCMDHD_DISABLE_WOWLAN),y)
 DHDCFLAGS += -DDISABLE_WOWLAN
 endif
@@ -44,6 +46,15 @@ DHDCFLAGS += -DSDIO_ISR_THREAD
 endif
 endif
 
+ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
+ifneq ($(CONFIG_BCMDHD_SDIO),)
+DHDCFLAGS += -DPROP_TXSTATUS
+endif
+ifneq ($(CONFIG_CFG80211),)
+DHDCFLAGS += -DPROP_TXSTATUS_VSDB
+endif
+endif
+
 ifneq ($(CONFIG_BCMDHD_PCIE),)
 DHDCFLAGS += \
        -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1
@@ -55,9 +66,9 @@ endif
 obj-$(CONFIG_AP6XXX) += bcmdhd.o
 bcmdhd-objs += $(DHDOFILES)
 
-#ifeq ($(CONFIG_MACH_ODROID_4210),y)
+#ifeq ($(CONFIG_MACH_PLATFORM),y)
 DHDOFILES += dhd_gpio.o
-DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT -DGET_CUSTOM_MAC_ENABLE
+DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT
 #DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
 #endif
 
@@ -66,8 +77,7 @@ DHDCFLAGS += -DBAND_AG
 endif
 
 ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
-# add dhd_static_buf to kernel image build
-#DHDOFILES += dhd_static_buf.o
+obj-m += dhd_static_buf.o
 DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
 endif
 
@@ -76,7 +86,7 @@ DHDOFILES += wl_iw.o wl_escan.o
 DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW -DWL_ESCAN
 endif
 ifneq ($(CONFIG_CFG80211),)
-DHDOFILES += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o wl_cfg_btcoex.o
+DHDOFILES += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o wl_cfg_btcoex.o wl_cfgvendor.o
 DHDOFILES += dhd_cfg80211.o dhd_cfg_vendor.o
 DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF
 #DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
@@ -88,7 +98,7 @@ DHDCFLAGS += -DWL_SUPPORT_AUTO_CHANNEL
 DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
 DHDCFLAGS += -DESCAN_RESULT_PATCH
 DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
-DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8 -DPROP_TXSTATUS_VSDB
+DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8
 endif
 EXTRA_CFLAGS = $(DHDCFLAGS)
 ifeq ($(CONFIG_BCMDHD),m)
index 70b2b6301ecb53b794239640c12d12bacd741996..493a2e08ab9c3143898a058de718e46ec46dae7e 100755 (executable)
@@ -357,7 +357,7 @@ ai_scan(si_t *sih, void *regs, uint devid)
                sii->numcores++;
        }
 
-       SI_ERROR(("Reached end of erom without finding END"));
+       SI_ERROR(("Reached end of erom without finding END\n"));
 
 error:
        sii->numcores = 0;
index 5f955a75b3edbf1cc77ebce809d9cbf983d5548c..400f441cc58d35f3542caaf0460c73793dc500d1 100755 (executable)
@@ -392,7 +392,7 @@ bcmsdh_reg_read(void *sdh, uint32 addr, uint size)
        SDIOH_API_RC status;
        uint32 word = 0;
 
-       BCMSDH_INFO(("%s:fun = 1, addr = 0x%x", __FUNCTION__, addr));
+       BCMSDH_INFO(("%s:fun = 1, addr = 0x%x\n", __FUNCTION__, addr));
 
        if (!bcmsdh)
                bcmsdh = l_bcmsdh;
index e9e261a06c611b806d6fa80c6693e161cb94b3d2..9c93279dcbf2188b8e6b38a5b397947a1297257b 100755 (executable)
@@ -345,7 +345,7 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl
 #else
        printf("%s: SW_OOB enabled\n", __FUNCTION__);
 #endif
-       SDLX_MSG(("%s OOB irq=%d flags=%X\n", __FUNCTION__,
+       SDLX_MSG(("%s OOB irq=%d flags=0x%X\n", __FUNCTION__,
                (int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
        bcmsdh_osinfo->oob_irq_handler = oob_irq_handler;
        bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context;
index f0bef15bd56cb4a9854e9b66777ae5168fba33c6..1605f65af5d03c44e681396c688cdbb822efd7bc 100755 (executable)
@@ -62,7 +62,7 @@ static void IRQHandler(struct sdio_func *func);
 static void IRQHandlerF2(struct sdio_func *func);
 #endif /* !defined(OOB_INTR_ONLY) */
 static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
-#if defined(ENABLE_INSMOD_NO_FW_LOAD)
+#if defined(ENABLE_INSMOD_NO_FW_LOAD) && !defined(BUS_POWER_RESTORE)
 extern int sdio_reset_comm(struct mmc_card *card);
 #else
 int sdio_reset_comm(struct mmc_card *card)
@@ -545,7 +545,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
                /* Now set it */
                si->client_block_size[func] = blksize;
 
-#ifdef USE_DYNAMIC_F2_BLKSIZE
                if (si->func[func] == NULL) {
                        sd_err(("%s: SDIO Device not present\n", __FUNCTION__));
                        bcmerror = BCME_NORESOURCE;
@@ -557,7 +556,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
                        sd_err(("%s: Failed to set F%d blocksize to %d(%d)\n",
                                __FUNCTION__, func, blksize, bcmerror));
                sdio_release_host(si->func[func]);
-#endif /* USE_DYNAMIC_F2_BLKSIZE */
                break;
        }
 
@@ -820,6 +818,10 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
 #if defined(MMC_SDIO_ABORT)
        int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
 #endif
+       struct timespec now, before;
+
+       if (sd_msglevel & SDH_COST_VAL)
+               getnstimeofday(&before);
 
        sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr));
 
@@ -911,6 +913,12 @@ 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));
+       }
+
        return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
 }
 
@@ -1317,6 +1325,10 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add
 #if defined(MMC_SDIO_ABORT)
        int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
 #endif
+       struct timespec now, before;
+
+       if (sd_msglevel & SDH_COST_VAL)
+               getnstimeofday(&before);
 
        if (func == 0) {
                sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__));
@@ -1378,6 +1390,12 @@ 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));
+       }
+
        return (((err_ret == 0)&&(err_ret2 == 0)) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
 }
 
@@ -1404,12 +1422,16 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
        uint local_plen = 0;
        uint pkt_len = 0;
 #endif /* BCMSDIOH_TXGLOM */
+       struct timespec now, before;
 
        sd_trace(("%s: Enter\n", __FUNCTION__));
        ASSERT(pkt);
        DHD_PM_RESUME_WAIT(sdioh_request_packet_wait);
        DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
 
+       if (sd_msglevel & SDH_COST_VAL)
+               getnstimeofday(&before);
+
        blk_size = sd->client_block_size[func];
        max_blk_count = min(host->max_blk_count, (uint)MAX_IO_RW_EXTENDED_BLK);
        max_req_size = min(max_blk_count * blk_size, host->max_req_size);
@@ -1449,7 +1471,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\n", __FUNCTION__));
+                               sd_err(("%s: sg list entries exceed limit %d\n", __FUNCTION__, sg_count));
                                return (SDIOH_API_RC_FAIL);
                        }
                        pdata += pkt_offset;
@@ -1585,6 +1607,12 @@ txglomfail:
                MFREE(sd->osh, localbuf, ttl_len);
 #endif /* BCMSDIOH_TXGLOM */
 
+       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_trace(("%s: Exit\n", __FUNCTION__));
        return SDIOH_API_RC_SUCCESS;
 }
@@ -1595,10 +1623,14 @@ sdioh_buffer_tofrom_bus(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
 {
        bool fifo = (fix_inc == SDIOH_DATA_FIX);
        int err_ret = 0;
+       struct timespec now, before;
 
        sd_trace(("%s: Enter\n", __FUNCTION__));
        ASSERT(buf);
 
+       if (sd_msglevel & SDH_COST_VAL)
+               getnstimeofday(&before);
+
        /* NOTE:
         * For all writes, each packet length is aligned to 32 (or 4)
         * bytes in dhdsdio_txpkt_preprocess, and for glom the last packet length
@@ -1629,6 +1661,13 @@ sdioh_buffer_tofrom_bus(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
                        (write) ? "TX" : "RX", buf, addr, len));
 
        sd_trace(("%s: Exit\n", __FUNCTION__));
+
+       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));
+       }
+
        return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
 }
 
@@ -1650,11 +1689,15 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
 {
        SDIOH_API_RC status;
        void *tmppkt;
+       struct timespec now, before;
 
        sd_trace(("%s: Enter\n", __FUNCTION__));
        DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait);
        DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
 
+       if (sd_msglevel & SDH_COST_VAL)
+               getnstimeofday(&before);
+
        if (pkt) {
                /* packet chain, only used for tx/rx glom, all packets length
                 * are aligned, total length is a block multiple
@@ -1696,6 +1739,12 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
 
        PKTFREE_STATIC(sd->osh, tmppkt, write ? TRUE : FALSE);
 
+       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));
+       }
+
        return status;
 }
 
index fe00aaf81bed58bd3b37670f67357b8a557676b7..741c50892102be360df81cf0dcd63a042e87cfa8 100755 (executable)
@@ -113,9 +113,12 @@ static int sdioh_probe(struct sdio_func *func)
 
        sd_err(("bus num (host idx)=%d, slot num (rca)=%d\n", host_idx, rca));
        adapter = dhd_wifi_platform_get_adapter(SDIO_BUS, host_idx, rca);
-       if (adapter  != NULL)
+       if (adapter != NULL) {
                sd_err(("found adapter info '%s'\n", adapter->name));
-       else
+#ifdef BUS_POWER_RESTORE
+               adapter->sdio_func = func;
+#endif
+       } else
                sd_err(("can't find adapter info for this chip\n"));
 
 #ifdef WL_CFG80211
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/circularbuf.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/circularbuf.c
deleted file mode 100755 (executable)
index bfb308c..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/** @file circularbuf.c
- *
- * PCIe host driver and dongle firmware need to communicate with each other. The mechanism consists
- * of multiple circular buffers located in (DMA'able) host memory. A circular buffer is either used
- * for host -> dongle (h2d) or dongle -> host communication. Both host driver and firmware make use
- * of this source file. This source file contains functions to manage such a set of circular
- * buffers, but does not contain the code to read or write the data itself into the buffers. It
- * leaves that up to the software layer that uses this file, which can be implemented either using
- * pio or DMA transfers. It also leaves the format of the data that is written and read to a higher
- * layer. Typically the data is in the form of so-called 'message buffers'.
- *
- * $Copyright Open Broadcom Corporation$
- *
- * $Id: circularbuf.c 467150 2014-04-02 17:30:43Z $
- */
-
-#include <circularbuf.h>
-#include <bcmmsgbuf.h>
-#include <osl.h>
-
-#define CIRCULARBUF_READ_SPACE_AT_END(x)               \
-                       ((x->w_ptr >= x->rp_ptr) ? (x->w_ptr - x->rp_ptr) : (x->e_ptr - x->rp_ptr))
-
-#define CIRCULARBUF_READ_SPACE_AVAIL(x)                \
-                       (((CIRCULARBUF_READ_SPACE_AT_END(x) == 0) && (x->w_ptr < x->rp_ptr)) ? \
-                               x->w_ptr : CIRCULARBUF_READ_SPACE_AT_END(x))
-
-int cbuf_msg_level = CBUF_ERROR_VAL | CBUF_TRACE_VAL | CBUF_INFORM_VAL;
-
-/* #define CBUF_DEBUG */
-#ifdef CBUF_DEBUG
-#define CBUF_DEBUG_CHECK(x)    x
-#else
-#define CBUF_DEBUG_CHECK(x)
-#endif /* CBUF_DEBUG */
-
-/**
- * -----------------------------------------------------------------------------
- * Function   : circularbuf_init
- * Description:
- *
- *
- * Input Args : buf_base_addr: address of DMA'able host memory provided by caller
- *
- *
- * Return Values :
- *
- * -----------------------------------------------------------------------------
- */
-void
-circularbuf_init(circularbuf_t *handle, void *buf_base_addr, uint16 total_buf_len)
-{
-       handle->buf_addr = buf_base_addr;
-
-       handle->depth = handle->e_ptr = HTOL32(total_buf_len);
-
-       /* Initialize Read and Write pointers */
-       handle->w_ptr = handle->r_ptr = handle->wp_ptr = handle->rp_ptr = HTOL32(0);
-       handle->mb_ring_bell = NULL;
-       handle->mb_ctx = NULL;
-
-       return;
-}
-
-/**
- * When an item is added to the circular buffer by the producing party, the consuming party has to
- * be notified by means of a 'door bell' or 'ring'. This function allows the caller to register a
- * 'ring' function that will be called when a 'write complete' occurs.
- */
-void
-circularbuf_register_cb(circularbuf_t *handle, mb_ring_t mb_ring_func, void *ctx)
-{
-       handle->mb_ring_bell = mb_ring_func;
-       handle->mb_ctx = ctx;
-}
-
-#ifdef CBUF_DEBUG
-static void
-circularbuf_check_sanity(circularbuf_t *handle)
-{
-       if ((handle->e_ptr > handle->depth) ||
-           (handle->r_ptr > handle->e_ptr) ||
-               (handle->rp_ptr > handle->e_ptr) ||
-               (handle->w_ptr > handle->e_ptr))
-       {
-               printf("%s:%d: Pointers are corrupted.\n", __FUNCTION__, __LINE__);
-               circularbuf_debug_print(handle);
-               ASSERT(0);
-       }
-       return;
-}
-#endif /* CBUF_DEBUG */
-
-/**
- * -----------------------------------------------------------------------------
- * Function   : circularbuf_reserve_for_write
- *
- * Description:
- * This function reserves N bytes for write in the circular buffer. The circularbuf
- * implementation will only reserve space in the circular buffer and return
- * the pointer to the address where the new data can be written.
- * The actual write implementation (bcopy/dma) is outside the scope of
- * circularbuf implementation.
- *
- * Input Args :
- *             size - No. of bytes to reserve for write
- *
- * Return Values :
- *             void * : Pointer to the reserved location. This is the address
- *                       that will be used for write (dma/bcopy)
- *
- * -----------------------------------------------------------------------------
- */
-void * BCMFASTPATH
-circularbuf_reserve_for_write(circularbuf_t *handle, uint16 size)
-{
-       int16 avail_space;
-       void *ret_ptr = NULL;
-
-       CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle));
-       ASSERT(size < handle->depth);
-
-       if (handle->wp_ptr >= handle->r_ptr)
-               avail_space = handle->depth - handle->wp_ptr;
-       else
-               avail_space = handle->r_ptr - handle->wp_ptr;
-
-       ASSERT(avail_space <= handle->depth);
-       if (avail_space > size)
-       {
-               /* Great. We have enough space. */
-               ret_ptr = CIRCULARBUF_START(handle) + handle->wp_ptr;
-
-               /*
-                * We need to update the wp_ptr for the next guy to write.
-                *
-                * Please Note : We are not updating the write pointer here. This can be
-                * done only after write is complete (In case of DMA, we can only schedule
-                * the DMA. Actual completion will be known only on DMA complete interrupt).
-                */
-               handle->wp_ptr += size;
-               return ret_ptr;
-       }
-
-       /*
-        * If there is no available space, we should check if there is some space left
-        * in the beginning of the circular buffer.  Wrap-around case, where there is
-        * not enough space in the end of the circular buffer. But, there might be
-        * room in the beginning of the buffer.
-        */
-       if (handle->wp_ptr >= handle->r_ptr)
-       {
-               avail_space = handle->r_ptr;
-               if (avail_space > size)
-               {
-                       /* OK. There is room in the beginning. Let's go ahead and use that.
-                        * But, before that, we have left a hole at the end of the circular
-                        * buffer as that was not sufficient to accomodate the requested
-                        * size. Let's make sure this is updated in the circularbuf structure
-                        * so that consumer does not use the hole.
-                        */
-                       handle->e_ptr  = handle->wp_ptr;
-                       handle->wp_ptr = size;
-
-                       return CIRCULARBUF_START(handle);
-               }
-       }
-
-       /* We have tried enough to accomodate the new packet. There is no room for now. */
-       return NULL;
-}
-
-/**
- * -----------------------------------------------------------------------------
- * Function   : circularbuf_write_complete
- *
- * Description:
- * This function has to be called by the producer end of circularbuf to indicate to
- * the circularbuf layer that data has been written and the write pointer can be
- * updated. In the process, if there was a doorbell callback registered, that
- * function would also be invoked as to notify the consuming party.
- *
- * Input Args :
- *             dest_addr         : Address where the data was written. This would be the
- *                                         same address that was reserved earlier.
- *             bytes_written : Length of data written
- *
- * -----------------------------------------------------------------------------
- */
-void BCMFASTPATH
-circularbuf_write_complete(circularbuf_t *handle, uint16 bytes_written)
-{
-       CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle));
-
-       /* Update the write pointer */
-       if ((handle->w_ptr + bytes_written) >= handle->depth) {
-               OSL_CACHE_FLUSH((void *) CIRCULARBUF_START(handle), bytes_written);
-               handle->w_ptr = bytes_written;
-       } else {
-               OSL_CACHE_FLUSH((void *) (CIRCULARBUF_START(handle) + handle->w_ptr),
-                       bytes_written);
-               handle->w_ptr += bytes_written;
-       }
-
-       /* And ring the door bell (mail box interrupt) to indicate to the peer that
-        * message is available for consumption.
-        */
-       if (handle->mb_ring_bell)
-               handle->mb_ring_bell(handle->mb_ctx);
-}
-
-/**
- * -----------------------------------------------------------------------------
- * Function   : circularbuf_get_read_ptr
- *
- * Description:
- * This function will be called by the consumer of circularbuf for reading data from
- * the circular buffer. This will typically be invoked when the consumer gets a
- * doorbell interrupt.
- * Please note that the function only returns the pointer (and length) from
- * where the data can be read. Actual read implementation is up to the
- * consumer. It could be a bcopy or dma.
- *
- * Input Args :
- *             void *                  : Address from where the data can be read.
- *             available_len   : Length of data available for read.
- *
- * -----------------------------------------------------------------------------
- */
-void * BCMFASTPATH
-circularbuf_get_read_ptr(circularbuf_t *handle, uint16 *available_len)
-{
-       uint8 *ret_addr;
-
-       CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle));
-
-       /* First check if there is any data available in the circular buffer */
-       *available_len = CIRCULARBUF_READ_SPACE_AVAIL(handle);
-       if (*available_len == 0)
-               return NULL;
-
-       /*
-        * Although there might be data in the circular buffer for read, in
-        * cases of write wrap-around and read still in the end of the circular
-        * buffer, we might have to wrap around the read pending pointer also.
-        */
-       if (CIRCULARBUF_READ_SPACE_AT_END(handle) == 0)
-               handle->rp_ptr = 0;
-
-       ret_addr = CIRCULARBUF_START(handle) + handle->rp_ptr;
-
-       /*
-        * Please note that we do not update the read pointer here. Only
-        * read pending pointer is updated, so that next reader knows where
-        * to read data from.
-        * read pointer can only be updated when the read is complete.
-        */
-       handle->rp_ptr = (uint16)(ret_addr - CIRCULARBUF_START(handle) + *available_len);
-
-       ASSERT(*available_len <= handle->depth);
-
-       OSL_CACHE_INV((void *) ret_addr, *available_len);
-
-       return ret_addr;
-}
-
-/**
- * -----------------------------------------------------------------------------
- * Function   : circularbuf_read_complete
- * Description:
- * This function has to be called by the consumer end of circularbuf to indicate
- * that data has been consumed and the read pointer can be updated, so the producing side
- * can can use the freed space for new entries.
- *
- *
- * Input Args :
- *             bytes_read : No. of bytes consumed by the consumer. This has to match
- *                                      the length returned by circularbuf_get_read_ptr
- *
- * Return Values :
- *             CIRCULARBUF_SUCCESS             : Otherwise
- *
- * -----------------------------------------------------------------------------
- */
-circularbuf_ret_t BCMFASTPATH
-circularbuf_read_complete(circularbuf_t *handle, uint16 bytes_read)
-{
-       CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle));
-       ASSERT(bytes_read < handle->depth);
-
-       /* Update the read pointer */
-       if ((handle->w_ptr < handle->e_ptr) && (handle->r_ptr + bytes_read) > handle->e_ptr)
-               handle->r_ptr = bytes_read;
-       else
-               handle->r_ptr += bytes_read;
-
-       return CIRCULARBUF_SUCCESS;
-}
-
-/**
- * -----------------------------------------------------------------------------
- * Function    : circularbuf_revert_rp_ptr
- *
- * Description:
- * The rp_ptr update during circularbuf_get_read_ptr() is done to reflect the amount of data
- * that is sent out to be read by the consumer. But the consumer may not always read the
- * entire data. In such a case, the rp_ptr needs to be reverted back by 'left' bytes, where
- * 'left' is the no. of bytes left unread.
- *
- * Input args:
- *     bytes : The no. of bytes left unread by the consumer
- *
- * -----------------------------------------------------------------------------
- */
-circularbuf_ret_t
-circularbuf_revert_rp_ptr(circularbuf_t *handle, uint16 bytes)
-{
-       CBUF_DEBUG_CHECK(circularbuf_check_sanity(handle));
-       ASSERT(bytes < handle->depth);
-
-       handle->rp_ptr -= bytes;
-
-       return CIRCULARBUF_SUCCESS;
-}
index 0e743b462ed16c665474854b9d22a1339ea57339..6371bdefd7d1393c5f6051bef466f421f717b401 100644 (file)
@@ -1034,6 +1034,7 @@ extern int        dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val);
 extern void dhd_enable_packet_filter(int value, dhd_pub_t *dhd);
 extern int net_os_enable_packet_filter(struct net_device *dev, int val);
 extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num);
+extern int net_os_set_suspend_bcn_li_dtim(struct net_device *dev, int val);
 #endif /* PKT_FILTER_SUPPORT */
 
 extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd);
@@ -1172,25 +1173,6 @@ extern int wl_iw_send_priv_event(struct net_device *dev, char *flag);
 extern uint dhd_watchdog_ms;
 extern bool dhd_os_wd_timer_enabled(void *bus);
 
-#ifdef PKT_STATICS
-typedef struct pkt_statics {
-       uint16  event_count;
-       uint32  event_size;
-       uint16  ctrl_count;
-       uint32  ctrl_size;
-       uint32  data_count;
-       uint32  data_size;
-       uint16  glom_1_count;
-       uint16  glom_3_count;
-       uint16  glom_3_8_count;
-       uint16  glom_8_count;
-       uint16  glom_count;
-       uint32  glom_size;
-       uint16  test_count;
-       uint32  test_size;
-} pkt_statics_t;
-#endif
-
 #ifdef DHD_PCIE_RUNTIMEPM
 extern uint dhd_runtimepm_ms;
 #endif /* DHD_PCIE_RUNTIMEPM */
@@ -1316,7 +1298,11 @@ extern uint dhd_force_tx_queueing;
 #define WIFI_TURNON_DELAY              DEFAULT_WIFI_TURNON_DELAY
 #endif /* WIFI_TURNON_DELAY */
 
+#ifdef BCMSDIO
 #define DEFAULT_DHD_WATCHDOG_INTERVAL_MS       10 /* msec */
+#else
+#define DEFAULT_DHD_WATCHDOG_INTERVAL_MS       0 /* msec */
+#endif
 #ifndef CUSTOM_DHD_WATCHDOG_MS
 #define CUSTOM_DHD_WATCHDOG_MS                 DEFAULT_DHD_WATCHDOG_INTERVAL_MS
 #endif /* DEFAULT_DHD_WATCHDOG_INTERVAL_MS */
index 639cc23790279a38b6b367f73990b7fc390b55fe..b767174608ca59750ed08740ee79713d41c61c10 100755 (executable)
@@ -50,6 +50,7 @@
 #include <dhd_bus.h>
 #include <dhd_proto.h>
 #include <dhd_config.h>
+#include <bcmsdbus.h>
 #include <dhd_dbg.h>
 #include <msgtrace.h>
 
@@ -672,9 +673,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
                int_val = (int32)wl_dbg_level;
                bcopy(&int_val, arg, val_size);
                printf("cfg_msg_level=0x%x\n", wl_dbg_level);
-#endif
-#ifdef PKT_STATICS
-               dhdsdio_txpktstatics();
 #endif
                break;
 
@@ -703,6 +701,9 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
        case IOV_GVAL(IOV_MSGLEVEL):
                int_val = (int32)dhd_msg_level;
                bcopy(&int_val, arg, val_size);
+#ifdef PKT_STATICS
+               dhdsdio_txpktstatics();
+#endif
                break;
 
        case IOV_SVAL(IOV_MSGLEVEL):
@@ -3126,6 +3127,7 @@ dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd)
        if (bcn_li_dtim == 0) {
                bcn_li_dtim = 1;
        }
+       bcn_li_dtim = MAX(dhd->suspend_bcn_li_dtim, bcn_li_dtim);
 #else /* ENABLE_MAX_DTIM_IN_SUSPEND */
        /* attemp to use platform defined dtim skip interval */
        bcn_li_dtim = dhd->suspend_bcn_li_dtim;
index 1d7ae19b2feaff9628705003e36d31ecf463e078..3c5c9f29a4974a63636e07b411ca2c12001a32b3 100755 (executable)
@@ -48,144 +48,47 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
 #define FW_TYPE_AG      1\r
 \r
 #ifdef CONFIG_PATH_AUTO_SELECT\r
-#define BCM4330B2_CONF_NAME "config_40183b2.txt"\r
-#define BCM43362A0_CONF_NAME "config_40181a0.txt"\r
-#define BCM43362A2_CONF_NAME "config_40181a2.txt"\r
-#define BCM43438A0_CONF_NAME "config_43438a0.txt"\r
-#define BCM43438A1_CONF_NAME "config_43438a1.txt"\r
-#define BCM4334B1_CONF_NAME "config_4334b1.txt"\r
-#define BCM43341B0_CONF_NAME "config_43341b0.txt"\r
-#define BCM43241B4_CONF_NAME "config_43241b4.txt"\r
-#define BCM4339A0_CONF_NAME "config_4339a0.txt"\r
-#define BCM43455C0_CONF_NAME "config_43455c0.txt"\r
-#define BCM4354A1_CONF_NAME "config_4354a1.txt"\r
-#define BCM4356A2_CONF_NAME "config_4356a2.txt"\r
-#define BCM4359B1_CONF_NAME "config_4359b1.txt"\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_BCM4354A1 "config_4354a1.txt"\r
+#endif\r
+#define CONFIG_BCM4356A2 "config_4356a2.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
-const static char *bcm4330b2_fw_name[] = {\r
-       "fw_RK903b2.bin",
-       "fw_RK903b2_apsta.bin",
-       "fw_RK903b2_p2p.bin",
-       "fw_bcm40183b2_es.bin",\r
-       "fw_RK903b2_mfg.bin"
-};\r
-\r
-const static char *bcm4330b2_ag_fw_name[] = {\r
-       "fw_RK903_ag.bin",
-       "fw_RK903_ag_apsta.bin",
-       "fw_RK903_ag_p2p.bin",
-       "fw_bcm40183b2_ag_es.bin",\r
-       "fw_RK903_ag_mfg.bin"
-};\r
-\r
-const static char *bcm43362a0_fw_name[] = {\r
-       "fw_RK901a0.bin",
-       "fw_RK901a0_apsta.bin",
-       "fw_RK901a0_p2p.bin",
-       "fw_bcm40181a0_es.bin",\r
-       "fw_RK901a0_mfg.bin"
-};\r
-\r
-const static char *bcm43362a2_fw_name[] = {\r
-       "fw_RK901a2.bin",
-       "fw_RK901a2_apsta.bin",
-       "fw_RK901a2_p2p.bin",
-       "fw_bcm40181a2_es.bin",\r
-       "fw_RK901a2_mfg.bin"
-};\r
-\r
-const static char *bcm4334b1_ag_fw_name[] = {\r
-       "fw_bcm4334b1_ag.bin",\r
-       "fw_bcm4334b1_ag_apsta.bin",\r
-       "fw_bcm4334b1_ag_p2p.bin",\r
-       "fw_bcm4334b1_ag_es.bin",\r
-       "fw_bcm4334b1_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm43438a0_fw_name[] = {\r
-       "fw_bcm43438a0.bin",\r
-       "fw_bcm43438a0_apsta.bin",\r
-       "fw_bcm43438a0_p2p.bin",\r
-       "fw_bcm43438a0_es.bin",\r
-       "fw_bcm43438a0_mfg.bin"\r
-};\r
-\r
-const static char *bcm43438a1_fw_name[] = {\r
-       "fw_bcm43438a1.bin",\r
-       "fw_bcm43438a1_apsta.bin",\r
-       "fw_bcm43438a1_p2p.bin",\r
-       "fw_bcm43438a1_es.bin",\r
-       "fw_bcm43438a1_mfg.bin"\r
-};\r
-\r
-const static char *bcm43341b0_ag_fw_name[] = {\r
-       "fw_bcm43341b0_ag.bin",\r
-       "fw_bcm43341b0_ag_apsta.bin",\r
-       "fw_bcm43341b0_ag_p2p.bin",\r
-       "fw_bcm43341b0_ag_es.bin",\r
-       "fw_bcm43341b0_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm43241b4_ag_fw_name[] = {\r
-       "fw_bcm43241b4_ag.bin",\r
-       "fw_bcm43241b4_ag_apsta.bin",\r
-       "fw_bcm43241b4_ag_p2p.bin",\r
-       "fw_bcm43241b4_ag_es.bin",\r
-       "fw_bcm43241b4_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm4339a0_ag_fw_name[] = {\r
-       "fw_bcm4339a0_ag.bin",\r
-       "fw_bcm4339a0_ag_apsta.bin",\r
-       "fw_bcm4339a0_ag_p2p.bin",\r
-       "fw_bcm4339a0_ag_es.bin",\r
-       "fw_bcm4339a0_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm43455c0_ag_fw_name[] = {\r
-       "fw_bcm43455c0_ag.bin",\r
-       "fw_bcm43455c0_ag_apsta.bin",\r
-       "fw_bcm43455c0_ag_p2p.bin",\r
-       "fw_bcm43455c0_ag_es.bin",\r
-       "fw_bcm43455c0_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm4354a1_ag_fw_name[] = {\r
-       "fw_bcm4354a1_ag.bin",\r
-       "fw_bcm4354a1_ag_apsta.bin",\r
-       "fw_bcm4354a1_ag_p2p.bin",\r
-       "fw_bcm4354a1_ag_es.bin",\r
-       "fw_bcm4354a1_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm4356a2_ag_fw_name[] = {\r
-       "fw_bcm4356a2_ag.bin",\r
-       "fw_bcm4356a2_ag_apsta.bin",\r
-       "fw_bcm4356a2_ag_p2p.bin",\r
-       "fw_bcm4356a2_ag_es.bin",\r
-       "fw_bcm4356a2_ag_mfg.bin"\r
-};\r
-\r
-const static char *bcm4359b1_ag_fw_name[] = {\r
-       "fw_bcm4359b1_ag.bin",\r
-       "fw_bcm4359b1_ag_apsta.bin",\r
-       "fw_bcm4359b1_ag_p2p.bin",\r
-       "fw_bcm4359b1_ag_es.bin",\r
-       "fw_bcm4359b1_ag_mfg.bin"\r
-};\r
+#define FW_BCM4330B2 "fw_RK903b2"\r
+#define FW_BCM4330B2_AG "fw_RK903_ag"\r
+#define FW_BCM43362A0 "fw_RK901a0"\r
+#define FW_BCM43362A2 "fw_RK901a2"\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_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_BCM4354A1 "fw_bcm4354a1_ag"\r
+#define FW_BCM4356A2 "fw_bcm4356a2_ag"\r
+#define FW_BCM4359B1 "fw_bcm4359b1_ag"\r
+#define FW_BCM4359C0 "fw_bcm4359c0_ag"\r
 #endif\r
 #ifdef BCMPCIE\r
-const static char *bcm4356a2_pcie_ag_fw_name[] = {\r
-       "fw_bcm4356a2_pcie_ag.bin",\r
-       "fw_bcm4356a2_pcie_ag_apsta.bin",\r
-       "fw_bcm4356a2_pcie_ag_p2p.bin",\r
-       "fw_bcm4356a2_pcie_ag_es.bin",\r
-       "fw_bcm4356a2_pcie_ag_mfg.bin"\r
-};\r
+#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag"\r
 #endif\r
 \r
 #define htod32(i) i
@@ -312,7 +215,7 @@ dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac)
                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+1, 6);\r
+                                       memcpy(mac, ptr+3, 6);\r
                                        err = 0;\r
                                        break;\r
                                }\r
@@ -442,7 +345,8 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path, char *nv_path)
 {\r
        int fw_type, ag_type;\r
        uint chip, chiprev;\r
-       int i, j;
+       int i,j;\r
+       char fw_tail[10];\r
 \r
        chip = dhd->conf->chip;\r
        chiprev = dhd->conf->chiprev;\r
@@ -484,94 +388,110 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path, char *nv_path)
                (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], bcm4330b2_fw_name[fw_type]);\r
-                               break;\r
+                                       strcpy(&fw_path[i+1], FW_BCM4330B2);\r
                        } else {\r
                                if (chiprev == BCM4330B2_CHIP_REV)\r
-                                       strcpy(&fw_path[i+1], bcm4330b2_ag_fw_name[fw_type]);\r
-                               strcpy(&nv_path[j + 1], "nvram_AP6330.txt");
-                               break;\r
+                                       strcpy(&fw_path[i+1], FW_BCM4330B2_AG);\r
+                               strcpy(&nv_path[j + 1], "nvram_AP6330.txt");\r
                        }\r
+                       break;\r
                case BCM43362_CHIP_ID:\r
                        if (chiprev == BCM43362A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm43362a0_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM43362A0);\r
                        else\r
-                               strcpy(&fw_path[i+1], bcm43362a2_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM43362A2);\r
                        if (!strstr(nv_path, "6476"))
                                strcpy(&nv_path[j + 1], "nvram_AP6210.txt");
                        break;\r
                case BCM43430_CHIP_ID:\r
-                       if (chiprev == BCM43430A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm43438a0_fw_name[fw_type]);\r
-                       else if (chiprev == BCM43430A1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm43438a1_fw_name[fw_type]);\r
-                       strcpy(&nv_path[j + 1], "nvram_ap6212.txt");
+                       if (chiprev == BCM43430A0_CHIP_REV) {\r
+                               strcpy(&fw_path[i+1], FW_BCM43438A0);\r
+                               strcpy(&nv_path[j + 1], "nvram_ap6212.txt");\r
+                       } else if (chiprev == BCM43430A1_CHIP_REV) {\r
+                               strcpy(&fw_path[i+1], FW_BCM43438A1);\r
+                               strcpy(&nv_path[j + 1], "nvram_ap6212a.txt");
+                       } else if (chiprev == BCM43430A2_CHIP_REV) {\r
+                               strcpy(&fw_path[i+1], FW_BCM43436B0);\r
+                               strcpy(&nv_path[j + 1], "nvram_ap6236.txt");
+                       }
                        break;\r
                case BCM4334_CHIP_ID:\r
                        if (chiprev == BCM4334B1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4334b1_ag_fw_name[fw_type]);\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], bcm43341b0_ag_fw_name[fw_type]);\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], bcm43241b4_ag_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM43241B4);\r
                        strcpy(&nv_path[j + 1], "nvram_ap62x2.txt");
                        break;\r
                case BCM4335_CHIP_ID:\r
                        if (chiprev == BCM4335A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4339a0_ag_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM4339A0);\r
+                       strcpy(&nv_path[j + 1], "nvram_AP6335.txt");\r
+                       break;\r
+               case BCM4339_CHIP_ID:\r
+                       if (chiprev == BCM4339A0_CHIP_REV)\r
+                               strcpy(&fw_path[i+1], FW_BCM4339A0);\r
+                       strcpy(&nv_path[j + 1], "nvram_AP6335.txt");\r
                        break;\r
                case BCM4345_CHIP_ID:\r
                case BCM43454_CHIP_ID:\r
                        if (chiprev == BCM43455C0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm43455c0_ag_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM43455C0);\r
                        strcpy(&nv_path[j + 1], "nvram_ap6255.txt");
                        break;\r
-               case BCM4339_CHIP_ID:\r
-                       if (chiprev == BCM4339A0_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4339a0_ag_fw_name[fw_type]);\r
-                       strcpy(&nv_path[j + 1], "nvram_AP6335.txt");
-                       break;\r
                case BCM4354_CHIP_ID:\r
-                       if (chiprev == BCM4354A1_CHIP_REV) {
-                               strcpy(&fw_path[i+1], bcm4354a1_ag_fw_name[fw_type]);\r
+                       if (chiprev == BCM4354A1_CHIP_REV) {\r
+                               strcpy(&fw_path[i+1], FW_BCM4354A1);\r
                                strcpy(&nv_path[j + 1], "nvram_ap6354.txt");
-                       } else if (chiprev == BCM4356A2_CHIP_REV) {
-                               strcpy(&fw_path[i+1], bcm4356a2_ag_fw_name[fw_type]);\r
+                       } else if (chiprev == BCM4356A2_CHIP_REV) {\r
+                               strcpy(&fw_path[i+1], FW_BCM4356A2);\r
                                strcpy(&nv_path[j + 1], "nvram_ap6356.txt");
                        }
                        break;\r
                case BCM4356_CHIP_ID:\r
                case BCM4371_CHIP_ID:\r
                        if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4356a2_ag_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM4356A2);\r
                        strcpy(&nv_path[j + 1], "nvram_ap6356.txt");
                        break;\r
                case BCM4359_CHIP_ID:\r
                        if (chiprev == BCM4359B1_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4359b1_ag_fw_name[fw_type]);\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
-                       if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4356a2_pcie_ag_fw_name[fw_type]);\r
-                       break;\r
                case BCM4356_CHIP_ID:\r
                        if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&fw_path[i+1], bcm4356a2_pcie_ag_fw_name[fw_type]);\r
+                               strcpy(&fw_path[i+1], FW_BCM4356A2);\r
                        break;\r
 #endif\r
        }\r
+       strcat(fw_path, fw_tail);\r
 \r
        printf("%s: firmware_path=%s\n", __FUNCTION__, fw_path);\r
 }\r
@@ -673,66 +593,71 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
 #ifdef BCMSDIO\r
                case BCM4330_CHIP_ID:\r
                        if (chiprev == BCM4330B2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], BCM4330B2_CONF_NAME);\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], BCM43362A0_CONF_NAME);\r
+                               strcpy(&conf_path[i+1], CONFIG_BCM43362A0);\r
                        else\r
-                               strcpy(&conf_path[i+1], BCM43362A2_CONF_NAME);\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], BCM43438A0_CONF_NAME);\r
+                               strcpy(&conf_path[i+1], CONFIG_BCM43438A0);\r
                        else if (chiprev == BCM43430A1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], BCM43438A1_CONF_NAME);\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], BCM4334B1_CONF_NAME);\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], BCM43341B0_CONF_NAME);\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], BCM43241B4_CONF_NAME);\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], BCM4339A0_CONF_NAME);\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], BCM43455C0_CONF_NAME);\r
+                               strcpy(&conf_path[i+1], CONFIG_BCM43455C0);\r
                        break;\r
                case BCM4339_CHIP_ID:\r
                        if (chiprev == BCM4339A0_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], BCM4339A0_CONF_NAME);\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], BCM4354A1_CONF_NAME);\r
+                               strcpy(&conf_path[i+1], CONFIG_BCM4354A1);\r
                        else if (chiprev == BCM4356A2_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], BCM4356A2_CONF_NAME);\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], BCM4356A2_CONF_NAME);\r
+                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
                        break;\r
                case BCM4359_CHIP_ID:\r
                        if (chiprev == BCM4359B1_CHIP_REV)\r
-                               strcpy(&conf_path[i+1], BCM4359B1_CONF_NAME);\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], BCM4356A2_CONF_NAME);\r
+                               strcpy(&conf_path[i+1], CONFIG_BCM4356A2);\r
                        break;\r
 #endif\r
        }\r
@@ -742,76 +667,80 @@ dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
 #endif\r
 \r
 int\r
-dhd_conf_set_fw_int_cmd(dhd_pub_t *dhd, char *name, uint cmd, int val,\r
+dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val,\r
        int def, bool down)\r
 {\r
-       int bcmerror = -1;\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 ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, bcmerror));\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
-               printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val);\r
-               if ((bcmerror = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, bcmerror));\r
        }\r
-       return bcmerror;\r
+\r
+       return ret;\r
 }\r
 \r
 int\r
-dhd_conf_set_fw_int_struct_cmd(dhd_pub_t *dhd, char *name, uint cmd,\r
-       int *val, int len, bool down)\r
+dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf,\r
+       int len, bool down)\r
 {\r
-       int bcmerror = -1;\r
+       char iovbuf[WLC_IOCTL_SMLEN];\r
+       int ret = -1;\r
 \r
        if (down) {\r
-               if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, bcmerror));\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 ((bcmerror = dhd_wl_ioctl_cmd(dhd, cmd, val, len, TRUE, 0)) < 0)\r
-               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, bcmerror));\r
-\r
-       return bcmerror;\r
-}\r
 \r
-int\r
-dhd_conf_set_fw_string_cmd(dhd_pub_t *dhd, char *cmd, int val, int def,\r
-       bool down)\r
-{\r
-       int bcmerror = -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 ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                               CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, bcmerror));\r
-               }\r
-               printf("%s: set %s %d\n", __FUNCTION__, cmd, val);\r
-               bcm_mkiovar(cmd, (char *)&val, 4, iovbuf, sizeof(iovbuf));\r
-               if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, cmd, bcmerror));\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
-       return bcmerror;\r
+\r
+       return ret;\r
 }\r
 \r
 int\r
-dhd_conf_set_fw_string_struct_cmd(dhd_pub_t *dhd, char *cmd, char *val,\r
-       int len, bool down)\r
+dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx)\r
 {\r
-       int bcmerror = -1;\r
        char iovbuf[WLC_IOCTL_SMLEN];\r
-       \r
-       if (down) {\r
-               if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0)\r
-                       CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, bcmerror));\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
-       printf("%s: set %s\n", __FUNCTION__, cmd);\r
-       bcm_mkiovar(cmd, val, len, iovbuf, sizeof(iovbuf));\r
-       if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)\r
-               CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, cmd, bcmerror));\r
 \r
-       return bcmerror;\r
+       return ret;\r
 }\r
 \r
 uint\r
@@ -835,7 +764,7 @@ dhd_conf_set_country(dhd_pub_t *dhd)
        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_fw_string_struct_cmd(dhd, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE);\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
@@ -938,27 +867,50 @@ dhd_conf_set_roam(dhd_pub_t *dhd)
        struct dhd_conf *conf = dhd->conf;\r
 \r
        dhd_roam_disable = conf->roam_off;\r
-       dhd_conf_set_fw_string_cmd(dhd, "roam_off", dhd->conf->roam_off, 0, FALSE);\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_fw_int_struct_cmd(dhd, "WLC_SET_ROAM_TRIGGER", WLC_SET_ROAM_TRIGGER,\r
-                               conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);\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_fw_int_struct_cmd(dhd, "WLC_SET_ROAM_SCAN_PERIOD", WLC_SET_ROAM_SCAN_PERIOD,\r
-                               conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);\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_fw_int_struct_cmd(dhd, "WLC_SET_ROAM_DELTA", WLC_SET_ROAM_DELTA,\r
-                               conf->roam_delta, sizeof(conf->roam_delta), FALSE);\r
-               \r
-               dhd_conf_set_fw_string_cmd(dhd, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE);\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, edcf_acparam_t *acp)\r
 {\r
@@ -980,25 +932,29 @@ dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp)
        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 size %d\n", __FUNCTION__,\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
-               (int)sizeof(acp)));\r
+               acparam->TXOP));\r
        acparam = &acp[AC_BE];\r
-       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\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
-               (int)sizeof(acp)));\r
+               acparam->TXOP));\r
        acparam = &acp[AC_VI];\r
-       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\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
-               (int)sizeof(acp)));\r
+               acparam->TXOP));\r
        acparam = &acp[AC_VO];\r
-       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\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
-               (int)sizeof(acp)));\r
+               acparam->TXOP));\r
 \r
        return;\r
 }\r
@@ -1006,7 +962,7 @@ dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp)
 void\r
 dhd_conf_update_wme(dhd_pub_t *dhd, edcf_acparam_t *acparam_cur, int aci)\r
 {\r
-       int aifsn, ecwmin, ecwmax;\r
+       int aifsn, ecwmin, ecwmax, txop;\r
        edcf_acparam_t *acp;\r
        struct dhd_conf *conf = dhd->conf;\r
 \r
@@ -1014,32 +970,41 @@ dhd_conf_update_wme(dhd_pub_t *dhd, edcf_acparam_t *acparam_cur, int aci)
        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 (conf->wme.aifsn[aci] > 0)\r
                aifsn = conf->wme.aifsn[aci];\r
-       if (conf->wme.cwmin[aci] > 0)\r
-               ecwmin = conf->wme.cwmin[aci];\r
-       if (conf->wme.cwmax[aci] > 0)\r
-               ecwmax = conf->wme.cwmax[aci];\r
+       if (conf->wme.ecwmin[aci] > 0)\r
+               ecwmin = conf->wme.ecwmin[aci];\r
+       if (conf->wme.ecwmax[aci] > 0)\r
+               ecwmax = conf->wme.ecwmax[aci];\r
+       if (conf->wme.txop[aci] > 0)\r
+               txop = conf->wme.txop[aci];\r
+\r
+       if (!(conf->wme.aifsn[aci] || conf->wme.ecwmin[aci] ||\r
+                       conf->wme.ecwmax[aci] || conf->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
-       CONFIG_TRACE(("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\r
+       printf("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",\r
+               __FUNCTION__,\r
                acp->ACI, acp->ACI&EDCF_AIFSN_MASK,\r
                acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               (int)sizeof(edcf_acparam_t)));\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
-       dhd_conf_set_fw_string_struct_cmd(dhd, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
+       dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE);\r
 \r
 }\r
 \r
@@ -1076,13 +1041,21 @@ dhd_conf_set_wme(dhd_pub_t *dhd)
 void\r
 dhd_conf_add_pkt_filter(dhd_pub_t *dhd)\r
 {\r
-       int i;\r
+       int i, j;\r
        char str[12];\r
 #define MACS "%02x%02x%02x%02x%02x%02x"\r
 \r
        /*\r
-        * All pkt: pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000\r
-        * Netbios pkt: 120 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089\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
@@ -1090,15 +1063,17 @@ dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
        }\r
        dhd->pktfilter_count += i;\r
 \r
-       if (dhd->conf->pkt_filter_magic) {\r
-               strcpy(&dhd->conf->pkt_filter_add.filter[dhd->conf->pkt_filter_add.count][0], "256 0 1 0 0x");\r
-               for (i=0; i<16; i++)\r
-                       strcat(&dhd->conf->pkt_filter_add.filter[dhd->conf->pkt_filter_add.count][0], "FFFFFFFFFFFF");\r
-               strcat(&dhd->conf->pkt_filter_add.filter[dhd->conf->pkt_filter_add.count][0], " 0x");\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 (i=0; i<16; i++)\r
-                       strcat(&dhd->conf->pkt_filter_add.filter[dhd->conf->pkt_filter_add.count][0], str);\r
-               dhd->pktfilter[dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[dhd->conf->pkt_filter_add.count];\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
@@ -1142,19 +1117,12 @@ dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)
        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] = "120 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";\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
-void\r
-dhd_conf_set_disable_proptx(dhd_pub_t *dhd)\r
-{\r
-       printf("%s: set disable_proptx %d\n", __FUNCTION__, dhd->conf->disable_proptx);\r
-       disable_proptx = dhd->conf->disable_proptx;\r
-}\r
-\r
 int\r
 dhd_conf_get_pm(dhd_pub_t *dhd)\r
 {\r
@@ -1163,13 +1131,55 @@ dhd_conf_get_pm(dhd_pub_t *dhd)
        return -1;\r
 }\r
 \r
+#ifdef PROP_TXSTATUS\r
 int\r
-dhd_conf_get_tcpack_sup_mode(dhd_pub_t *dhd)\r
+dhd_conf_get_disable_proptx(dhd_pub_t *dhd)\r
 {\r
-       if (dhd && dhd->conf)\r
-               return dhd->conf->tcpack_sup_mode;\r
-       return -1;\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
 unsigned int\r
 process_config_vars(char *varbuf, unsigned int len, char *pickbuf, char *param)\r
@@ -1305,6 +1315,42 @@ dhd_conf_read_log_level(dhd_pub_t *dhd, char *bufp, uint len)
                MFREE(dhd->osh, pick, MAXSZ_BUF);\r
 }
 
+void\r
+dhd_conf_read_wme_ac_value(dhd_pub_t *dhd, char *pick, uint len, int ac_val)\r
+{\r
+       char *pick_tmp, *pch;\r
+       struct dhd_conf *conf = dhd->conf;\r
+\r
+       /* Process WMM parameters */\r
+       if (len) {\r
+               pick_tmp = pick;\r
+               pch = bcmstrstr(pick_tmp, "aifsn ");\r
+               if (pch) {\r
+                       conf->wme.aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);\r
+                       printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, conf->wme.aifsn[ac_val]);\r
+               }\r
+               pick_tmp = pick;\r
+               pch = bcmstrstr(pick_tmp, "ecwmin ");\r
+               if (pch) {\r
+                       conf->wme.ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);\r
+                       printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, conf->wme.ecwmin[ac_val]);\r
+               }\r
+               pick_tmp = pick;\r
+               pch = bcmstrstr(pick_tmp, "ecwmax ");\r
+               if (pch) {\r
+                       conf->wme.ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);\r
+                       printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, conf->wme.ecwmax[ac_val]);\r
+               }\r
+               pick_tmp = pick;\r
+               pch = bcmstrstr(pick_tmp, "txop ");\r
+               if (pch) {\r
+                       conf->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, conf->wme.txop[ac_val]);\r
+               }\r
+       }\r
+\r
+}\r
+
 void\r
 dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len)\r
 {\r
@@ -1318,6 +1364,8 @@ dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len)
                        __FUNCTION__, MAXSZ_BUF));\r
                return;\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
        memset(pick, 0, MAXSZ_BUF);\r
@@ -1327,90 +1375,28 @@ dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len)
                printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac);\r
        }\r
 \r
-       if (conf->force_wme_ac) {\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bk_aifsn=");\r
-               if (len_val) {\r
-                       conf->wme.aifsn[AC_BK] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_BK aifsn = %d\n", __FUNCTION__, conf->wme.aifsn[AC_BK]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bk_cwmin=");\r
-               if (len_val) {\r
-                       conf->wme.cwmin[AC_BK] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_BK cwmin = %d\n", __FUNCTION__, conf->wme.cwmin[AC_BK]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bk_cwmax=");\r
-               if (len_val) {\r
-                       conf->wme.cwmax[AC_BK] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_BK cwmax = %d\n", __FUNCTION__, conf->wme.cwmax[AC_BK]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "be_aifsn=");\r
-               if (len_val) {\r
-                       conf->wme.aifsn[AC_BE] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_BE aifsn = %d\n", __FUNCTION__, conf->wme.aifsn[AC_BE]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "be_cwmin=");\r
-               if (len_val) {\r
-                       conf->wme.cwmin[AC_BE] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_BE cwmin = %d\n", __FUNCTION__, conf->wme.cwmin[AC_BE]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "be_cwmax=");\r
-               if (len_val) {\r
-                       conf->wme.cwmax[AC_BE] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_BE cwmax = %d\n", __FUNCTION__, conf->wme.cwmax[AC_BE]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "vi_aifsn=");\r
-               if (len_val) {\r
-                       conf->wme.aifsn[AC_VI] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_VI aifsn = %d\n", __FUNCTION__, conf->wme.aifsn[AC_VI]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "vi_cwmin=");\r
-               if (len_val) {\r
-                       conf->wme.cwmin[AC_VI] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_VI cwmin = %d\n", __FUNCTION__, conf->wme.cwmin[AC_VI]);\r
-               }\r
-\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "vi_cwmax=");\r
-               if (len_val) {\r
-                       conf->wme.cwmax[AC_VI] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_VI cwmax = %d\n", __FUNCTION__, conf->wme.cwmax[AC_VI]);\r
-               }\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_be=");\r
+       if (len_val) {\r
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_BE);\r
+       }\r
 \r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "vo_aifsn=");\r
-               if (len_val) {\r
-                       conf->wme.aifsn[AC_VO] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_VO aifsn = %d\n", __FUNCTION__, conf->wme.aifsn[AC_VO]);\r
-               }\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_bk=");\r
+       if (len_val) {\r
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_BK);\r
+       }\r
 \r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "vo_cwmin=");\r
-               if (len_val) {\r
-                       conf->wme.cwmin[AC_VO] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_VO cwmin = %d\n", __FUNCTION__, conf->wme.cwmin[AC_VO]);\r
-               }\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_vi=");\r
+       if (len_val) {\r
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_VI);\r
+       }\r
 \r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "vo_cwmax=");\r
-               if (len_val) {\r
-                       conf->wme.cwmax[AC_VO] = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: AC_VO cwmax = %d\n", __FUNCTION__, conf->wme.cwmax[AC_VO]);\r
-               }\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "wme_ac_sta_vo=");\r
+       if (len_val) {\r
+               dhd_conf_read_wme_ac_value(dhd, pick, len, AC_VO);\r
        }\r
 \r
        if (pick)\r
@@ -1728,6 +1714,54 @@ dhd_conf_read_country_list(dhd_pub_t *dhd, char *bufp, uint len)
                MFREE(dhd->osh, pick, MAXSZ_BUF);\r
 }\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
+void\r
+dhd_conf_read_iapsta(dhd_pub_t *dhd, char *bufp, uint len)\r
+{\r
+       uint len_val;\r
+       char *pick;\r
+       struct dhd_conf *conf = dhd->conf;\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
+               return;\r
+       }\r
+\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "iapsta_init=");\r
+       if (len_val) {\r
+               sprintf(conf->iapsta_init, "iapsta_init %s", pick);\r
+               printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init);\r
+       }\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "iapsta_config=");\r
+       if (len_val) {\r
+               sprintf(conf->iapsta_config, "iapsta_config %s", pick);\r
+               printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config);\r
+       }\r
+       memset(pick, 0, MAXSZ_BUF);\r
+       len_val = process_config_vars(bufp, len, pick, "iapsta_enable=");\r
+       if (len_val) {\r
+               sprintf(conf->iapsta_enable, "iapsta_enable %s", pick);\r
+               printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable);\r
+       }\r
+\r
+       if (pick)\r
+               MFREE(dhd->osh, pick, MAXSZ_BUF);\r
+}\r
+#endif\r
+\r
 int\r
 dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)\r
 {\r
@@ -1783,6 +1817,9 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                dhd_conf_read_nv_by_mac(dhd, bufp, len);\r
                dhd_conf_read_nv_by_chip(dhd, bufp, len);\r
                dhd_conf_read_country_list(dhd, bufp, len);\r
+#ifdef IAPSTA_PREINIT\r
+               dhd_conf_read_iapsta(dhd, bufp, len);\r
+#endif\r
 \r
                /* Process band:\r
                 * band=a for 5GHz only and band=b for 2.4GHz only\r
@@ -1807,6 +1844,22 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap);\r
                }\r
 \r
+               /* Process bw_cap_2g */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "bw_cap_2g=");\r
+               if (len_val) {\r
+                       conf->bw_cap_2g = (uint)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g);\r
+               }\r
+\r
+               /* Process bw_cap_5g */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "bw_cap_5g=");\r
+               if (len_val) {\r
+                       conf->bw_cap_5g = (uint)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: bw_cap_5g = %d\n", __FUNCTION__, conf->bw_cap_5g);\r
+               }\r
+\r
                /* Process country code */\r
                memset(pick, 0, MAXSZ_BUF);\r
                len_val = process_config_vars(bufp, len, pick, "ccode=");\r
@@ -1886,6 +1939,17 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                                dhd_slpauto = TRUE;\r
                        printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);\r
                }\r
+\r
+               /* Process kso_enable parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "kso_enable=");\r
+               if (len_val) {\r
+                       if (!strncmp(pick, "1", len_val))\r
+                               dhd_slpauto = FALSE;\r
+                       else\r
+                               dhd_slpauto = TRUE;\r
+                       printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto);\r
+               }\r
 #endif\r
 \r
                /* Process dhd_master_mode parameters */\r
@@ -1936,6 +2000,23 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                                printf("%d ", conf->pkt_filter_del.id[i]);\r
                        printf("\n");\r
                }\r
+\r
+               /* Process magic_pkt_filter_add=141 0 1 12\r
+                */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "magic_pkt_filter_add=");\r
+               pick_tmp = pick;\r
+               if (len_val) {\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
 #endif\r
 \r
                /* Process srl parameters */\r
@@ -1962,14 +2043,6 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout);\r
                }\r
 \r
-               /* Process bus:txglom */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bus:txglom=");\r
-               if (len_val) {\r
-                       conf->bus_txglom = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);
-               }\r
-\r
                /* Process ampdu_ba_wsize parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
                len_val = process_config_vars(bufp, len, pick, "ampdu_ba_wsize=");\r
@@ -1978,15 +2051,12 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize);\r
                }\r
 \r
-               /* Process kso_enable parameters */\r
+               /* Process ampdu_hostreorder parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "kso_enable=");\r
+               len_val = process_config_vars(bufp, len, pick, "ampdu_hostreorder=");\r
                if (len_val) {\r
-                       if (!strncmp(pick, "0", len_val))\r
-                               conf->kso_enable = FALSE;\r
-                       else\r
-                               conf->kso_enable = TRUE;\r
-                       printf("%s: kso_enable = %d\n", __FUNCTION__, conf->kso_enable);\r
+                       conf->ampdu_hostreorder = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder);\r
                }\r
 \r
                /* Process spect parameters */\r
@@ -2021,6 +2091,15 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc);\r
                }\r
 \r
+#ifdef BCMSDIO\r
+               /* Process bus:txglom */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "bus:txglom=");\r
+               if (len_val) {\r
+                       conf->bus_txglom = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);
+               }\r
+\r
                /* Process use_rxchain parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
                len_val = process_config_vars(bufp, len, pick, "use_rxchain=");\r
@@ -2029,6 +2108,41 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain);\r
                }\r
 \r
+               /* Process dhd_txminmax parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "dhd_txminmax=");\r
+               if (len_val) {
+                       conf->dhd_txminmax = (uint)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax);\r
+               }\r
+\r
+               /* Process txinrx_thres parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "txinrx_thres=");\r
+               if (len_val) {\r
+                       conf->txinrx_thres = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres);\r
+               }\r
+\r
+               /* Process sd_f2_blocksize parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "sd_f2_blocksize=");\r
+               if (len_val) {\r
+                       conf->sd_f2_blocksize = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize);\r
+               }\r
+\r
+               /* Process oob_enabled_later parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "oob_enabled_later=");\r
+               if (len_val) {\r
+                       if (!strncmp(pick, "0", len_val))
+                               conf->oob_enabled_later = FALSE;\r
+                       else
+                               conf->oob_enabled_later = TRUE;\r
+                       printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later);\r
+               }\r
+\r
 #if defined(BCMSDIOH_TXGLOM)
                /* Process txglomsize parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
@@ -2069,6 +2183,78 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        }
                        printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size);
                }
+\r
+               /* Process bus:rxglom parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "bus:rxglom=");\r
+               if (len_val) {\r
+                       if (!strncmp(pick, "0", len_val))\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
+\r
+               /* Process dhd_poll parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "dhd_poll=");\r
+               if (len_val) {\r
+                       if (!strncmp(pick, "0", len_val))\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
+\r
+               /* Process deferred_tx_len parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "deferred_tx_len=");\r
+               if (len_val) {\r
+                       conf->deferred_tx_len = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);\r
+               }\r
+
+               /* Process txctl_tmo_fix parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "txctl_tmo_fix=");
+               if (len_val) {
+                       if (!strncmp(pick, "0", len_val))
+                               conf->txctl_tmo_fix = FALSE;
+                       else
+                               conf->txctl_tmo_fix = TRUE;
+                       printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);
+               }\r
+\r
+               /* Process tx_in_rx parameters */
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "tx_in_rx=");
+               if (len_val) {
+                       if (!strncmp(pick, "0", len_val))
+                               conf->tx_in_rx = FALSE;
+                       else
+                               conf->tx_in_rx = TRUE;
+                       printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);
+               }\r
+\r
+               /* Process tx_max_offset parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "tx_max_offset=");\r
+               if (len_val) {\r
+                       conf->tx_max_offset = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);\r
+               }\r
+
+               /* Process txglom_mode parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "txglom_mode=");\r
+               if (len_val) {
+                       if (!strncmp(pick, "0", len_val))
+                               conf->txglom_mode = FALSE;\r
+                       else
+                               conf->txglom_mode = TRUE;\r
+                       printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);\r
+               }\r
+#endif\r
 #endif\r
 \r
                /* Process disable_proptx parameters */\r
@@ -2087,17 +2273,6 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore);\r
                }\r
 \r
-               /* Process bus:rxglom parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "bus:rxglom=");\r
-               if (len_val) {\r
-                       if (!strncmp(pick, "0", len_val))\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
-\r
                /* Process deepsleep parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
                len_val = process_config_vars(bufp, len, pick, "deepsleep=");\r
@@ -2117,32 +2292,31 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: PM = %d\n", __FUNCTION__, conf->pm);\r
                }\r
 \r
-               /* Process tcpack_sup_mode parameters */\r
+               /* Process pm_in_suspend parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "tcpack_sup_mode=");\r
+               len_val = process_config_vars(bufp, len, pick, "pm_in_suspend=");\r
                if (len_val) {\r
-                       conf->tcpack_sup_mode = (uint)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);\r
+                       conf->pm_in_suspend = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend);\r
                }\r
 \r
-               /* Process dhd_poll parameters */\r
+               /* Process pm2_sleep_ret parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "dhd_poll=");\r
+               len_val = process_config_vars(bufp, len, pick, "pm2_sleep_ret=");\r
                if (len_val) {\r
-                       if (!strncmp(pick, "0", len_val))\r
-                               conf->dhd_poll = 0;\r
-                       else\r
-                               conf->dhd_poll = 1;\r
-                       printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll);\r
+                       conf->pm2_sleep_ret = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret);\r
                }\r
 \r
-               /* Process deferred_tx_len parameters */\r
+#ifdef DHDTCPACK_SUPPRESS\r
+               /* Process tcpack_sup_mode parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "deferred_tx_len=");\r
+               len_val = process_config_vars(bufp, len, pick, "tcpack_sup_mode=");\r
                if (len_val) {\r
-                       conf->deferred_tx_len = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len);\r
+                       conf->tcpack_sup_mode = (uint)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode);\r
                }\r
+#endif\r
 \r
                /* Process pktprio8021x parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
@@ -2152,28 +2326,6 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x);\r
                }
 
-               /* Process txctl_tmo_fix parameters */
-               memset(pick, 0, MAXSZ_BUF);
-               len_val = process_config_vars(bufp, len, pick, "txctl_tmo_fix=");
-               if (len_val) {
-                       if (!strncmp(pick, "0", len_val))
-                               conf->txctl_tmo_fix = FALSE;
-                       else
-                               conf->txctl_tmo_fix = TRUE;
-                       printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix);
-               }
-
-               /* Process tx_in_rx parameters */
-               memset(pick, 0, MAXSZ_BUF);
-               len_val = process_config_vars(bufp, len, pick, "tx_in_rx=");
-               if (len_val) {
-                       if (!strncmp(pick, "0", len_val))
-                               conf->tx_in_rx = FALSE;
-                       else
-                               conf->tx_in_rx = TRUE;
-                       printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx);
-               }
-
                /* Process dhd_txbound parameters */
                memset(pick, 0, MAXSZ_BUF);
                len_val = process_config_vars(bufp, len, pick, "dhd_txbound=");
@@ -2190,14 +2342,6 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound);
                }\r
 \r
-               /* Process tx_max_offset parameters */\r
-               memset(pick, 0, MAXSZ_BUF);\r
-               len_val = process_config_vars(bufp, len, pick, "tx_max_offset=");\r
-               if (len_val) {\r
-                       conf->tx_max_offset = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset);\r
-               }\r
-\r
                /* Process rsdb_mode parameters */\r
                memset(pick, 0, MAXSZ_BUF);\r
                len_val = process_config_vars(bufp, len, pick, "rsdb_mode=");\r
@@ -2206,15 +2350,52 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode);\r
                }\r
 
-               /* Process txglom_mode parameters */\r
+               /* Process vhtmode parameters */\r
                memset(pick, 0, MAXSZ_BUF);
-               len_val = process_config_vars(bufp, len, pick, "txglom_mode=");\r
+               len_val = process_config_vars(bufp, len, pick, "vhtmode=");\r
                if (len_val) {
                        if (!strncmp(pick, "0", len_val))
-                               conf->txglom_mode = FALSE;\r
+                               conf->vhtmode = 0;\r
                        else
-                               conf->txglom_mode = TRUE;\r
-                       printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode);\r
+                               conf->vhtmode = 1;\r
+                       printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode);\r
+               }\r
+\r
+               /* Process num_different_channels parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "num_different_channels=");\r
+               if (len_val) {\r
+                       conf->num_different_channels = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels);\r
+               }\r
+\r
+               /* Process xmit_in_suspend parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "xmit_in_suspend=");\r
+               if (len_val) {\r
+                       if (!strncmp(pick, "1", len_val))\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
+\r
+#ifdef IDHCPC\r
+               /* Process dhcpc_enable parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "dhcpc_enable=");\r
+               if (len_val) {\r
+                       conf->dhcpc_enable = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable);\r
+               }\r
+#endif\r
+\r
+               /* Process tsq parameters */\r
+               memset(pick, 0, MAXSZ_BUF);
+               len_val = process_config_vars(bufp, len, pick, "tsq=");\r
+               if (len_val) {\r
+                       conf->tsq = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq);\r
                }\r
 \r
                bcmerror = 0;\r
@@ -2265,6 +2446,7 @@ dhd_conf_get_chiprev(void *context)
        return 0;\r
 }\r
 \r
+#ifdef BCMSDIO\r
 void\r
 dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)\r
 {\r
@@ -2282,26 +2464,32 @@ dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)
                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->tx_in_rx = TRUE;\r
-               conf->tx_max_offset = 0;\r
                conf->txglomsize = 0;\r
                conf->deferred_tx_len = 0;\r
        }\r
-       printf("%s: swtxglom=%d, txglom_ext=%d\n", __FUNCTION__,\r
-               conf->swtxglom, conf->txglom_ext);\r
-       printf("%s: txglom_bucket_size=%d\n", __FUNCTION__, conf->txglom_bucket_size);\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, tx_max_offset=%d\n", __FUNCTION__,\r
-               conf->tx_in_rx, conf->tx_max_offset);\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
@@ -2318,6 +2506,8 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        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
@@ -2367,77 +2557,75 @@ dhd_conf_preinit(dhd_pub_t *dhd)
 #ifdef PKT_FILTER_SUPPORT\r
        memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));\r
        memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));\r
-       conf->pkt_filter_magic = FALSE;\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->kso_enable = TRUE;\r
        conf->spect = -1;\r
        conf->txbf = -1;\r
        conf->lpc = -1;\r
-       conf->disable_proptx = 0;\r
-       conf->bus_txglom = 0;\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->deferred_tx_len = 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_CPY;\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->dpc_cpucore = 0;\r
+       conf->ampdu_hostreorder = -1;\r
+       conf->dpc_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
 #ifdef DHDTCPACK_SUPPRESS
        conf->tcpack_sup_mode = TCPACK_SUP_OFF;\r
 #endif\r
-       conf->dhd_poll = -1;\r
-       conf->pktprio8021x = -1;
-       conf->txctl_tmo_fix = FALSE;
-       conf->tx_in_rx = TRUE;\r
+       conf->pktprio8021x = -1;\r
        conf->rsdb_mode = -2;\r
-       conf->txglom_mode = SDPCM_TXGLOM_CPY;
-       if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) {\r
-               conf->disable_proptx = 1;\r
-               conf->use_rxchain = 0;\r
-       }
-       if (conf->chip == BCM4354_CHIP_ID) {
-               conf->disable_proptx = 1;
-       }
-       if (conf->chip == BCM43430_CHIP_ID) {\r
-               conf->bus_rxglom = FALSE;\r
-               conf->use_rxchain = 0;\r
-       }
-       if (conf->chip == BCM4339_CHIP_ID) {\r
-               conf->txbf = 1;\r
-       }\r
-       if (conf->chip == BCM4345_CHIP_ID) {\r
-               conf->txbf = 1;\r
-       }\r
-       if (conf->chip == BCM4354_CHIP_ID) {\r
-               conf->txbf = 1;\r
-       }\r
-       if (conf->chip == BCM4356_CHIP_ID) {\r
-               conf->txbf = 1;\r
-       }\r
-       if (conf->chip == BCM4371_CHIP_ID) {\r
-               conf->txbf = 1;\r
-       }\r
-       if (conf->chip == BCM4359_CHIP_ID) {\r
-               conf->txbf = 1;\r
-               conf->rsdb_mode = 0;\r
-       }\r
+       conf->vhtmode = -1;\r
 #ifdef BCMSDIO\r
-       if (conf->chip == BCM4356_CHIP_ID) {\r
-               conf->txbf = 1;\r
+       if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) {\r
+               conf->txctl_tmo_fix = 1;\r
        }\r
-#elif defined(BCMPCIE)\r
-       if (conf->chip == BCM4356_CHIP_ID) {\r
+#endif\r
+       if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID ||\r
+                       conf->chip == BCM4371_CHIP_ID || 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
-       }\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
@@ -2478,7 +2666,6 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        }\r
 #endif\r
 #if defined(BCMSDIOH_TXGLOM_EXT)\r
-       conf->txglom_mode = SDPCM_TXGLOM_CPY;\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
@@ -2502,6 +2689,7 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        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
index dfd205d5f44d1b4232c18f9721bacf93eb9a5670..ae453cd975bd0ddf8e26ec5598a199cbd342c890 100755 (executable)
 #define FW_PATH_AUTO_SELECT 1\r
 //#define CONFIG_PATH_AUTO_SELECT\r
 extern char firmware_path[MOD_PARAM_PATHLEN];\r
-extern int disable_proptx;\r
 extern uint dhd_rxbound;
 extern uint dhd_txbound;
-#define TXGLOM_RECV_OFFSET 8
 #ifdef BCMSDIO\r
+#define TXGLOM_RECV_OFFSET 8\r
 extern uint dhd_doflow;\r
 extern uint dhd_slpauto;\r
 \r
@@ -23,6 +22,7 @@ extern uint dhd_slpauto;
 #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 BCM4330B2_CHIP_REV      4\r
 #define BCM4334B1_CHIP_REV      3\r
 #define BCM43341B0_CHIP_REV     2\r
@@ -32,6 +32,7 @@ extern uint dhd_slpauto;
 #define BCM43455C0_CHIP_REV     6\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
 \r
@@ -78,8 +79,9 @@ typedef struct wl_channel_list {
 \r
 typedef struct wmes_param {\r
        int aifsn[AC_COUNT];\r
-       int cwmin[AC_COUNT];\r
-       int cwmax[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
@@ -118,6 +120,8 @@ typedef struct dhd_conf {
        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
@@ -134,41 +138,71 @@ typedef struct dhd_conf {
 #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
-       bool pkt_filter_magic;\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
-       bool kso_enable;\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
+       bool bus_rxglom; /* bus:rxglom */\r
+       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 ampdu_ba_wsize;\r
-       int dpc_cpucore;\r
-       int frameburst;\r
-       bool deepsleep;\r
-       int pm;\r
-       uint8 tcpack_sup_mode;\r
        int dhd_poll;\r
-       uint deferred_tx_len;\r
-       int pktprio8021x;\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 swtxglom; /* SW TXGLOM */\r
-       bool txglom_ext; /* Only for 43362/4330/43340/43341/43241 */
+       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 */
        /*txglom_bucket_size:
         * 43362/4330: 1680
         * 43340/43341/43241: 1684
         */
        int txglom_bucket_size;
-       int tx_max_offset;\r
-       bool tx_in_rx; // Skip tx before rx, in order to get more glomed in tx\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 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
-       bool txglom_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 tsq;\r
 } dhd_conf_t;\r
 \r
 #ifdef BCMSDIO\r
@@ -178,6 +212,7 @@ void dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_pa
 #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, char *nv_path);
 void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path);\r
@@ -185,8 +220,8 @@ void dhd_conf_set_conf_path_by_nv_path(dhd_pub_t *dhd, char *conf_path, char *nv
 #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_fw_int_cmd(dhd_pub_t *dhd, char *name, uint cmd, int val, int def, bool down);\r
-int dhd_conf_set_fw_string_cmd(dhd_pub_t *dhd, char *cmd, int val, int def, bool down);\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
@@ -194,23 +229,24 @@ int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec);
 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_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp);\r
 void dhd_conf_set_wme(dhd_pub_t *dhd);\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
-void dhd_conf_set_disable_proptx(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
-void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable);\r
 int dhd_conf_get_pm(dhd_pub_t *dhd);\r
-int dhd_conf_get_tcpack_sup_mode(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
-\r
+void *dhd_get_conf(struct net_device *dev);\r
 #endif /* _dhd_config_ */\r
index d17890ca710aa30f084972fd5902822ba833ef70..cbe4af515c4dba28a9e66abb5becee19db870ce2 100755 (executable)
@@ -256,11 +256,12 @@ const struct cntry_locales_custom translate_custom_table[] = {
 *  input : ISO 3166-1 country abbreviation
 *  output: customized cspec
 */
+void
 #ifdef CUSTOM_COUNTRY_CODE
-void get_customized_country_code(void *adapter, char *country_iso_code,
 wl_country_t *cspec, u32 flags)
+get_customized_country_code(void *adapter, char *country_iso_code,
+ wl_country_t *cspec, u32 flags)
 #else
-void get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec)
+get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec)
 #endif /* CUSTOM_COUNTRY_CODE */
 {
 #if (defined(CUSTOMER_HW) || defined(CUSTOMER_HW2)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
index aee9c968530eb22237ec5e70c0b3b1f38e5dc507..d049e497f0f70f2711054ed770e5f78bcbc67654 100755 (executable)
 
 #include <osl.h>
 #include <dhd_linux.h>
+#include <linux/gpio.h>
 #include <linux/rfkill-wlan.h>
 
-#ifdef CONFIG_MACH_ODROID_4210
-#include <mach/gpio.h>
-#include <mach/regs-gpio.h>
-#include <plat/gpio-cfg.h>
+#ifdef CUSTOMER_HW_PLATFORM
 #include <plat/sdhci.h>
-#include <plat/devs.h>
-#define        sdmmc_channel   s3c_device_hsmmc0
-#endif
-
-struct wifi_platform_data dhd_wlan_control = {0};
-
-#ifdef CUSTOMER_OOB
-uint bcm_wlan_get_oob_irq(void)
-{
-       uint host_oob_irq = 0;
-
-       host_oob_irq = rockchip_wifi_get_oob_irq();
-
-       printk("host_oob_irq: %d\n", host_oob_irq);
-
-       return host_oob_irq;
-}
+#define        sdmmc_channel   sdmmc_device_mmc0
+#endif /* CUSTOMER_HW_PLATFORM */
 
-uint bcm_wlan_get_oob_irq_flags(void)
-{
-       uint host_oob_irq_flags = 0;
+#if defined(BUS_POWER_RESTORE) && defined(BCMSDIO)
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#endif /* defined(BUS_POWER_RESTORE) && defined(BCMSDIO) */
 
-       host_oob_irq_flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE) & IRQF_TRIGGER_MASK;
-       printk("host_oob_irq_flags=0x%X\n", host_oob_irq_flags);
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
 
-       return host_oob_irq_flags;
-}
+static int gpio_wl_reg_on = -1; // WL_REG_ON is input pin of WLAN module
+#ifdef CUSTOMER_OOB
+static int gpio_wl_host_wake = -1; // WL_HOST_WAKE is output pin of WLAN module
 #endif
 
-int bcm_wlan_set_power(bool on)
+static int
+dhd_wlan_set_power(bool on
+#ifdef BUS_POWER_RESTORE
+, wifi_adapter_info_t *adapter
+#endif /* BUS_POWER_RESTORE */
+)
 {
        int err = 0;
 
        if (on) {
-               printk("======== PULL WL_REG_ON HIGH! ========\n");
+               printf("======== PULL WL_REG_ON(%d) HIGH! ========\n", gpio_wl_reg_on);
+               if (gpio_wl_reg_on >= 0) {
+                       err = gpio_direction_output(gpio_wl_reg_on, 1);
+                       if (err) {
+                               printf("%s: WL_REG_ON didn't output high\n", __FUNCTION__);
+                               return -EIO;
+                       }
+               }
                rockchip_wifi_power(1);
+#if defined(BUS_POWER_RESTORE)
+#if defined(BCMSDIO)
+               if (adapter->sdio_func && adapter->sdio_func->card && adapter->sdio_func->card->host) {
+                       printf("======== mmc_power_restore_host! ========\n");
+                       mmc_power_restore_host(adapter->sdio_func->card->host);
+               }
+#elif defined(BCMPCIE)
+               OSL_SLEEP(50); /* delay needed to be able to restore PCIe configuration registers */
+               if (adapter->pci_dev) {
+                       printf("======== pci_set_power_state PCI_D0! ========\n");
+                       pci_set_power_state(adapter->pci_dev, PCI_D0);
+                       if (adapter->pci_saved_state)
+                               pci_load_and_free_saved_state(adapter->pci_dev, &adapter->pci_saved_state);
+                       pci_restore_state(adapter->pci_dev);
+                       err = pci_enable_device(adapter->pci_dev);
+                       if (err < 0)
+                               printf("%s: PCI enable device failed", __FUNCTION__);
+                       pci_set_master(adapter->pci_dev);
+               }
+#endif /* BCMPCIE */
+#endif /* BUS_POWER_RESTORE */
        } else {
-               printk("======== PULL WL_REG_ON LOW! ========\n");
+#if defined(BUS_POWER_RESTORE)
+#if defined(BCMSDIO)
+               if (adapter->sdio_func && adapter->sdio_func->card && adapter->sdio_func->card->host) {
+                       printf("======== mmc_power_save_host! ========\n");
+                       mmc_power_save_host(adapter->sdio_func->card->host);
+               }
+#elif defined(BCMPCIE)
+               if (adapter->pci_dev) {
+                       printf("======== pci_set_power_state PCI_D3hot! ========\n");
+                       pci_save_state(adapter->pci_dev);
+                       adapter->pci_saved_state = pci_store_saved_state(adapter->pci_dev);
+                       if (pci_is_enabled(adapter->pci_dev))
+                               pci_disable_device(adapter->pci_dev);
+                       pci_set_power_state(adapter->pci_dev, PCI_D3hot);
+               }
+#endif /* BCMPCIE */
+#endif /* BUS_POWER_RESTORE */
+               printf("======== PULL WL_REG_ON(%d) LOW! ========\n", gpio_wl_reg_on);
+               if (gpio_wl_reg_on >= 0) {
+                       err = gpio_direction_output(gpio_wl_reg_on, 0);
+                       if (err) {
+                               printf("%s: WL_REG_ON didn't output low\n", __FUNCTION__);
+                               return -EIO;
+                       }
+               }
                rockchip_wifi_power(0);
        }
 
        return err;
 }
 
-int bcm_wlan_set_carddetect(bool present)
+static int dhd_wlan_set_reset(int onoff)
+{
+       return 0;
+}
+
+static int dhd_wlan_set_carddetect(bool present)
 {
        int err = 0;
 
+#if !defined(BUS_POWER_RESTORE)
        if (present) {
-               printk("======== Card detection to detect SDIO card! ========\n");
-               rockchip_wifi_set_carddetect(1);
+#if defined(BCMSDIO)
+               printf("======== Card detection to detect SDIO card! ========\n");
+#ifdef CUSTOMER_HW_PLATFORM
+               err = sdhci_force_presence_change(&sdmmc_channel, 1);
+#endif /* CUSTOMER_HW_PLATFORM */
+               rockchip_wifi_set_carddetect(1);
+#elif defined(BCMPCIE)
+               printf("======== Card detection to detect PCIE card! ========\n");
+#endif
        } else {
-               printk("======== Card detection to remove SDIO card! ========\n");
-               rockchip_wifi_set_carddetect(0);
+#if defined(BCMSDIO)
+               printf("======== Card detection to remove SDIO card! ========\n");
+#ifdef CUSTOMER_HW_PLATFORM
+               err = sdhci_force_presence_change(&sdmmc_channel, 0);
+#endif /* CUSTOMER_HW_PLATFORM */
+       rockchip_wifi_set_carddetect(0);
+#elif defined(BCMPCIE)
+               printf("======== Card detection to remove PCIE card! ========\n");
+#endif
        }
+#endif /* BUS_POWER_RESTORE */
 
        return err;
 }
 
-int bcm_wlan_get_mac_address(unsigned char *buf)
+static int dhd_wlan_get_mac_addr(unsigned char *buf)
 {
        int err = 0;
 
-       printk("======== %s ========\n", __FUNCTION__);
+       printf("======== %s ========\n", __FUNCTION__);
 #ifdef EXAMPLE_GET_MAC
        /* EXAMPLE code */
        {
@@ -84,23 +150,6 @@ int bcm_wlan_get_mac_address(unsigned char *buf)
        return err;
 }
 
-#ifdef CONFIG_DHD_USE_STATIC_BUF
-extern void *bcmdhd_mem_prealloc(int section, unsigned long size);
-void* bcm_wlan_prealloc(int section, unsigned long size)
-{
-       void *alloc_ptr = NULL;
-       alloc_ptr = bcmdhd_mem_prealloc(section, size);
-       if (alloc_ptr) {
-               printf("success alloc section %d, size %ld\n", section, size);
-               if (size != 0L)
-                       bzero(alloc_ptr, size);
-               return alloc_ptr;
-       }
-       printf("can't alloc section %d\n", section);
-       return NULL;
-}
-#endif
-
 #if !defined(WL_WIRELESS_EXT)
 struct cntry_locales_custom {
        char iso_abbrev[WLC_CNTRY_BUF_SZ];      /* ISO 3166-1 country abbreviation */
@@ -122,7 +171,7 @@ struct cntry_locales_custom brcm_wlan_translate_nodfs_table[] = {
 };
 #endif
 
-static void *bcm_wlan_get_country_code(char *ccode
+static void *dhd_wlan_get_country_code(char *ccode
 #ifdef CUSTOM_FORCE_NODFS_FLAG
        , u32 flags
 #endif
@@ -153,15 +202,123 @@ static void *bcm_wlan_get_country_code(char *ccode
        return NULL;
 }
 
-int bcm_wlan_set_plat_data(void) {
-       printf("======== %s ========\n", __FUNCTION__);
-       dhd_wlan_control.set_power = bcm_wlan_set_power;
-       dhd_wlan_control.set_carddetect = bcm_wlan_set_carddetect;
-       dhd_wlan_control.get_mac_addr = bcm_wlan_get_mac_address;
+struct resource dhd_wlan_resources[] = {
+       [0] = {
+               .name   = "bcmdhd_wlan_irq",
+               .start  = 0, /* Dummy */
+               .end    = 0, /* Dummy */
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE
+                       | IORESOURCE_IRQ_HIGHLEVEL, /* Dummy */
+       },
+};
+
+struct wifi_platform_data dhd_wlan_control = {
+       .set_power      = dhd_wlan_set_power,
+       .set_reset      = dhd_wlan_set_reset,
+       .set_carddetect = dhd_wlan_set_carddetect,
+       .get_mac_addr   = dhd_wlan_get_mac_addr,
 #ifdef CONFIG_DHD_USE_STATIC_BUF
-       dhd_wlan_control.mem_prealloc = bcm_wlan_prealloc;
+       .mem_prealloc   = dhd_wlan_mem_prealloc,
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+       .get_country_code = dhd_wlan_get_country_code,
+};
+
+int dhd_wlan_init_gpio(void)
+{
+       int err = 0;
+#ifdef CUSTOMER_OOB
+       int host_oob_irq = -1;
+       uint host_oob_irq_flags = 0;
+#endif
+
+       /* Please check your schematic and fill right GPIO number which connected to
+       * WL_REG_ON and WL_HOST_WAKE.
+       */
+       gpio_wl_reg_on = -1;
+#ifdef CUSTOMER_OOB
+       gpio_wl_host_wake = -1;
+#endif
+
+       printf("%s: GPIO(WL_REG_ON) = %d\n", __FUNCTION__, gpio_wl_reg_on);
+       if (gpio_wl_reg_on >= 0) {
+               err = gpio_request(gpio_wl_reg_on, "WL_REG_ON");
+               if (err < 0) {
+                       printf("%s: Faiiled to request gpio %d for WL_REG_ON\n",
+                               __FUNCTION__, gpio_wl_reg_on);
+                       gpio_wl_reg_on = -1;
+               }
+       }
+
+#ifdef CUSTOMER_OOB
+       printf("%s: GPIO(WL_HOST_WAKE) = %d\n", __FUNCTION__, gpio_wl_host_wake);
+       if (gpio_wl_host_wake >= 0) {
+               err = gpio_request(gpio_wl_host_wake, "bcmdhd");
+               if (err < 0) {
+                       printf("%s: gpio_request failed\n", __FUNCTION__);
+                       return -1;
+               }
+               err = gpio_direction_input(gpio_wl_host_wake);
+               if (err < 0) {
+                       printf("%s: gpio_direction_input failed\n", __FUNCTION__);
+                       gpio_free(gpio_wl_host_wake);
+                       return -1;
+               }
+               host_oob_irq = gpio_to_irq(gpio_wl_host_wake);
+               if (host_oob_irq < 0) {
+                       printf("%s: gpio_to_irq failed\n", __FUNCTION__);
+                       gpio_free(gpio_wl_host_wake);
+                       return -1;
+               }
+       }
+       host_oob_irq = rockchip_wifi_get_oob_irq();
+       printf("%s: host_oob_irq: %d\n", __FUNCTION__, host_oob_irq);
+
+#ifdef HW_OOB
+#ifdef HW_OOB_LOW_LEVEL
+       host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#else
+       host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#endif
+#else
+       host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
 #endif
-       dhd_wlan_control.get_country_code = bcm_wlan_get_country_code;
+
+       dhd_wlan_resources[0].start = dhd_wlan_resources[0].end = host_oob_irq;
+       dhd_wlan_resources[0].flags = host_oob_irq_flags;
+       printf("%s: host_oob_irq_flags=0x%x\n", __FUNCTION__, host_oob_irq_flags);
+#endif /* CUSTOMER_OOB */
+
        return 0;
 }
 
+static void dhd_wlan_deinit_gpio(void)
+{
+       if (gpio_wl_reg_on >= 0) {
+               printf("%s: gpio_free(WL_REG_ON %d)\n", __FUNCTION__, gpio_wl_reg_on);
+               gpio_free(gpio_wl_reg_on);
+               gpio_wl_reg_on = -1;
+       }
+#ifdef CUSTOMER_OOB
+       if (gpio_wl_host_wake >= 0) {
+               printf("%s: gpio_free(WL_HOST_WAKE %d)\n", __FUNCTION__, gpio_wl_host_wake);
+               gpio_free(gpio_wl_host_wake);
+               gpio_wl_host_wake = -1;
+       }
+#endif /* CUSTOMER_OOB */
+}
+
+int dhd_wlan_init_plat_data(void)
+{
+       int err = 0;
+
+       printf("======== %s ========\n", __FUNCTION__);
+       err = dhd_wlan_init_gpio();
+       return err;
+}
+
+void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter)
+{
+       printf("======== %s ========\n", __FUNCTION__);
+       dhd_wlan_deinit_gpio();
+}
+
index 9daa6e2c76a11cd61310493154c6857528f05fe0..7e75bb8acba7fcf2e56817a11a075d5bd74d9c96 100644 (file)
@@ -295,10 +295,8 @@ extern bool dhd_wlfc_skip_fc(void);
 extern void dhd_wlfc_plat_init(void *dhd);
 extern void dhd_wlfc_plat_deinit(void *dhd);
 #endif /* PROP_TXSTATUS */
-#ifdef USE_DYNAMIC_F2_BLKSIZE
 extern uint sd_f2_blocksize;
 extern int dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size);
-#endif /* USE_DYNAMIC_F2_BLKSIZE */
 
 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 15)
 const char *
@@ -2480,7 +2478,8 @@ int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost)
        return 0;
 }
 
-#if defined(PKT_FILTER_SUPPORT) && !defined(GAN_LITE_NAT_KEEPALIVE_FILTER)
+// terence 20160615: fix building error if ARP_OFFLOAD_SUPPORT removed
+#if defined(PKT_FILTER_SUPPORT) &&defined(ARP_OFFLOAD_SUPPORT) && !defined(GAN_LITE_NAT_KEEPALIVE_FILTER)
 static bool
 _turn_on_arp_filter(dhd_pub_t *dhd, int op_mode)
 {
@@ -2533,7 +2532,8 @@ void dhd_enable_packet_filter(int value, dhd_pub_t *dhd)
            (dhd_support_sta_mode(dhd) && !dhd->dhcp_in_progress)))
        {
                for (i = 0; i < dhd->pktfilter_count; i++) {
-#ifndef GAN_LITE_NAT_KEEPALIVE_FILTER
+// terence 20160615: fix building error if ARP_OFFLOAD_SUPPORT removed
+#if defined(ARP_OFFLOAD_SUPPORT) && !defined(GAN_LITE_NAT_KEEPALIVE_FILTER)
                        if (value && (i == DHD_ARP_FILTER_NUM) &&
                                !_turn_on_arp_filter(dhd, dhd->op_mode)) {
                                DHD_TRACE(("Do not turn on ARP white list pkt filter:"
@@ -2551,9 +2551,7 @@ void dhd_enable_packet_filter(int value, dhd_pub_t *dhd)
 
 static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 {
-#ifndef SUPPORT_PM2_ONLY
        int power_mode = PM_MAX;
-#endif /* SUPPORT_PM2_ONLY */
 #ifdef SUPPORT_SENSORHUB
        uint32 shub_msreq;
 #endif /* SUPPORT_SENSORHUB */
@@ -2605,10 +2603,11 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
        /* set specific cpucore */
        dhd_set_cpucore(dhd, TRUE);
 #endif /* CUSTOM_SET_CPUCORE */
-#ifndef SUPPORT_PM2_ONLY
+
        if (dhd->conf->pm >= 0)
                power_mode = dhd->conf->pm;
-#endif /* SUPPORT_PM2_ONLY */
+       else
+               power_mode = PM_FAST;
        if (dhd->up) {
                if (value && dhd->in_suspend) {
 #ifdef PKT_FILTER_SUPPORT
@@ -2630,10 +2629,10 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                        }
 #endif /* SUPPORT_SENSORHUB */
 
-#ifndef SUPPORT_PM2_ONLY
+                       if (dhd->conf->pm_in_suspend >= 0)
+                               power_mode = dhd->conf->pm_in_suspend;
                        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
                                sizeof(power_mode), TRUE, 0);
-#endif /* SUPPORT_PM2_ONLY */
 
 #ifdef PKT_FILTER_SUPPORT
                        /* Enable packet filter,
@@ -2744,11 +2743,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                DHD_ERROR(("failed to set intr_width (%d)\n", ret));
                        }
 #endif /* DYNAMIC_SWOOB_DURATION */
-#ifndef SUPPORT_PM2_ONLY
-                       power_mode = PM_FAST;
                        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
                                sizeof(power_mode), TRUE, 0);
-#endif /* SUPPORT_PM2_ONLY */
 #ifdef PKT_FILTER_SUPPORT
                        /* disable pkt filter */
                        dhd_enable_packet_filter(0, dhd);
@@ -2804,6 +2800,11 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                                ret));
                        }
 #endif /* DHD_USE_EARLYSUSPEND */
+
+                       /* terence 2017029: Reject in early suspend */
+                       if (!dhd->conf->xmit_in_suspend) {
+                               dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+                       }
                }
        }
        dhd_suspend_unlock(dhd);
@@ -3370,6 +3371,10 @@ dhd_set_mac_addr_handler(void *handle, void *event_info, u8 event)
        }
 #endif /* SOFTAP */
 
+       // terence 20160907: fix for not able to set mac when wlan0 is down
+       if (ifp == NULL || !ifp->set_macaddress) {
+               goto done;
+       }
        if (ifp == NULL || !dhd->pub.up) {
                DHD_ERROR(("%s: interface info not available/down \n", __FUNCTION__));
                goto done;
@@ -3481,6 +3486,10 @@ dhd_set_multicast_list(struct net_device *dev)
        dhd->iflist[ifidx]->set_multicast = TRUE;
        dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)dhd->iflist[ifidx],
                DHD_WQ_WORK_SET_MCAST_LIST, dhd_set_mcast_list_handler, DHD_WORK_PRIORITY_LOW);
+
+       // terence 20160907: fix for not able to set mac when wlan0 is down
+       dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)dhd->iflist[ifidx],
+               DHD_WQ_WORK_SET_MAC, dhd_set_mac_addr_handler, DHD_WORK_PRIORITY_LOW);
 }
 
 #ifdef PROP_TXSTATUS
@@ -3489,6 +3498,9 @@ dhd_os_wlfc_block(dhd_pub_t *pub)
 {
        dhd_info_t *di = (dhd_info_t *)(pub->info);
        ASSERT(di != NULL);
+       /* terence 20161229: don't do spin lock if proptx not enabled */
+       if (disable_proptx)
+               return 1;
        spin_lock_bh(&di->wlfc_spinlock);
        return 1;
 }
@@ -3499,6 +3511,9 @@ dhd_os_wlfc_unblock(dhd_pub_t *pub)
        dhd_info_t *di = (dhd_info_t *)(pub->info);
 
        ASSERT(di != NULL);
+       /* terence 20161229: don't do spin lock if proptx not enabled */
+       if (disable_proptx)
+               return 1;
        spin_unlock_bh(&di->wlfc_spinlock);
        return 1;
 }
@@ -3909,6 +3924,16 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
+       /* terence 2017029: Reject in early suspend */
+       if (!dhd->pub.conf->xmit_in_suspend && dhd->pub.early_suspended) {
+               dhd_txflowcontrol(&dhd->pub, ALL_INTERFACES, ON);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
+               return -ENODEV;
+#else
+               return NETDEV_TX_BUSY;
+#endif
+       }
+
 
 #ifdef PCIE_FULL_DONGLE
        DHD_GENERAL_LOCK(&dhd->pub, flags);
@@ -3967,10 +3992,10 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
 #ifdef PCIE_FULL_DONGLE
                dhd->pub.dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_TX;
                dhd_os_busbusy_wake(&dhd->pub);
-               DHD_GENERAL_UNLOCK(&dhd->pub, flags);
 #endif /* PCIE_FULL_DONGLE */
                DHD_PERIM_UNLOCK_TRY(DHD_FWDER_UNIT(dhd), lock_taken);
                DHD_OS_WAKE_UNLOCK(&dhd->pub);
+               DHD_GENERAL_UNLOCK(&dhd->pub, flags);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
                return -ENODEV;
 #else
@@ -3988,10 +4013,10 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
 #ifdef PCIE_FULL_DONGLE
                dhd->pub.dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_TX;
                dhd_os_busbusy_wake(&dhd->pub);
-               DHD_GENERAL_UNLOCK(&dhd->pub, flags);
 #endif /* PCIE_FULL_DONGLE */
                DHD_PERIM_UNLOCK_TRY(DHD_FWDER_UNIT(dhd), lock_taken);
                DHD_OS_WAKE_UNLOCK(&dhd->pub);
+               DHD_GENERAL_UNLOCK(&dhd->pub, flags);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
                return -ENODEV;
 #else
@@ -5710,7 +5735,12 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
        memset(&ioc, 0, sizeof(ioc));
 
 #ifdef CONFIG_COMPAT
-       if (is_compat_task()) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
+       if (in_compat_syscall())
+#else
+       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;
@@ -6015,7 +6045,10 @@ dhd_stop(struct net_device *net)
 #endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
                                dhd_net_if_unlock_local(dhd);
                        }
+#if 0
+                       // terence 20161024: remove this to prevent dev_close() get stuck in dhd_hang_process
                        cancel_work_sync(dhd->dhd_deferred_wq);
+#endif
 #if defined(DHD_LB) && defined(DHD_LB_RXP)
                        __skb_queue_purge(&dhd->rx_pend_queue);
 #endif /* DHD_LB && DHD_LB_RXP */
@@ -6046,9 +6079,12 @@ dhd_stop(struct net_device *net)
 
        OLD_MOD_DEC_USE_COUNT;
 exit:
-       if (ifidx == 0 && !dhd_download_fw_on_driverload)
+       if (ifidx == 0 && !dhd_download_fw_on_driverload) {
                wl_android_wifi_off(net, TRUE);
-       else {
+#ifdef WL_EXT_IAPSTA
+               wl_android_ext_dettach_netdev();
+#endif
+       } else {
                if (dhd->pub.conf->deepsleep)
                        dhd_deepsleep(dhd, 1);
        }
@@ -6637,7 +6673,7 @@ dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock)
                dhd_if_del_sta_list(ifp);
 
                MFREE(dhdinfo->pub.osh, ifp, sizeof(*ifp));
-
+               ifp = NULL;
        }
 
        return BCME_OK;
@@ -7206,6 +7242,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        DHD_OS_WAKE_LOCK_INIT(dhd);
        dhd->wakelock_wd_counter = 0;
 #ifdef CONFIG_HAS_WAKELOCK
+       // terence 20161023: can not destroy wl_wifi when wlan down, it will happen null pointer in dhd_ioctl_entry
+       wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
        wake_lock_init(&dhd->wl_wdwake, WAKE_LOCK_SUSPEND, "wlan_wd_wake");
 #endif /* CONFIG_HAS_WAKELOCK */
 
@@ -8240,7 +8278,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd->suspend_bcn_li_dtim = CUSTOM_SUSPEND_BCN_LI_DTIM;
        DHD_TRACE(("Enter %s\n", __FUNCTION__));
 
-       dhd_conf_set_fw_int_cmd(dhd, "WLC_SET_BAND", WLC_SET_BAND, dhd->conf->band, 0, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_BAND, "WLC_SET_BAND", dhd->conf->band, 0, FALSE);
 #ifdef DHDTCPACK_SUPPRESS
        printf("%s: Set tcpack_sup_mode %d\n", __FUNCTION__, dhd->conf->tcpack_sup_mode);
        dhd_tcpack_suppress_set(dhd, dhd->conf->tcpack_sup_mode);
@@ -8281,27 +8319,20 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                if (ret < 0) {
                        DHD_ERROR(("%s: can't set MAC address MAC="MACDBG", error=%d\n",
                                __FUNCTION__, MAC2STRDBG(ea_addr.octet), ret));
-                       ret = BCME_NOTUP;
-                       goto done;
                }
-               memcpy(dhd->mac.octet, ea_addr.octet, ETHER_ADDR_LEN);
-       } else {
-#endif /* GET_CUSTOM_MAC_ENABLE */
-               /* Get the default device MAC address directly from firmware */
-               memset(buf, 0, sizeof(buf));
-               bcm_mkiovar("cur_etheraddr", 0, 0, buf, sizeof(buf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
-                       FALSE, 0)) < 0) {
-                       DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
-                       ret = BCME_NOTUP;
-                       goto done;
-               }
-               /* Update public MAC address after reading from Firmware */
-               memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
-
-#ifdef GET_CUSTOM_MAC_ENABLE
        }
 #endif /* GET_CUSTOM_MAC_ENABLE */
+       /* Get the default device MAC address directly from firmware */
+       memset(buf, 0, sizeof(buf));
+       bcm_mkiovar("cur_etheraddr", 0, 0, buf, sizeof(buf));
+       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
+               FALSE, 0)) < 0) {
+               DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
+               ret = BCME_NOTUP;
+               goto done;
+       }
+       /* Update public MAC address after reading from Firmware */
+       memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
 
        /* get a capabilities from firmware */
        {
@@ -8448,6 +8479,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                (void)concurrent_mode;
 #endif 
        }
+       if (dhd->conf->sd_f2_blocksize)
+               dhdsdio_func_blocksize(dhd, 2, dhd->conf->sd_f2_blocksize);
 
 #ifdef RSDB_MODE_FROM_FILE
        (void)dhd_rsdb_mode_from_file(dhd);
@@ -8565,12 +8598,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                }
        }
 #endif /* DHD_ENABLE_LPC */
-       dhd_conf_set_fw_string_cmd(dhd, "lpc", dhd->conf->lpc, 0, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "lpc", dhd->conf->lpc, 0, FALSE);
 
        /* Set PowerSave mode */
        if (dhd->conf->pm >= 0)
                power_mode = dhd->conf->pm;
        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "pm2_sleep_ret", dhd->conf->pm2_sleep_ret, 0, FALSE);
 
 #if defined(BCMSDIO)
        /* Match Host and Dongle rx alignment */
@@ -8609,14 +8643,19 @@ 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_fw_string_cmd(dhd, "mimo_bw_cap", dhd->conf->mimo_bw_cap, 1, TRUE);
-       dhd_conf_set_fw_string_cmd(dhd, "force_wme_ac", dhd->conf->force_wme_ac, 1, FALSE);
-       dhd_conf_set_fw_string_cmd(dhd, "stbc_tx", dhd->conf->stbc, 0, FALSE);
-       dhd_conf_set_fw_string_cmd(dhd, "stbc_rx", dhd->conf->stbc, 0, FALSE);
-       dhd_conf_set_fw_int_cmd(dhd, "WLC_SET_SRL", WLC_SET_SRL, dhd->conf->srl, 0, TRUE);
-       dhd_conf_set_fw_int_cmd(dhd, "WLC_SET_LRL", WLC_SET_LRL, dhd->conf->lrl, 0, FALSE);
-       dhd_conf_set_fw_int_cmd(dhd, "WLC_SET_SPECT_MANAGMENT", WLC_SET_SPECT_MANAGMENT, dhd->conf->spect, 0, FALSE);
-       dhd_conf_set_fw_string_cmd(dhd, "rsdb_mode", dhd->conf->rsdb_mode, -1, TRUE);
+       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, "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);
+       dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", dhd->conf->srl, 0, TRUE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_LRL, "WLC_SET_LRL", dhd->conf->lrl, 0, FALSE);
+       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
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "dhcpc_enable", dhd->conf->dhcpc_enable, 0, FALSE);
+#endif
+       dhd_conf_set_bw_cap(dhd);
 
 #ifdef MIMO_ANT_SETTING
        dhd_sel_ant_from_file(dhd);
@@ -8652,7 +8691,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                DHD_ERROR(("%s Set txbf returned (%d)\n", __FUNCTION__, ret));
        }
 #endif /* USE_WL_TXBF */
-       dhd_conf_set_fw_string_cmd(dhd, "txbf", dhd->conf->txbf, 0, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "txbf", dhd->conf->txbf, 0, FALSE);
 
 #ifdef USE_WFA_CERT_CONF
 #ifdef USE_WL_FRAMEBURST
@@ -8675,7 +8714,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                sizeof(frameburst), TRUE, 0)) < 0) {
                DHD_INFO(("%s frameburst not supported  %d\n", __FUNCTION__, ret));
        }
-       dhd_conf_set_fw_string_cmd(dhd, "frameburst", dhd->conf->frameburst, 0, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_FAKEFRAG, "WLC_SET_FAKEFRAG", dhd->conf->frameburst, 0, FALSE);
 #if defined(CUSTOM_AMPDU_BA_WSIZE)
        /* Set ampdu ba wsize to 64 or 16 */
 #ifdef CUSTOM_AMPDU_BA_WSIZE
@@ -8690,7 +8729,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                }
        }
 #endif 
-       dhd_conf_set_fw_string_cmd(dhd, "ampdu_ba_wsize", dhd->conf->ampdu_ba_wsize, 1, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_ba_wsize", dhd->conf->ampdu_ba_wsize, 1, FALSE);
 
        iov_buf = (char*)kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL);
        if (iov_buf == NULL) {
@@ -8999,10 +9038,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #if defined(BCMSDIO)
        dhd_txglom_enable(dhd, dhd->conf->bus_rxglom);
        // terence 20151210: set bus:txglom after dhd_txglom_enable since it's possible changed in dhd_conf_set_txglom_params
-       dhd_conf_set_fw_string_cmd(dhd, "bus:txglom", dhd->conf->bus_txglom, 1, FALSE);
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bus:txglom", dhd->conf->bus_txglom, 0, FALSE);
 #endif /* defined(BCMSDIO) */
 
-       dhd_conf_set_disable_proptx(dhd);
 #if defined(BCMSDIO)
 #ifdef PROP_TXSTATUS
        if (disable_proptx ||
@@ -9014,6 +9052,16 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                FALSE) {
                wlfc_enable = FALSE;
        }
+       ret = dhd_conf_get_disable_proptx(dhd);
+       if (ret == 0){
+               disable_proptx = 0;
+               wlfc_enable = TRUE;
+       } else if (ret >= 1) {
+               disable_proptx = 1;
+               wlfc_enable = FALSE;
+               /* terence 20161229: we should set ampdu_hostreorder=0 when disalbe_proptx=1 */
+               hostreorder = 0;
+       }
 
 #ifdef USE_WFA_CERT_CONF
        if (sec_get_param_wfa_cert(dhd, SET_PARAM_PROPTX, &proptx) == BCME_OK) {
@@ -9056,8 +9104,11 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        else if (hostreorder)
                dhd_wlfc_hostreorder_init(dhd);
 #endif /* DISABLE_11N */
-
+#else
+       /* terence 20161229: disable ampdu_hostreorder if PROP_TXSTATUS not defined */
+       printf("%s: not define PROP_TXSTATUS\n", __FUNCTION__);
 #endif /* PROP_TXSTATUS */
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_hostreorder", dhd->conf->ampdu_hostreorder, 0, TRUE);
 #endif /* BCMSDIO || BCMBUS */
 #ifdef PCIE_FULL_DONGLE
        /* For FD we need all the packets at DHD to handle intra-BSS forwarding */
@@ -9505,6 +9556,11 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
 
        if (ifidx == 0)
                printf("%s\n", dhd_version);
+#ifdef WL_EXT_IAPSTA
+       else if (!strncmp(net->name, "wl0.", strlen("wl0."))) {
+               wl_android_ext_attach_netdev(net, ifidx);
+       }
+#endif
 
        if (need_rtnl_lock)
                err = register_netdev(net);
@@ -9532,7 +9588,7 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
 #if (defined(BCMPCIE) || (defined(BCMLXSDMMC) && (LINUX_VERSION_CODE >= \
        KERNEL_VERSION(2, 6, 27))))
        if (ifidx == 0) {
-#ifdef BCMLXSDMMC
+#if defined(BCMLXSDMMC) && !defined(DHD_PRELOAD)
                up(&dhd_registration_sem);
 #endif /* BCMLXSDMMC */
                if (!dhd_download_fw_on_driverload) {
@@ -9840,6 +9896,8 @@ void dhd_detach(dhd_pub_t *dhdp)
 #ifdef CONFIG_HAS_WAKELOCK
                dhd->wakelock_wd_counter = 0;
                wake_lock_destroy(&dhd->wl_wdwake);
+               // terence 20161023: can not destroy wl_wifi when wlan down, it will happen null pointer in dhd_ioctl_entry
+               wake_lock_destroy(&dhd->wl_wifi);
 #endif /* CONFIG_HAS_WAKELOCK */
                DHD_OS_WAKE_LOCK_DESTROY(dhd);
        }
@@ -10536,7 +10594,7 @@ dhd_os_tcpackunlock(dhd_pub_t *pub, unsigned long flags)
 
        if (dhd) {
 #ifdef BCMSDIO
-               spin_lock_bh(&dhd->tcpack_lock);
+               spin_unlock_bh(&dhd->tcpack_lock); // terence 20160519
 #else
                spin_unlock_irqrestore(&dhd->tcpack_lock, flags);
 #endif /* BCMSDIO */
@@ -10606,7 +10664,7 @@ dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
        ASSERT(dhd->iflist[*ifidx]->net != NULL);
 
                if (dhd->iflist[*ifidx]->net) {
-               wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+                       wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
                }
        }
 #endif /* defined(WL_WIRELESS_EXT)  */
@@ -11278,6 +11336,10 @@ static void dhd_hang_process(void *dhd_info, void *event_info, u8 event)
        dev = dhd->iflist[0]->net;
 
        if (dev) {
+               // terence 20161024: let wlan0 down when hang happened
+               rtnl_lock();
+               dev_close(dev);
+               rtnl_unlock();
 #if defined(WL_WIRELESS_EXT)
                wl_iw_send_priv_event(dev, "HANG");
 #endif
@@ -12364,7 +12426,7 @@ void dhd_os_wake_lock_init(struct dhd_info *dhd)
        dhd->wakelock_rx_timeout_enable = 0;
        dhd->wakelock_ctrl_timeout_enable = 0;
 #ifdef CONFIG_HAS_WAKELOCK
-       wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
+       // terence 20161023: can not destroy wl_wifi when wlan down, it will happen null pointer in dhd_ioctl_entry
        wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
        wake_lock_init(&dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake");
        wake_lock_init(&dhd->wl_evtwake, WAKE_LOCK_SUSPEND, "wlan_evt_wake");
@@ -12388,7 +12450,7 @@ void dhd_os_wake_lock_destroy(struct dhd_info *dhd)
        dhd->wakelock_counter = 0;
        dhd->wakelock_rx_timeout_enable = 0;
        dhd->wakelock_ctrl_timeout_enable = 0;
-       wake_lock_destroy(&dhd->wl_wifi);
+       // terence 20161023: can not destroy wl_wifi when wlan down, it will happen null pointer in dhd_ioctl_entry
        wake_lock_destroy(&dhd->wl_rxwake);
        wake_lock_destroy(&dhd->wl_ctrlwake);
        wake_lock_destroy(&dhd->wl_evtwake);
@@ -12468,7 +12530,7 @@ bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret)
        net = dhd_idx2net(dhdp, ifidx);
        if (!net) {
                DHD_ERROR(("%s : Invalid index : %d\n", __FUNCTION__, ifidx));
-               return FALSE;
+               return -EINVAL;
        }
 
        return dhd_check_hang(net, dhdp, ret);
@@ -13947,8 +14009,21 @@ void *dhd_get_pub(struct net_device *dev)
        dhd_info_t *dhdinfo = *(dhd_info_t **)netdev_priv(dev);
        if (dhdinfo)
                return (void *)&dhdinfo->pub;
-       else
+       else {
+               printf("%s: null dhdinfo\n", __FUNCTION__);
                return NULL;
+       }
+}
+
+void *dhd_get_conf(struct net_device *dev)
+{
+       dhd_info_t *dhdinfo = *(dhd_info_t **)netdev_priv(dev);
+       if (dhdinfo)
+               return (void *)dhdinfo->pub.conf;
+       else {
+               printf("%s: null dhdinfo\n", __FUNCTION__);
+               return NULL;
+       }
 }
 
 bool dhd_os_wd_timer_enabled(void *bus)
index ab05136a2e213c3ac2960238e500491457f42ced..10de394367562b27947e40632fa3b995f05db023 100755 (executable)
 #include <linux/earlysuspend.h>
 #endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
 
-
-#if defined(CUSTOMER_HW)
-#define WLAN_PLAT_NODFS_FLAG    0x01
-#define WLAN_PLAT_AP_FLAG      0x02
-struct wifi_platform_data {
-       int (*set_power)(bool val);
-       int (*set_carddetect)(bool val);
-       void *(*mem_prealloc)(int section, unsigned long size);
-       int (*get_mac_addr)(unsigned char *buf);
-#if defined(CUSTOM_COUNTRY_CODE)
-       void *(*get_country_code)(char *ccode, u32 flags);
-#else /* defined (CUSTOM_COUNTRY_CODE) */
-       void *(*get_country_code)(char *ccode);
-#endif
-};
-#endif
 #define DHD_REGISTRATION_TIMEOUT  12000  /* msec : allowed time to finished dhd registration */
 
 typedef struct wifi_adapter_info {
@@ -80,8 +64,36 @@ typedef struct wifi_adapter_info {
        uint            bus_type;
        uint            bus_num;
        uint            slot_num;
+#ifdef BUS_POWER_RESTORE
+#if defined(BCMSDIO)
+       struct sdio_func *sdio_func;
+#endif /* BCMSDIO */
+#if defined(BCMPCIE)
+       struct pci_dev *pci_dev;
+       struct pci_saved_state *pci_saved_state;
+#endif /* BCMPCIE */
+#endif
 } wifi_adapter_info_t;
 
+#define WLAN_PLAT_NODFS_FLAG    0x01
+#define WLAN_PLAT_AP_FLAG      0x02
+struct wifi_platform_data {
+#ifdef BUS_POWER_RESTORE
+       int (*set_power)(bool val, wifi_adapter_info_t *adapter);
+#else
+       int (*set_power)(bool val);
+#endif
+       int (*set_reset)(int val);
+       int (*set_carddetect)(bool val);
+       void *(*mem_prealloc)(int section, unsigned long size);
+       int (*get_mac_addr)(unsigned char *buf);
+#if defined(CUSTOM_COUNTRY_CODE)
+       void *(*get_country_code)(char *ccode, u32 flags);
+#else /* defined (CUSTOM_COUNTRY_CODE) */
+       void *(*get_country_code)(char *ccode);
+#endif
+};
+
 typedef struct bcmdhd_wifi_platdata {
        uint                            num_adapters;
        wifi_adapter_info_t     *adapters;
index c1969c72d7018a62790311d631648a1b4ec9d9e1..fed0d0c1ed1ada2997d00aa20c315f5226d7efa6 100755 (executable)
 #endif /* CONFIG_DTS */
 
 #if defined(CUSTOMER_HW)
-#if defined(CUSTOMER_OOB)
-extern uint bcm_wlan_get_oob_irq(void);
-extern uint bcm_wlan_get_oob_irq_flags(void);
-#endif
-extern int bcm_wlan_set_plat_data(void);
+extern int dhd_wlan_init_plat_data(void);
+extern void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter);
 #endif /* CUSTOMER_HW */
 
 #define WIFI_PLAT_NAME         "bcmdhd_wlan"
@@ -70,13 +67,12 @@ static bool is_power_on = FALSE;
 #if !defined(CONFIG_DTS)
 #if defined(DHD_OF_SUPPORT)
 static bool dts_enabled = TRUE;
+extern struct resource dhd_wlan_resources;
 extern struct wifi_platform_data dhd_wlan_control;
 #else
 static bool dts_enabled = FALSE;
 struct resource dhd_wlan_resources = {0};
-#ifdef CUSTOMER_HW
-struct wifi_platform_data dhd_wlan_control = {0};
-#endif
+extern struct wifi_platform_data dhd_wlan_control;
 #endif /* !defind(DHD_OF_SUPPORT) */
 #endif /* !defind(CONFIG_DTS) */
 
@@ -187,7 +183,11 @@ int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long
                }
 #endif /* ENABLE_4335BT_WAR */
 
+#ifdef BUS_POWER_RESTORE
+               err = plat_data->set_power(on, adapter);
+#else
                err = plat_data->set_power(on);
+#endif
        }
 
        if (msec && !err)
@@ -256,8 +256,8 @@ wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode)
 #else
                return plat_data->get_country_code(ccode);
 #endif /* CUSTOM_COUNTRY_CODE */
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 58)) */
        }
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */
 
        return NULL;
 }
@@ -434,7 +434,7 @@ static int wifi_ctrlfunc_register_drv(void)
        adapter = kzalloc(sizeof(wifi_adapter_info_t), GFP_KERNEL);
        if (adapter == NULL) {
                DHD_ERROR(("%s:adapter alloc failed", __FUNCTION__));
-               return ENOMEM;
+               return -ENOMEM;
        }
        adapter->name = "DHD generic adapter";
        adapter->bus_type = -1;
@@ -468,19 +468,16 @@ static int wifi_ctrlfunc_register_drv(void)
 
 #if !defined(CONFIG_DTS)
        if (dts_enabled) {
-#ifdef CUSTOMER_HW
-               adapter->wifi_plat_data = (void *)&dhd_wlan_control;
-               bcm_wlan_set_plat_data();
-#ifdef CUSTOMER_OOB
-               adapter->irq_num = bcm_wlan_get_oob_irq();
-               adapter->intr_flags = bcm_wlan_get_oob_irq_flags();
-#endif
-#else
                struct resource *resource;
+               adapter->wifi_plat_data = (void *)&dhd_wlan_control;
                resource = &dhd_wlan_resources;
+#ifdef CUSTOMER_HW
+               wifi_plat_dev_probe_ret = dhd_wlan_init_plat_data();
+               if (wifi_plat_dev_probe_ret)
+                       return wifi_plat_dev_probe_ret;
+#endif
                adapter->irq_num = resource->start;
                adapter->intr_flags = resource->flags & IRQF_TRIGGER_MASK;
-#endif
                wifi_plat_dev_probe_ret = dhd_wifi_platform_load();
        }
 #endif /* !defined(CONFIG_DTS) */
@@ -496,6 +493,7 @@ static int wifi_ctrlfunc_register_drv(void)
 
 void wifi_ctrlfunc_unregister_drv(void)
 {
+       wifi_adapter_info_t *adapter;
 
 #if defined(CONFIG_DTS) && !defined(CUSTOMER_HW)
        DHD_ERROR(("unregister wifi platform drivers\n"));
@@ -517,7 +515,6 @@ void wifi_ctrlfunc_unregister_drv(void)
                platform_driver_unregister(&wifi_platform_dev_driver_legacy);
 #endif
        if (dts_enabled) {
-               wifi_adapter_info_t *adapter;
                adapter = &dhd_wifi_platdata->adapters[0];
                if (is_power_on) {
                        wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
@@ -526,6 +523,10 @@ void wifi_ctrlfunc_unregister_drv(void)
        }
 #endif /* !defined(CONFIG_DTS) */
 
+#if defined(CUSTOMER_HW)
+       dhd_wlan_deinit_plat_data(adapter);
+#endif
+
        kfree(dhd_wifi_platdata->adapters);
        dhd_wifi_platdata->adapters = NULL;
        dhd_wifi_platdata->num_adapters = 0;
@@ -724,7 +725,7 @@ static int dhd_wifi_platform_load_sdio(void)
                !(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx))
                return -EINVAL;
 
-#if defined(BCMLXSDMMC)
+#if defined(BCMLXSDMMC) && !defined(DHD_PRELOAD)
        if (dhd_wifi_platdata == NULL) {
                DHD_ERROR(("DHD wifi platform data is required for Android build\n"));
                return -EINVAL;
index f22003136c2d43166f0f3369f32d3d272756158b..adb5881d11182a5350b106c5d83ebe8ed2219ca8 100755 (executable)
@@ -813,7 +813,8 @@ dhdpcie_bus_remove_prep(dhd_bus_t *bus)
        dhd_os_sdlock(bus->dhd);
 
        dhdpcie_bus_intr_disable(bus);
-       if (!bus->dhd->dongle_isolation) {
+       // terence 20150406: fix for null pointer handle when doing remove driver
+       if (!bus->dhd->dongle_isolation && bus->sih) {
                pcie_watchdog_reset(bus->osh, bus->sih, (sbpcieregs_t *)(bus->regs));
        }
 
@@ -2086,7 +2087,7 @@ dhdpcie_bus_membytes(dhd_bus_t *bus, bool write, ulong address, uint8 *data, uin
        dsize = sizeof(uint64);
 
        /* Do the transfer(s) */
-       DHD_INFO(("%s: %s %d bytes in window 0x%08x\n",
+       DHD_INFO(("%s: %s %d bytes in window 0x%08lx\n",
                  __FUNCTION__, (write ? "write" : "read"), size, address));
        if (write) {
                while (size) {
@@ -2180,7 +2181,7 @@ dhd_bus_schedule_queue(struct dhd_bus  *bus, uint16 flow_id, bool txs)
                }
 
                while ((txp = dhd_flow_queue_dequeue(bus->dhd, queue)) != NULL) {
-                       PKTORPHAN(txp);
+                       PKTORPHAN(txp, bus->dhd->conf->tsq);
 
                        /*
                         * Modifying the packet length caused P2P cert failures.
@@ -3732,6 +3733,7 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state)
        unsigned long flags;
        int rc = 0;
 
+       printf("%s: state=%d\n", __FUNCTION__, state);
        if (bus->dhd == NULL) {
                DHD_ERROR(("%s: bus not inited\n", __FUNCTION__));
                return BCME_ERROR;
index ca017627bf5eea5bea2339ff8933eb7aca040e57..0fef810a3a7cad8ff0a678602d02d885e14da5fd 100755 (executable)
@@ -493,6 +493,9 @@ dhdpcie_bus_unregister(void)
 int __devinit
 dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+#ifdef BUS_POWER_RESTORE
+       wifi_adapter_info_t *adapter = NULL;
+#endif
 
        if (dhdpcie_chipmatch (pdev->vendor, pdev->device)) {
                DHD_ERROR(("%s: chipmatch failed!!\n", __FUNCTION__));
@@ -512,6 +515,14 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        device_disable_async_suspend(&pdev->dev);
 #endif /* BCMPCIE_DISABLE_ASYNC_SUSPEND */
 
+#ifdef BUS_POWER_RESTORE
+       adapter = dhd_wifi_platform_get_adapter(PCI_BUS, pdev->bus->number,
+                                               PCI_SLOT(pdev->devfn));
+
+       if (adapter != NULL)
+               adapter->pci_dev = pdev;
+#endif
+
        DHD_TRACE(("%s: PCIe Enumeration done!!\n", __FUNCTION__));
        return 0;
 }
@@ -599,12 +610,14 @@ dhdpcie_request_irq(dhdpcie_info_t *dhdpcie_info)
 {
        dhd_bus_t *bus = dhdpcie_info->bus;
        struct pci_dev *pdev = dhdpcie_info->bus->dev;
+       int err = 0;
 
        if (!bus->irq_registered) {
                snprintf(dhdpcie_info->pciname, sizeof(dhdpcie_info->pciname),
                    "dhdpcie:%s", pci_name(pdev));
-               if (request_irq(pdev->irq, dhdpcie_isr, IRQF_SHARED,
-                       dhdpcie_info->pciname, bus) < 0) {
+               err = request_irq(pdev->irq, dhdpcie_isr, IRQF_SHARED,
+                       dhdpcie_info->pciname, bus);
+               if (err) {
                        DHD_ERROR(("%s: request_irq() failed\n", __FUNCTION__));
                        return -1;
                } else {
@@ -1397,9 +1410,9 @@ int dhdpcie_oob_intr_register(dhd_bus_t *bus)
        }
 
        if (dhdpcie_osinfo->oob_irq_num > 0) {
-               DHD_INFO_HW4(("%s OOB irq=%d flags=%X \n", __FUNCTION__,
+               printf("%s OOB irq=%d flags=0x%X\n", __FUNCTION__,
                        (int)dhdpcie_osinfo->oob_irq_num,
-                       (int)dhdpcie_osinfo->oob_irq_flags));
+                       (int)dhdpcie_osinfo->oob_irq_flags);
                err = request_irq(dhdpcie_osinfo->oob_irq_num, wlan_oob_irq,
                        dhdpcie_osinfo->oob_irq_flags, "dhdpcie_host_wake",
                        bus);
@@ -1408,10 +1421,17 @@ int dhdpcie_oob_intr_register(dhd_bus_t *bus)
                                __FUNCTION__, err));
                        return err;
                }
+#if defined(DISABLE_WOWLAN)
+               printf("%s: disable_irq_wake\n", __FUNCTION__);
+               dhdpcie_osinfo->oob_irq_wake_enabled = FALSE;
+#else
+               printf("%s: enable_irq_wake\n", __FUNCTION__);
                err = enable_irq_wake(dhdpcie_osinfo->oob_irq_num);
                if (!err) {
                        dhdpcie_osinfo->oob_irq_wake_enabled = TRUE;
-               }
+               } else
+                       printf("%s: enable_irq_wake failed with %d\n", __FUNCTION__, err);
+#endif
                dhdpcie_osinfo->oob_irq_enabled = TRUE;
        }
 
index 90e6877ec686562963b370dbed31fb2a8608f767..a0eddd2e892e18bb00b1e2df8b8f3babb7410255 100755 (executable)
@@ -477,12 +477,12 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t
 
 
 #ifdef GSCAN_SUPPORT
-                       if (mode == DHD_PNO_BATCH_MODE ||
-                               ((mode & DHD_PNO_GSCAN_MODE) && pno_params->params_gscan.mscan)) {
+       if (mode == DHD_PNO_BATCH_MODE ||
+               ((mode & DHD_PNO_GSCAN_MODE) && pno_params->params_gscan.mscan))
 #else
-                       if (mode == DHD_PNO_BATCH_MODE) {
+       if (mode == DHD_PNO_BATCH_MODE)
 #endif /* GSCAN_SUPPORT */
-
+       {
                int _tmp = pfn_param.bestn;
                /* set bestn to calculate the max mscan which firmware supports */
                err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 1);
@@ -509,6 +509,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t
 exit:
        return err;
 }
+
 static int
 _dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssids_list, int nssid)
 {
@@ -560,12 +561,14 @@ _dhd_pno_add_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssids_list, int nssid)
 exit:
        return err;
 }
+
 /* qsort compare function */
 static int
 _dhd_pno_cmpfunc(const void *a, const void *b)
 {
        return (*(uint16*)a - *(uint16*)b);
 }
+
 static int
 _dhd_pno_chan_merge(uint16 *d_chan_list, int *nchan,
        uint16 *chan_list1, int nchan1, uint16 *chan_list2, int nchan2)
@@ -601,6 +604,7 @@ _dhd_pno_chan_merge(uint16 *d_chan_list, int *nchan,
        *nchan = k;
        return err;
 }
+
 static int
 _dhd_pno_get_channels(dhd_pub_t *dhd, uint16 *d_chan_list,
        int *nchan, uint8 band, bool skip_dfs)
@@ -649,6 +653,7 @@ _dhd_pno_get_channels(dhd_pub_t *dhd, uint16 *d_chan_list,
 exit:
        return err;
 }
+
 static int
 _dhd_pno_convert_format(dhd_pub_t *dhd, struct dhd_pno_batch_params *params_batch,
        char *buf, int nbufsize)
@@ -1172,10 +1177,11 @@ dhd_pno_set_for_ssid(dhd_pub_t *dhd, wlc_ssid_ext_t* ssid_list, int nssid,
        /* If GSCAN is also ON will handle this down below */
 #ifdef GSCAN_SUPPORT
        if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE &&
-               !(_pno_state->pno_mode & DHD_PNO_GSCAN_MODE)) {
+               !(_pno_state->pno_mode & DHD_PNO_GSCAN_MODE))
 #else
-               if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE) {
+       if (_pno_state->pno_mode & DHD_PNO_LEGACY_MODE)
 #endif /* GSCAN_SUPPORT */
+       {
                DHD_ERROR(("%s : Legacy PNO mode was already started, "
                        "will disable previous one to start new one\n", __FUNCTION__));
                err = dhd_pno_stop_for_ssid(dhd);
@@ -1319,6 +1325,7 @@ exit_no_clear:
        }
        return err;
 }
+
 int
 dhd_pno_set_for_batch(dhd_pub_t *dhd, struct dhd_pno_batch_params *batch_params)
 {
@@ -2823,10 +2830,11 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
                goto exit_no_unlock;
        }
 #ifdef GSCAN_SUPPORT
-       if (!(_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_GSCAN_MODE))) {
+       if (!(_pno_state->pno_mode & (DHD_PNO_BATCH_MODE | DHD_PNO_GSCAN_MODE)))
 #else
-       if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE)) {
+       if (!(_pno_state->pno_mode & DHD_PNO_BATCH_MODE))
 #endif /* GSCAN_SUPPORT */
+       {
                DHD_ERROR(("%s: Batching SCAN mode is not enabled\n", __FUNCTION__));
                goto exit_no_unlock;
        }
@@ -3047,6 +3055,7 @@ exit_no_unlock:
                complete(&_pno_state->get_batch_done);
        return err;
 }
+
 static void
 _dhd_pno_get_batch_handler(struct work_struct *work)
 {
index 2d89838c3dc4ae9d31315b19ebf41c342686795c..bd33ca7ada098b74163fe53525b9ba7e82ddf46f 100755 (executable)
@@ -1596,7 +1596,6 @@ dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
        return err;
 }
 
-#ifdef USE_DYNAMIC_F2_BLKSIZE
 int dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size)
 {
        int func_blk_size = function_num;
@@ -1612,7 +1611,7 @@ int dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size)
        }
 
        if (result != block_size) {
-               DHD_TRACE_HW4(("%s: F%d Block size set from %d to %d\n",
+               DHD_ERROR(("%s: F%d Block size set from %d to %d\n",
                        __FUNCTION__, function_num, result, block_size));
                func_blk_size = function_num << 16 | block_size;
                bcmerr = dhd_bus_iovar_op(dhd, "sd_blocksize", NULL,
@@ -1625,7 +1624,6 @@ int dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size)
 
        return BCME_OK;
 }
-#endif /* USE_DYNAMIC_F2_BLKSIZE */
 
 #if defined(OOB_INTR_ONLY) || defined(FORCE_WOWLAN)
 void
@@ -2652,16 +2650,11 @@ dhdsdio_sendfromq_swtxglom(dhd_bus_t *bus, uint maxframes)
                        datalen = 0;
 
 #ifdef PKT_STATICS
-                       if (txglom_cnt < 2)
-                               tx_statics.glom_1_count++;
-                       else if (txglom_cnt < 3)
-                               tx_statics.glom_3_count++;
-                       else if (txglom_cnt < 8)
-                               tx_statics.glom_3_8_count++;
-                       else
-                               tx_statics.glom_8_count++;
-                       if (txglom_cnt > tx_statics.glom_max)
-                               tx_statics.glom_max = txglom_cnt;
+                       if (txglom_cnt) {
+                               tx_statics.glom_cnt[txglom_cnt-1]++;
+                               if (txglom_cnt > tx_statics.glom_max)
+                                       tx_statics.glom_max = txglom_cnt;
+                       }
 #endif
                        for (i = 0; i < txglom_cnt; i++) {
                                uint datalen_tmp = 0;
@@ -2920,7 +2913,7 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
                                ASSERT(0);
                                break;
                        }
-                       PKTORPHAN(pkts[i]);
+                       PKTORPHAN(pkts[i], bus->dhd->conf->tsq);
                        datalen += PKTLEN(osh, pkts[i]);
                }
                dhd_os_sdunlock_txq(bus->dhd);
@@ -2936,16 +2929,11 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
                }
                cnt += i;
 #ifdef PKT_STATICS
-               if (num_pkt < 2)
-                       tx_statics.glom_1_count++;
-               else if (num_pkt < 3)
-                       tx_statics.glom_3_count++;
-               else if (num_pkt < 8)
-                       tx_statics.glom_3_8_count++;
-               else
-                       tx_statics.glom_8_count++;
-               if (num_pkt > tx_statics.glom_max)
-                       tx_statics.glom_max = num_pkt;
+               if (num_pkt) {
+                       tx_statics.glom_cnt[num_pkt-1]++;
+                       if (num_pkt > tx_statics.glom_max)
+                               tx_statics.glom_max = num_pkt;
+               }
 #endif
 
                /* In poll mode, need to check for other events */
@@ -5241,6 +5229,7 @@ dhd_txglom_enable(dhd_pub_t *dhdp, bool enable)
                bus->txglom_enable = FALSE;
        printf("%s: enable %d\n",  __FUNCTION__, bus->txglom_enable);
        dhd_conf_set_txglom_params(bus->dhd, bus->txglom_enable);
+       bcmsdh_set_mode(bus->sdh, bus->dhd->conf->txglom_mode);
 }
 
 int
@@ -5978,6 +5967,15 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
                                        dhd_os_sdunlock(bus->dhd);
                                        dhd_rx_frame(bus->dhd, idx, list_head[idx], cnt, 0);
                                        dhd_os_sdlock(bus->dhd);
+#if defined(SDIO_ISR_THREAD)
+                                       /* terence 20150615: fix for below error due to bussleep in watchdog after dhd_os_sdunlock here,
+                                         * so call BUS_WAKE to wake up bus again
+                                         * dhd_bcmsdh_recv_buf: Device asleep
+                                         * dhdsdio_readframes: RXHEADER FAILED: -40
+                                         * dhdsdio_rxfail: abort command, terminate frame, send NAK
+                                       */
+                                       BUS_WAKE(bus);
+#endif
                                }
                        }
                }
@@ -6919,7 +6917,7 @@ clkwait:
         * or clock availability.  (Allows tx loop to check ipend if desired.)
         * (Unless register access seems hosed, as we may not be able to ACK...)
         */
-       if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
+       if (!bus->dhd->conf->oob_enabled_later && bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
                DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
                          __FUNCTION__, rxdone, framecnt));
                bus->intdis = FALSE;
@@ -6955,7 +6953,10 @@ clkwait:
        /* Send queued frames (limit 1 if rx may still be pending) */
        else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
            pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) {
-               framecnt = rxdone ? txlimit : MIN(txlimit, dhd_txminmax);
+               if (bus->dhd->conf->dhd_txminmax < 0)
+                       framecnt = rxdone ? txlimit : MIN(txlimit, DATABUFCNT(bus));
+               else
+                       framecnt = rxdone ? txlimit : MIN(txlimit, bus->dhd->conf->dhd_txminmax);
 #if defined(SWTXGLOM)
                if (bus->dhd->conf->swtxglom)
                        framecnt = dhdsdio_sendfromq_swtxglom(bus, framecnt);
@@ -7007,12 +7008,27 @@ clkwait:
 
 exit:
 
-       if (!resched && dhd_dpcpoll) {
-               if (dhdsdio_readframes(bus, dhd_rxbound, &rxdone) != 0) {
-                       resched = TRUE;
+       if (!resched) {
+               /* Re-enable interrupts to detect new device events (mailbox, rx frame)
+                * or clock availability.  (Allows tx loop to check ipend if desired.)
+                * (Unless register access seems hosed, as we may not be able to ACK...)
+                */
+               if (bus->dhd->conf->oob_enabled_later && bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) {
+                       DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n",
+                                         __FUNCTION__, rxdone, framecnt));
+                       bus->intdis = FALSE;
+#if defined(OOB_INTR_ONLY)
+                       bcmsdh_oob_intr_set(bus->sdh, TRUE);
+#endif /* defined(OOB_INTR_ONLY) */
+                       bcmsdh_intr_enable(sdh);
+               }
+               if (dhd_dpcpoll) {
+                       if (dhdsdio_readframes(bus, dhd_rxbound, &rxdone) != 0) {
+                               resched = TRUE;
 #ifdef DEBUG_DPC_THREAD_WATCHDOG
-                       is_resched_by_readframe = TRUE;
+                               is_resched_by_readframe = TRUE;
 #endif /* DEBUG_DPC_THREAD_WATCHDOG */
+                       }
                }
        }
 
@@ -7110,22 +7126,40 @@ dhdsdio_isr(void *arg)
 #ifdef PKT_STATICS
 void dhdsdio_txpktstatics(void)
 {
-       uint total, f1, f2, f3, f4;
-       printf("Randy: TYPE EVENT: %d pkts (size=%d) transfered\n", tx_statics.event_count, tx_statics.event_size);
-       printf("Randy: TYPE CTRL:  %d pkts (size=%d) transfered\n", tx_statics.ctrl_count, tx_statics.ctrl_size);
-       printf("Randy: TYPE DATA:  %d pkts (size=%d) transfered\n", tx_statics.data_count, tx_statics.data_size);
-       if(tx_statics.glom_1_count || tx_statics.glom_3_count || tx_statics.glom_3_8_count || tx_statics.glom_8_count) {
-               total = tx_statics.glom_1_count + tx_statics.glom_3_count + tx_statics.glom_3_8_count + tx_statics.glom_8_count;
-               f1 = (tx_statics.glom_1_count*100) / total;
-               f2 = (tx_statics.glom_3_count*100) / total;
-               f3 = (tx_statics.glom_3_8_count*100) / total;
-               f4 = (tx_statics.glom_8_count*100) / total;
-               printf("Randy: glomsize==1: %d(%d), tglomsize==2: %d(%d), pkts 3<=glomsize<8: %d(%d), pkts glomszie>=8: %d(%d)\n",
-                       tx_statics.glom_1_count, f1, tx_statics.glom_3_count, f2, tx_statics.glom_3_8_count, f3, tx_statics.glom_8_count, f4);
-               printf("Randy: data/glom=%d, glom_max=%d\n", tx_statics.data_count/total, tx_statics.glom_max);
-       }
-       printf("Randy: TYPE RX GLOM: %d pkts (size=%d) transfered\n", tx_statics.glom_count, tx_statics.glom_size);
-       printf("Randy: TYPE TEST: %d pkts (size=%d) transfered\n\n\n", tx_statics.test_count, tx_statics.test_size);
+       uint i, total = 0;
+
+       printf("%s: TYPE EVENT: %d pkts (size=%d) transfered\n",
+               __FUNCTION__, tx_statics.event_count, tx_statics.event_size);
+       printf("%s: TYPE CTRL:  %d pkts (size=%d) transfered\n",
+               __FUNCTION__, tx_statics.ctrl_count, tx_statics.ctrl_size);
+       printf("%s: TYPE DATA:  %d pkts (size=%d) transfered\n",
+               __FUNCTION__, tx_statics.data_count, tx_statics.data_size);
+       printf("%s: Glom size distribution:\n", __FUNCTION__);
+       for (i=0;i<tx_statics.glom_max;i++) {
+               total += tx_statics.glom_cnt[i];
+       }
+       for (i=0;i<tx_statics.glom_max;i++) {
+               printf("%02d: %d", i+1, tx_statics.glom_cnt[i]);
+               if ((i+1)%8) 
+                       printf(", ");
+               else
+                       printf("\n");
+       }
+       printf("\n");
+       for (i=0;i<tx_statics.glom_max;i++) {
+               printf("%02d:%3d%%", i+1, (tx_statics.glom_cnt[i]*100)/total);
+               if ((i+1)%8) 
+                       printf(", ");
+               else
+                       printf("\n");
+       }
+       printf("\n");
+       printf("%s: data/glom=%d, glom_max=%d\n",
+               __FUNCTION__, tx_statics.data_count/total, tx_statics.glom_max);
+       printf("%s: TYPE RX GLOM: %d pkts (size=%d) transfered\n",
+               __FUNCTION__, tx_statics.glom_count, tx_statics.glom_size);
+       printf("%s: TYPE TEST: %d pkts (size=%d) transfered\n\n\n",
+               __FUNCTION__, tx_statics.test_count, tx_statics.test_size);
 }
 #endif
 
@@ -7501,7 +7535,8 @@ dhd_bus_watchdog(dhd_pub_t *dhdp)
        dhd_os_sdlock(bus->dhd);
 
        /* Poll period: check device if appropriate. */
-       if (!SLPAUTO_ENAB(bus) && (bus->poll && (++bus->polltick >= bus->pollrate))) {
+       // terence 20160615: remove !SLPAUTO_ENAB(bus) to fix not able to polling if sr supported
+       if (1 && (bus->poll && (++bus->polltick >= bus->pollrate))) {
                uint32 intstatus = 0;
 
                /* Reset poll tick */
@@ -8368,6 +8403,29 @@ dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
        return ret;
 }
 
+void
+dhd_conf_set_bus_params(struct dhd_bus *bus)
+{
+       if (bus->dhd->conf->dhd_poll >= 0) {
+               bus->poll = bus->dhd->conf->dhd_poll;
+               if (!bus->pollrate)
+                       bus->pollrate = 1;
+               printf("%s: set polling mode %d\n", __FUNCTION__, bus->dhd->conf->dhd_poll);
+       }
+       if (bus->dhd->conf->use_rxchain >= 0) {
+               bus->use_rxchain = (bool)bus->dhd->conf->use_rxchain;
+               printf("%s: set use_rxchain %d\n", __FUNCTION__, bus->dhd->conf->use_rxchain);
+       }
+       if (bus->dhd->conf->txinrx_thres >= 0) {
+               bus->txinrx_thres = bus->dhd->conf->txinrx_thres;
+               printf("%s: set txinrx_thres %d\n", __FUNCTION__, bus->txinrx_thres);
+       }
+       if (bus->dhd->conf->txglomsize >= 0) {
+               bus->txglomsize = bus->dhd->conf->txglomsize;
+               printf("%s: set txglomsize %d\n", __FUNCTION__, bus->dhd->conf->txglomsize);
+       }
+}
+
 static int
 dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh)
 {
@@ -8388,21 +8446,7 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh)
        dhd_conf_set_nv_name_by_chip(bus->dhd, bus->nv_path);
        dhd_conf_set_fw_name_by_mac(bus->dhd, bus->sdh, bus->fw_path);
        dhd_conf_set_nv_name_by_mac(bus->dhd, bus->sdh, bus->nv_path);
-       if (bus->dhd->conf->dhd_poll >= 0) {
-               printf("%s: set polling mode %d\n", __FUNCTION__, bus->dhd->conf->dhd_poll);
-               bus->poll = TRUE;
-               if (!bus->pollrate)
-                       bus->pollrate = 1;
-       }
-       if (bus->dhd->conf->use_rxchain >= 0) {
-               printf("%s: set use_rxchain %d\n", __FUNCTION__, bus->dhd->conf->use_rxchain);
-               bus->use_rxchain = (bool)bus->dhd->conf->use_rxchain;
-       }
-       if (bus->dhd->conf->txglomsize >= 0) {
-               printf("%s: set txglomsize %d\n", __FUNCTION__, bus->dhd->conf->txglomsize);
-               bus->txglomsize = bus->dhd->conf->txglomsize;
-       }
-       bcmsdh_set_mode(sdh, bus->dhd->conf->txglom_mode);
+       dhd_conf_set_bus_params(bus);
 
        printf("Final fw_path=%s\n", bus->fw_path);
        printf("Final nv_path=%s\n", bus->nv_path);
@@ -8765,7 +8809,7 @@ dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path)
                // terence 20150412: fix for firmware failed to download
                if (bus->dhd->conf->chip == BCM43340_CHIP_ID ||
                                bus->dhd->conf->chip == BCM43341_CHIP_ID) {
-                       if (len%64 != 0) {
+                       if (len % 64 != 0) {
                                memset(memptr+len, 0, len%64);
                                len += (64 - len%64);
                        }
@@ -9184,7 +9228,7 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
                        } else
                                bcmerror = BCME_SDIO_ERROR;
 
-                               dhd_os_sdunlock(dhdp);
+                       dhd_os_sdunlock(dhdp);
                } else {
                        bcmerror = BCME_SDIO_ERROR;
                        printf("%s called when dongle is not in reset\n",
old mode 100755 (executable)
new mode 100644 (file)
index 1ebd3ee..56efdcc
 #include <linux/delay.h>\r
 #include <linux/err.h>\r
 #include <linux/skbuff.h>\r
-#include <linux/wlan_plat.h>\r
 \r
-#define CONFIG_BROADCOM_WIFI_RESERVED_MEM\r
+enum dhd_prealloc_index {\r
+       DHD_PREALLOC_PROT = 0,\r
+       DHD_PREALLOC_RXBUF,\r
+       DHD_PREALLOC_DATABUF,\r
+       DHD_PREALLOC_OSL_BUF,\r
+       DHD_PREALLOC_SKB_BUF,\r
+       DHD_PREALLOC_WIPHY_ESCAN0 = 5,\r
+       DHD_PREALLOC_WIPHY_ESCAN1 = 6,\r
+       DHD_PREALLOC_DHD_INFO = 7,\r
+       DHD_PREALLOC_DHD_WLFC_INFO = 8,\r
+       DHD_PREALLOC_IF_FLOW_LKUP = 9,\r
+       DHD_PREALLOC_FLOWRING = 10,\r
+       DHD_PREALLOC_MAX\r
+};\r
+\r
+#define STATIC_BUF_MAX_NUM     20\r
+#define STATIC_BUF_SIZE        (PAGE_SIZE*2)\r
 \r
-#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM\r
+#define DHD_PREALLOC_PROT_SIZE         (16 * 1024)\r
+#define DHD_PREALLOC_RXBUF_SIZE        (24 * 1024)\r
+#define DHD_PREALLOC_DATABUF_SIZE      (64 * 1024)\r
+#define DHD_PREALLOC_OSL_BUF_SIZE      (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)\r
+#define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)\r
+#define DHD_PREALLOC_DHD_INFO_SIZE             (24 * 1024)\r
+#ifdef CONFIG_64BIT\r
+#define DHD_PREALLOC_IF_FLOW_LKUP_SIZE (20 * 1024 * 2)\r
+#else\r
+#define DHD_PREALLOC_IF_FLOW_LKUP_SIZE (20 * 1024)\r
+#endif\r
 \r
-#define WLAN_STATIC_PKT_BUF                    4\r
-#define WLAN_STATIC_SCAN_BUF0          5\r
-#define WLAN_STATIC_SCAN_BUF1          6\r
-#define WLAN_STATIC_DHD_INFO           7\r
-#define WLAN_STATIC_DHD_WLFC_INFO              8\r
-#define PREALLOC_WLAN_SEC_NUM          6\r
-#define PREALLOC_WLAN_BUF_NUM          160\r
-#define PREALLOC_WLAN_SECTION_HEADER   24\r
+#if defined(CONFIG_64BIT)\r
+#define WLAN_DHD_INFO_BUF_SIZE         (24 * 1024)\r
+#define WLAN_DHD_WLFC_BUF_SIZE         (64 * 1024)\r
+#define WLAN_DHD_IF_FLOW_LKUP_SIZE     (64 * 1024)\r
+#else\r
+#define WLAN_DHD_INFO_BUF_SIZE         (16 * 1024)\r
+#define WLAN_DHD_WLFC_BUF_SIZE         (16 * 1024)\r
+#define WLAN_DHD_IF_FLOW_LKUP_SIZE     (20 * 1024)\r
+#endif /* CONFIG_64BIT */\r
+#define WLAN_DHD_MEMDUMP_SIZE          (800 * 1024)\r
 \r
-#define WLAN_SECTION_SIZE_0    (PREALLOC_WLAN_BUF_NUM * 128)\r
-#define WLAN_SECTION_SIZE_1    (PREALLOC_WLAN_BUF_NUM * 128)\r
-#define WLAN_SECTION_SIZE_2    (PREALLOC_WLAN_BUF_NUM * 512)\r
-#define WLAN_SECTION_SIZE_3    (PREALLOC_WLAN_BUF_NUM * 1024)\r
-#define WLAN_SECTION_SIZE_7    (PREALLOC_WLAN_BUF_NUM * 128)\r
-#define WLAN_SECTION_SIZE_8    (PREALLOC_WLAN_BUF_NUM * 512)\r
+#ifdef CONFIG_BCMDHD_PCIE\r
+#define DHD_SKB_1PAGE_BUFSIZE  (PAGE_SIZE*1)\r
+#define DHD_SKB_2PAGE_BUFSIZE  (PAGE_SIZE*2)\r
+#define DHD_SKB_4PAGE_BUFSIZE  (PAGE_SIZE*4)\r
 \r
-#define DHD_SKB_HDRSIZE                        336\r
+#define DHD_SKB_1PAGE_BUF_NUM  0\r
+#define DHD_SKB_2PAGE_BUF_NUM  64\r
+#define DHD_SKB_4PAGE_BUF_NUM  0\r
+#else\r
+#define DHD_SKB_HDRSIZE                336\r
 #define DHD_SKB_1PAGE_BUFSIZE  ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)\r
 #define DHD_SKB_2PAGE_BUFSIZE  ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)\r
 #define DHD_SKB_4PAGE_BUFSIZE  ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)\r
 \r
-#define WLAN_SKB_BUF_NUM       17\r
+#define DHD_SKB_1PAGE_BUF_NUM  8\r
+#define DHD_SKB_2PAGE_BUF_NUM  8\r
+#define DHD_SKB_4PAGE_BUF_NUM  1\r
+#endif /* CONFIG_BCMDHD_PCIE */\r
 \r
-static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];\r
+/* The number is defined in linux_osl.c\r
+ * WLAN_SKB_1_2PAGE_BUF_NUM => STATIC_PKT_1_2PAGE_NUM\r
+ * WLAN_SKB_BUF_NUM => STATIC_PKT_MAX_NUM\r
+ */\r
+#define WLAN_SKB_1_2PAGE_BUF_NUM ((DHD_SKB_1PAGE_BUF_NUM) + \\r
+               (DHD_SKB_2PAGE_BUF_NUM))\r
+#define WLAN_SKB_BUF_NUM ((WLAN_SKB_1_2PAGE_BUF_NUM) + (DHD_SKB_4PAGE_BUF_NUM))\r
 \r
-struct wlan_mem_prealloc {\r
-       void *mem_ptr;\r
-       unsigned long size;\r
-};\r
+void *wlan_static_prot = NULL;\r
+void *wlan_static_rxbuf = NULL;\r
+void *wlan_static_databuf = NULL;\r
+void *wlan_static_osl_buf = NULL;\r
+void *wlan_static_scan_buf0 = NULL;\r
+void *wlan_static_scan_buf1 = NULL;\r
+void *wlan_static_dhd_info_buf = NULL;\r
+void *wlan_static_dhd_wlfc_info_buf = NULL;\r
+void *wlan_static_if_flow_lkup = NULL;\r
 \r
-static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {\r
-       {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},\r
-       {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},\r
-       {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},\r
-       {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)},\r
-       {NULL, (WLAN_SECTION_SIZE_7 + PREALLOC_WLAN_SECTION_HEADER)},\r
-       {NULL, (WLAN_SECTION_SIZE_8 + PREALLOC_WLAN_SECTION_HEADER)}\r
-};\r
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];\r
 \r
-void *wlan_static_scan_buf0;\r
-void *wlan_static_scan_buf1;\r
-void *bcmdhd_mem_prealloc(int section, unsigned long size)\r
+void *dhd_wlan_mem_prealloc(int section, unsigned long size)\r
 {\r
-       if (section == WLAN_STATIC_PKT_BUF) {\r
-               printk("1 %s: section=%d, wlan_static_skb=%p\n",\r
-                       __FUNCTION__, section, wlan_static_skb);\r
+       printk("%s: sectoin %d, %ld\n", __FUNCTION__, section, size);\r
+       if (section == DHD_PREALLOC_PROT)\r
+               return wlan_static_prot;\r
+\r
+       if (section == DHD_PREALLOC_RXBUF)\r
+               return wlan_static_rxbuf;\r
+\r
+       if (section == DHD_PREALLOC_DATABUF)\r
+               return wlan_static_databuf;\r
+\r
+       if (section == DHD_PREALLOC_SKB_BUF)\r
                return wlan_static_skb;\r
-       }\r
-       if (section == WLAN_STATIC_SCAN_BUF0) {\r
-               printk("2 %s: section=%d, wlan_static_scan_buf0=%p\n",\r
-                       __FUNCTION__, section, wlan_static_scan_buf0);\r
+\r
+       if (section == DHD_PREALLOC_WIPHY_ESCAN0)\r
                return wlan_static_scan_buf0;\r
-       }\r
-       if (section == WLAN_STATIC_SCAN_BUF1) {\r
-               printk("3 %s: section=%d, wlan_static_scan_buf1=%p\n",\r
-                       __FUNCTION__, section, wlan_static_scan_buf1);\r
+\r
+       if (section == DHD_PREALLOC_WIPHY_ESCAN1)\r
                return wlan_static_scan_buf1;\r
+\r
+       if (section == DHD_PREALLOC_OSL_BUF) {\r
+               if (size > DHD_PREALLOC_OSL_BUF_SIZE) {\r
+                       pr_err("request OSL_BUF(%lu) is bigger than static size(%ld).\n",\r
+                               size, DHD_PREALLOC_OSL_BUF_SIZE);\r
+                       return NULL;\r
+               }\r
+               return wlan_static_osl_buf;\r
        }\r
-       if (section == WLAN_STATIC_DHD_INFO) {\r
-               printk("4 %s: section=%d, wlan_mem_array[4]=%p\n",\r
-                       __FUNCTION__, section, wlan_mem_array[4].mem_ptr);\r
-               return wlan_mem_array[4].mem_ptr;\r
-       }\r
-       if (section == WLAN_STATIC_DHD_WLFC_INFO) {\r
-               printk("5 %s: section=%d, wlan_mem_array[5]=%p\n",\r
-                       __FUNCTION__, section, wlan_mem_array[5].mem_ptr);\r
-               return wlan_mem_array[5].mem_ptr;\r
+\r
+       if (section == DHD_PREALLOC_DHD_INFO) {\r
+               if (size > DHD_PREALLOC_DHD_INFO_SIZE) {\r
+                       pr_err("request DHD_INFO size(%lu) is bigger than static size(%d).\n",\r
+                               size, DHD_PREALLOC_DHD_INFO_SIZE);\r
+                       return NULL;\r
+               }\r
+               return wlan_static_dhd_info_buf;\r
        }\r
-       if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM)) {\r
-               printk("6 %s: out of section %d\n", __FUNCTION__, section);\r
-               return NULL;\r
+       if (section == DHD_PREALLOC_DHD_WLFC_INFO) {\r
+               if (size > WLAN_DHD_WLFC_BUF_SIZE) {\r
+                       pr_err("request DHD_INFO size(%lu) is bigger than static size(%d).\n",\r
+                               size, WLAN_DHD_WLFC_BUF_SIZE);\r
+                       return NULL;\r
+               }\r
+               return wlan_static_dhd_wlfc_info_buf;\r
        }\r
+       if (section == DHD_PREALLOC_IF_FLOW_LKUP)  {\r
+               if (size > DHD_PREALLOC_IF_FLOW_LKUP_SIZE) {\r
+                       pr_err("request DHD_IF_FLOW_LKUP size(%lu) is bigger than static size(%d).\n",\r
+                               size, DHD_PREALLOC_IF_FLOW_LKUP_SIZE);\r
+                       return NULL;\r
+               }\r
 \r
-       if (wlan_mem_array[section].size < size) {\r
-               printk("7 %s: wlan_mem_array[section].size=%lu, size=%lu\n",\r
-                       __FUNCTION__, wlan_mem_array[section].size, size);\r
-               return NULL;\r
+               return wlan_static_if_flow_lkup;\r
        }\r
-       printk("8 %s: wlan_mem_array[section].mem_ptr=%p, size=%lu\n",\r
-               __FUNCTION__, &wlan_mem_array[section], size);\r
+       if ((section < 0) || (section > DHD_PREALLOC_MAX))\r
+               pr_err("request section id(%d) is out of max index %d\n",\r
+                               section, DHD_PREALLOC_MAX);\r
 \r
-       return wlan_mem_array[section].mem_ptr;\r
-}\r
+       pr_err("%s: failed to alloc section %d, size=%ld\n", __FUNCTION__, section, size);\r
 \r
-EXPORT_SYMBOL(bcmdhd_mem_prealloc);\r
+       return NULL;\r
+}\r
+EXPORT_SYMBOL(dhd_wlan_mem_prealloc);\r
 \r
-int bcmdhd_init_wlan_mem(void)
+static int dhd_init_wlan_mem(void)\r
 {\r
        int i;\r
        int j;\r
 \r
-       for (i=0; i<8; i++) {\r
+       for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {\r
                wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);\r
-               if (!wlan_static_skb[i])\r
-                       goto err_skb_alloc;
-               printk("1 %s: wlan_static_skb[%d]=%p, size=%lu\n",\r
-                       __FUNCTION__, i, wlan_static_skb[i], DHD_SKB_1PAGE_BUFSIZE);\r
+               if (!wlan_static_skb[i]) {\r
+                       goto err_skb_alloc;\r
+               }\r
+               printk("%s: sectoin %d skb[%d], size=%ld\n", __FUNCTION__, DHD_PREALLOC_SKB_BUF, i, DHD_SKB_1PAGE_BUFSIZE);\r
        }\r
 \r
-       for (; i<16; i++) {\r
+       for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {\r
                wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);\r
-               if (!wlan_static_skb[i])\r
-                       goto err_skb_alloc;
-               printk("2 %s: wlan_static_skb[%d]=%p, size=%lu\n",\r
-                       __FUNCTION__, i, wlan_static_skb[i], DHD_SKB_2PAGE_BUFSIZE);\r
+               if (!wlan_static_skb[i]) {\r
+                       goto err_skb_alloc;\r
+               }\r
+               printk("%s: sectoin %d skb[%d], size=%ld\n", __FUNCTION__, DHD_PREALLOC_SKB_BUF, i, DHD_SKB_2PAGE_BUFSIZE);\r
        }\r
 \r
+#if !defined(CONFIG_BCMDHD_PCIE)\r
        wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);\r
-       if (!wlan_static_skb[i])\r
-               goto err_skb_alloc;
-       printk("3 %s: wlan_static_skb[%d]=%p, size=%lu\n",\r
-               __FUNCTION__, i, wlan_static_skb[i], DHD_SKB_4PAGE_BUFSIZE);\r
+       if (!wlan_static_skb[i]) {\r
+               goto err_skb_alloc;\r
+       }\r
+#endif /* !CONFIG_BCMDHD_PCIE */\r
+\r
+       wlan_static_prot = kmalloc(DHD_PREALLOC_PROT_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_prot) {\r
+               pr_err("Failed to alloc wlan_static_prot\n");\r
+               goto err_mem_alloc;\r
+       }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_PROT, DHD_PREALLOC_PROT_SIZE);\r
+\r
+#if defined(CONFIG_BCMDHD_SDIO)\r
+       wlan_static_rxbuf = kmalloc(DHD_PREALLOC_RXBUF_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_rxbuf) {\r
+               pr_err("Failed to alloc wlan_static_rxbuf\n");\r
+               goto err_mem_alloc;\r
+       }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_RXBUF, DHD_PREALLOC_RXBUF_SIZE);\r
+\r
+       wlan_static_databuf = kmalloc(DHD_PREALLOC_DATABUF_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_databuf) {\r
+               pr_err("Failed to alloc wlan_static_databuf\n");\r
+               goto err_mem_alloc;\r
+       }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_DATABUF, DHD_PREALLOC_DATABUF_SIZE);\r
+#endif\r
 \r
-       for (i=0; i<PREALLOC_WLAN_SEC_NUM; i++) {\r
-               wlan_mem_array[i].mem_ptr =\r
-                               kmalloc(wlan_mem_array[i].size, GFP_KERNEL);\r
+       wlan_static_osl_buf = kmalloc(DHD_PREALLOC_OSL_BUF_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_osl_buf) {\r
+               pr_err("Failed to alloc wlan_static_osl_buf\n");\r
+               goto err_mem_alloc;\r
+       }\r
+       printk("%s: sectoin %d, size=%ld\n", __FUNCTION__, DHD_PREALLOC_OSL_BUF, DHD_PREALLOC_OSL_BUF_SIZE);\r
 \r
-               if (!wlan_mem_array[i].mem_ptr)\r
-                       goto err_mem_alloc;\r
-               printk("4 %s: wlan_mem_array[%d]=%p, size=%lu\n",\r
-                       __FUNCTION__, i, wlan_static_skb[i], wlan_mem_array[i].size);\r
+       wlan_static_scan_buf0 = kmalloc(DHD_PREALLOC_WIPHY_ESCAN0_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_scan_buf0) {\r
+               pr_err("Failed to alloc wlan_static_scan_buf0\n");\r
+               goto err_mem_alloc;\r
        }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_WIPHY_ESCAN0, DHD_PREALLOC_WIPHY_ESCAN0_SIZE);\r
 \r
-       wlan_static_scan_buf0 = kmalloc (65536, GFP_KERNEL);\r
-       if (!wlan_static_scan_buf0)
+       wlan_static_dhd_info_buf = kmalloc(DHD_PREALLOC_DHD_INFO_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_dhd_info_buf) {\r
+               pr_err("Failed to alloc wlan_static_dhd_info_buf\n");\r
                goto err_mem_alloc;\r
-       printk("5 %s: wlan_static_scan_buf0=%p, size=%d\n",\r
-               __FUNCTION__, wlan_static_scan_buf0, 65536);\r
+       }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_DHD_INFO, DHD_PREALLOC_DHD_INFO_SIZE);\r
 \r
-       wlan_static_scan_buf1 = kmalloc (65536, GFP_KERNEL);\r
-       if (!wlan_static_scan_buf1)
+       wlan_static_dhd_wlfc_info_buf = kmalloc(WLAN_DHD_WLFC_BUF_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_dhd_wlfc_info_buf) {\r
+               pr_err("Failed to alloc wlan_static_dhd_wlfc_info_buf\n");\r
                goto err_mem_alloc;\r
-       printk("6 %s: wlan_static_scan_buf1=%p, size=%d\n",\r
-               __FUNCTION__, wlan_static_scan_buf1, 65536);\r
+       }\r
+       printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_DHD_WLFC_INFO, WLAN_DHD_WLFC_BUF_SIZE);\r
+\r
+#ifdef CONFIG_BCMDHD_PCIE\r
+       wlan_static_if_flow_lkup = kmalloc(DHD_PREALLOC_IF_FLOW_LKUP_SIZE, GFP_KERNEL);\r
+       if (!wlan_static_if_flow_lkup) {\r
+               pr_err("Failed to alloc wlan_static_if_flow_lkup\n");\r
+               goto err_mem_alloc;\r
+       }\r
+#endif /* CONFIG_BCMDHD_PCIE */\r
 \r
-       printk("%s: WIFI MEM Allocated\n", __FUNCTION__);\r
        return 0;\r
 \r
 err_mem_alloc:\r
+\r
+       if (wlan_static_prot)\r
+               kfree(wlan_static_prot);\r
+\r
+#if defined(CONFIG_BCMDHD_SDIO)\r
+       if (wlan_static_rxbuf)\r
+               kfree(wlan_static_rxbuf);\r
+\r
+       if (wlan_static_databuf)\r
+               kfree(wlan_static_databuf);\r
+#endif\r
+\r
+       if (wlan_static_dhd_info_buf)\r
+               kfree(wlan_static_dhd_info_buf);\r
+\r
+       if (wlan_static_dhd_wlfc_info_buf)\r
+               kfree(wlan_static_dhd_wlfc_info_buf);\r
+\r
+       if (wlan_static_scan_buf1)\r
+               kfree(wlan_static_scan_buf1);\r
+\r
+       if (wlan_static_scan_buf0)\r
+               kfree(wlan_static_scan_buf0);\r
+\r
+       if (wlan_static_osl_buf)\r
+               kfree(wlan_static_osl_buf);\r
+\r
+#ifdef CONFIG_BCMDHD_PCIE\r
+       if (wlan_static_if_flow_lkup)\r
+               kfree(wlan_static_if_flow_lkup);\r
+#endif\r
        pr_err("Failed to mem_alloc for WLAN\n");\r
-       for (j=0; j<i; j++)\r
-               kfree(wlan_mem_array[j].mem_ptr);\r
 \r
        i = WLAN_SKB_BUF_NUM;\r
 \r
 err_skb_alloc:\r
        pr_err("Failed to skb_alloc for WLAN\n");\r
-       for (j=0; j<i; j++)\r
+       for (j = 0; j < i; j++) {\r
                dev_kfree_skb(wlan_static_skb[j]);\r
+       }\r
 \r
        return -ENOMEM;\r
 }\r
-#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */\r
 \r
-static int __init bcmdhd_wlan_init(void)\r
+static int __init\r
+dhd_static_buf_init(void)\r
 {\r
-       printk("%s()\n", __FUNCTION__);\r
+       printk(KERN_ERR "%s()\n", __FUNCTION__);\r
 \r
-#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM\r
-       bcmdhd_init_wlan_mem();\r
-#endif\r
+       dhd_init_wlan_mem();\r
 \r
        return 0;\r
 }\r
 \r
-__initcall(bcmdhd_wlan_init);\r
+static void __exit\r
+dhd_static_buf_exit(void)\r
+{\r
+       int i;\r
+\r
+       printk(KERN_ERR "%s()\n", __FUNCTION__);\r
+\r
+       for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {\r
+               if (wlan_static_skb[i])\r
+                       dev_kfree_skb(wlan_static_skb[i]);\r
+       }\r
+\r
+       for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {\r
+               if (wlan_static_skb[i])\r
+                       dev_kfree_skb(wlan_static_skb[i]);\r
+       }\r
+\r
+#if !defined(CONFIG_BCMDHD_PCIE)\r
+       if (wlan_static_skb[i])\r
+               dev_kfree_skb(wlan_static_skb[i]);\r
+#endif /* !CONFIG_BCMDHD_PCIE */\r
+\r
+       if (wlan_static_prot)\r
+               kfree(wlan_static_prot);\r
+\r
+#if defined(CONFIG_BCMDHD_SDIO)\r
+       if (wlan_static_rxbuf)\r
+               kfree(wlan_static_rxbuf);\r
+\r
+       if (wlan_static_databuf)\r
+               kfree(wlan_static_databuf);\r
+#endif\r
+\r
+       if (wlan_static_osl_buf)\r
+               kfree(wlan_static_osl_buf);\r
+\r
+       if (wlan_static_scan_buf0)\r
+               kfree(wlan_static_scan_buf0);\r
+\r
+       if (wlan_static_dhd_info_buf)\r
+               kfree(wlan_static_dhd_info_buf);\r
+\r
+       if (wlan_static_dhd_wlfc_info_buf)\r
+               kfree(wlan_static_dhd_wlfc_info_buf);\r
+\r
+       if (wlan_static_scan_buf1)\r
+               kfree(wlan_static_scan_buf1);\r
+\r
+#ifdef CONFIG_BCMDHD_PCIE\r
+       if (wlan_static_if_flow_lkup)\r
+               kfree(wlan_static_if_flow_lkup);\r
+#endif\r
+       return;\r
+}\r
+\r
+module_init(dhd_static_buf_init);\r
+\r
+module_exit(dhd_static_buf_exit);\r
index 0e74318d173a3b7b2a21693b71e1d7ae5d8fc722..9e5e46da48c3bed556722dfbb1ff4db9a36a2e66 100755 (executable)
@@ -41,6 +41,7 @@
 #include <dhd_bus.h>
 
 #include <dhd_dbg.h>
+#include <dhd_config.h>
 
 #ifdef PROP_TXSTATUS /* a form of flow control between host and dongle */
 #include <wlfc_proto.h>
@@ -3538,7 +3539,7 @@ dhd_wlfc_init(dhd_pub_t *dhd)
 
        dhd_os_wlfc_block(dhd);
        if (dhd->wlfc_enabled) {
-               DHD_INFO(("%s():%d, Already enabled!\n", __FUNCTION__, __LINE__));
+               DHD_ERROR(("%s():%d, Already enabled!\n", __FUNCTION__, __LINE__));
                dhd_os_wlfc_unblock(dhd);
                return BCME_OK;
        }
@@ -3563,8 +3564,10 @@ dhd_wlfc_init(dhd_pub_t *dhd)
                Leaving the message for now, it should be removed after a while; once
                the tlv situation is stable.
                */
-               DHD_INFO(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n",
+               DHD_ERROR(("dhd_wlfc_init(): successfully %s bdcv2 tlv signaling, %d\n",
                        dhd->wlfc_enabled?"enabled":"disabled", tlv));
+               /* terence 20161229: enable ampdu_hostreorder if tlv enable hostreorder */
+               dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_hostreorder", 1, 0, TRUE);
        }
 
        mode = 0;
@@ -3573,7 +3576,7 @@ dhd_wlfc_init(dhd_pub_t *dhd)
        ret = dhd_wl_ioctl_get_intiovar(dhd, "wlfc_mode", &fw_caps, WLC_GET_VAR, FALSE, 0);
 
        if (!ret) {
-               DHD_INFO(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps));
+               DHD_ERROR(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps));
 
                if (WLFC_IS_OLD_DEF(fw_caps)) {
                        /* enable proptxtstatus v2 by default */
@@ -3597,7 +3600,7 @@ dhd_wlfc_init(dhd_pub_t *dhd)
                }
        }
 
-       DHD_INFO(("dhd_wlfc_init(): wlfc_mode=0x%x, ret=%d\n", dhd->wlfc_mode, ret));
+       DHD_ERROR(("dhd_wlfc_init(): wlfc_mode=0x%x, ret=%d\n", dhd->wlfc_mode, ret));
 
        dhd_os_wlfc_unblock(dhd);
 
@@ -3639,6 +3642,8 @@ dhd_wlfc_hostreorder_init(dhd_pub_t *dhd)
        dhd_os_wlfc_block(dhd);
        dhd->proptxstatus_mode = WLFC_ONLY_AMPDU_HOSTREORDER;
        dhd_os_wlfc_unblock(dhd);
+       /* terence 20161229: enable ampdu_hostreorder if tlv enable hostreorder */
+       dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "ampdu_hostreorder", 1, 0, TRUE);
 
        return BCME_OK;
 }
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/Makefile b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/Makefile
deleted file mode 100755 (executable)
index bc90f3c..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-#
-# This script serves following purpose:
-#
-# 1. It generates native version information by querying
-#    automerger maintained database to see where src/include
-#    came from
-# 2. For select components, as listed in compvers.sh
-#    it generates component version files
-#
-# Copyright 2005, Broadcom, Inc.
-#
-# $Id: Makefile 347587 2012-07-27 09:13:31Z $
-#
-
-export SRCBASE:=..
-
-TARGETS := epivers.h
-
-ifdef VERBOSE
-export VERBOSE
-endif
-
-all release: epivers compvers
-
-# Generate epivers.h for native branch url
-epivers:
-       bash epivers.sh
-
-# Generate component versions based on component url
-compvers:
-       @if [ -s "compvers.sh" ]; then \
-               echo "Generating component versions, if any"; \
-               bash compvers.sh; \
-       else \
-               echo "Skipping component version generation"; \
-       fi
-
-# Generate epivers.h for native branch version
-clean_compvers:
-       @if [ -s "compvers.sh" ]; then \
-               echo "bash compvers.sh clean"; \
-               bash compvers.sh clean; \
-       else \
-               echo "Skipping component version clean"; \
-       fi
-
-clean:
-       rm -f $(TARGETS) *.prev
-
-clean_all: clean clean_compvers
-
-.PHONY: all release clean epivers compvers clean_compvers
index e6b436479503ecfa4358f9c841894b2c08b88b2e..56ea1d49b40f7d413d0946ae981b4689d0fae376 100755 (executable)
@@ -53,7 +53,7 @@
 #ifdef CUSTOM_MAX_TXGLOM_SIZE
 #define SDPCM_MAXGLOM_SIZE  CUSTOM_MAX_TXGLOM_SIZE
 #else
-#define SDPCM_MAXGLOM_SIZE     40
+#define SDPCM_MAXGLOM_SIZE     36
 #endif /* CUSTOM_MAX_TXGLOM_SIZE */
 
 #define SDPCM_TXGLOM_CPY 0                     /* SDIO 2.0 should use copy mode */
 #define SDPCM_DEFGLOM_SIZE SDPCM_MAXGLOM_SIZE
 #endif
 
+#ifdef PKT_STATICS
+typedef struct pkt_statics {
+       uint16  event_count;
+       uint32  event_size;
+       uint16  ctrl_count;
+       uint32  ctrl_size;
+       uint32  data_count;
+       uint32  data_size;
+       uint32  glom_cnt[SDPCM_MAXGLOM_SIZE];
+       uint16  glom_max;
+       uint16  glom_count;
+       uint32  glom_size;
+       uint16  test_count;
+       uint32  test_size;
+} pkt_statics_t;
+#endif
+
 typedef int SDIOH_API_RC;
 
 /* SDio Host structure */
index 60832f66e82eb4ae24d73b6cc8800397b7a97c70..1bd35b527b9d0449487f58e12855751739f0a52f 100755 (executable)
@@ -36,6 +36,7 @@
 #define sd_debug(x)    do { if (sd_msglevel & SDH_DEBUG_VAL) printf x; } while (0)
 #define sd_data(x)     do { if (sd_msglevel & SDH_DATA_VAL) printf x; } while (0)
 #define sd_ctrl(x)     do { if (sd_msglevel & SDH_CTRL_VAL) printf x; } while (0)
+#define sd_cost(x)     do { if (sd_msglevel & SDH_COST_VAL) printf x; } while (0)
 
 #define sd_sync_dma(sd, read, nbytes)
 #define sd_init_dma(sd)
@@ -59,7 +60,7 @@
 /* private bus modes */
 #define SDIOH_MODE_SD4         2
 #define CLIENT_INTR                    0x100   /* Get rid of this! */
-#define SDIOH_SDMMC_MAX_SG_ENTRIES     32
+#define SDIOH_SDMMC_MAX_SG_ENTRIES     SDPCM_MAXGLOM_SIZE
 
 #if defined(SWTXGLOM)
 typedef struct glom_buf {
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmwifi_channels.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmwifi_channels.h
deleted file mode 100755 (executable)
index b96aee6..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Misc utility routines for WL and Apps
- * This header file housing the define and function prototype use by
- * both the wl driver, tools & Apps.
- *
- * $Copyright Open Broadcom Corporation$
- *
- * $Id: bcmwifi_channels.h 309193 2012-01-19 00:03:57Z $
- */
-
-#ifndef        _bcmwifi_channels_h_
-#define        _bcmwifi_channels_h_
-
-
-/* A chanspec holds the channel number, band, bandwidth and control sideband */
-typedef uint16 chanspec_t;
-
-/* channel defines */
-#define CH_UPPER_SB                    0x01
-#define CH_LOWER_SB                    0x02
-#define CH_EWA_VALID                   0x04
-#define CH_80MHZ_APART                 16
-#define CH_40MHZ_APART                 8
-#define CH_20MHZ_APART                 4
-#define CH_10MHZ_APART                 2
-#define CH_5MHZ_APART                  1       /* 2G band channels are 5 Mhz apart */
-#define CH_MAX_2G_CHANNEL              14      /* Max channel in 2G band */
-#define MAXCHANNEL             224     /* max # supported channels. The max channel no is above,
-                                        * this is that + 1 rounded up to a multiple of NBBY (8).
-                                        * DO NOT MAKE it > 255: channels are uint8's all over
-                                        */
-#define MAXCHANNEL_NUM (MAXCHANNEL - 1)        /* max channel number */
-
-/* make sure channel num is within valid range */
-#define CH_NUM_VALID_RANGE(ch_num) ((ch_num) > 0 && (ch_num) <= MAXCHANNEL_NUM)
-
-#define CHSPEC_CTLOVLP(sp1, sp2, sep)  (ABS(wf_chspec_ctlchan(sp1) - wf_chspec_ctlchan(sp2)) < \
-                                 (sep))
-
-/* All builds use the new 11ac ratespec/chanspec */
-#undef  D11AC_IOTYPES
-#define D11AC_IOTYPES
-
-#define WL_CHANSPEC_CHAN_MASK          0x00ff
-#define WL_CHANSPEC_CHAN_SHIFT         0
-#define WL_CHANSPEC_CHAN1_MASK         0x000f
-#define WL_CHANSPEC_CHAN1_SHIFT                0
-#define WL_CHANSPEC_CHAN2_MASK         0x00f0
-#define WL_CHANSPEC_CHAN2_SHIFT                4
-
-#define WL_CHANSPEC_CTL_SB_MASK                0x0700
-#define WL_CHANSPEC_CTL_SB_SHIFT       8
-#define WL_CHANSPEC_CTL_SB_LLL         0x0000
-#define WL_CHANSPEC_CTL_SB_LLU         0x0100
-#define WL_CHANSPEC_CTL_SB_LUL         0x0200
-#define WL_CHANSPEC_CTL_SB_LUU         0x0300
-#define WL_CHANSPEC_CTL_SB_ULL         0x0400
-#define WL_CHANSPEC_CTL_SB_ULU         0x0500
-#define WL_CHANSPEC_CTL_SB_UUL         0x0600
-#define WL_CHANSPEC_CTL_SB_UUU         0x0700
-#define WL_CHANSPEC_CTL_SB_LL          WL_CHANSPEC_CTL_SB_LLL
-#define WL_CHANSPEC_CTL_SB_LU          WL_CHANSPEC_CTL_SB_LLU
-#define WL_CHANSPEC_CTL_SB_UL          WL_CHANSPEC_CTL_SB_LUL
-#define WL_CHANSPEC_CTL_SB_UU          WL_CHANSPEC_CTL_SB_LUU
-#define WL_CHANSPEC_CTL_SB_L           WL_CHANSPEC_CTL_SB_LLL
-#define WL_CHANSPEC_CTL_SB_U           WL_CHANSPEC_CTL_SB_LLU
-#define WL_CHANSPEC_CTL_SB_LOWER       WL_CHANSPEC_CTL_SB_LLL
-#define WL_CHANSPEC_CTL_SB_UPPER       WL_CHANSPEC_CTL_SB_LLU
-#define WL_CHANSPEC_CTL_SB_NONE                WL_CHANSPEC_CTL_SB_LLL
-
-#define WL_CHANSPEC_BW_MASK            0x3800
-#define WL_CHANSPEC_BW_SHIFT           11
-#define WL_CHANSPEC_BW_5               0x0000
-#define WL_CHANSPEC_BW_10              0x0800
-#define WL_CHANSPEC_BW_20              0x1000
-#define WL_CHANSPEC_BW_40              0x1800
-#define WL_CHANSPEC_BW_80              0x2000
-#define WL_CHANSPEC_BW_160             0x2800
-#define WL_CHANSPEC_BW_8080            0x3000
-
-#define WL_CHANSPEC_BAND_MASK          0xc000
-#define WL_CHANSPEC_BAND_SHIFT         14
-#define WL_CHANSPEC_BAND_2G            0x0000
-#define WL_CHANSPEC_BAND_3G            0x4000
-#define WL_CHANSPEC_BAND_4G            0x8000
-#define WL_CHANSPEC_BAND_5G            0xc000
-#define INVCHANSPEC                    255
-
-/* channel defines */
-#define LOWER_20_SB(channel)           (((channel) > CH_10MHZ_APART) ? \
-                                       ((channel) - CH_10MHZ_APART) : 0)
-#define UPPER_20_SB(channel)           (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \
-                                       ((channel) + CH_10MHZ_APART) : 0)
-
-#define LL_20_SB(channel) (((channel) > 3 * CH_10MHZ_APART) ? ((channel) - 3 * CH_10MHZ_APART) : 0)
-#define UU_20_SB(channel)      (((channel) < (MAXCHANNEL - 3 * CH_10MHZ_APART)) ? \
-                               ((channel) + 3 * CH_10MHZ_APART) : 0)
-#define LU_20_SB(channel) LOWER_20_SB(channel)
-#define UL_20_SB(channel) UPPER_20_SB(channel)
-
-#define LOWER_40_SB(channel)           ((channel) - CH_20MHZ_APART)
-#define UPPER_40_SB(channel)           ((channel) + CH_20MHZ_APART)
-#define CHSPEC_WLCBANDUNIT(chspec)     (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX)
-#define CH20MHZ_CHSPEC(channel)                (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \
-                                       (((channel) <= CH_MAX_2G_CHANNEL) ? \
-                                       WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G))
-#define NEXT_20MHZ_CHAN(channel)       (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \
-                                       ((channel) + CH_20MHZ_APART) : 0)
-#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
-                                       ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \
-                                       ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \
-                                       WL_CHANSPEC_BAND_5G))
-#define CH80MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \
-                                       ((channel) | (ctlsb) | \
-                                        WL_CHANSPEC_BW_80 | WL_CHANSPEC_BAND_5G)
-#define CH160MHZ_CHSPEC(channel, ctlsb)        (chanspec_t) \
-                                       ((channel) | (ctlsb) | \
-                                        WL_CHANSPEC_BW_160 | WL_CHANSPEC_BAND_5G)
-
-/* simple MACROs to get different fields of chanspec */
-#ifdef WL11AC_80P80
-#define CHSPEC_CHANNEL(chspec) wf_chspec_channel(chspec)
-#else
-#define CHSPEC_CHANNEL(chspec) ((uint8)((chspec) & WL_CHANSPEC_CHAN_MASK))
-#endif
-#define CHSPEC_CHAN1(chspec)   ((chspec) & WL_CHANSPEC_CHAN1_MASK) >> WL_CHANSPEC_CHAN1_SHIFT
-#define CHSPEC_CHAN2(chspec)   ((chspec) & WL_CHANSPEC_CHAN2_MASK) >> WL_CHANSPEC_CHAN2_SHIFT
-#define CHSPEC_BAND(chspec)            ((chspec) & WL_CHANSPEC_BAND_MASK)
-#define CHSPEC_CTL_SB(chspec)  ((chspec) & WL_CHANSPEC_CTL_SB_MASK)
-#define CHSPEC_BW(chspec)              ((chspec) & WL_CHANSPEC_BW_MASK)
-
-#ifdef WL11N_20MHZONLY
-
-#define CHSPEC_IS10(chspec)    0
-#define CHSPEC_IS20(chspec)    1
-#ifndef CHSPEC_IS40
-#define CHSPEC_IS40(chspec)    0
-#endif
-#ifndef CHSPEC_IS80
-#define CHSPEC_IS80(chspec)    0
-#endif
-#ifndef CHSPEC_IS160
-#define CHSPEC_IS160(chspec)   0
-#endif
-#ifndef CHSPEC_IS8080
-#define CHSPEC_IS8080(chspec)  0
-#endif
-
-#else /* !WL11N_20MHZONLY */
-
-#define CHSPEC_IS10(chspec)    (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10)
-#define CHSPEC_IS20(chspec)    (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20)
-#ifndef CHSPEC_IS40
-#define CHSPEC_IS40(chspec)    (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40)
-#endif
-#ifndef CHSPEC_IS80
-#define CHSPEC_IS80(chspec)    (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_80)
-#endif
-#ifndef CHSPEC_IS160
-#define CHSPEC_IS160(chspec)   (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_160)
-#endif
-#ifndef CHSPEC_IS8080
-#define CHSPEC_IS8080(chspec)  (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_8080)
-#endif
-
-#endif /* !WL11N_20MHZONLY */
-
-#define CHSPEC_IS5G(chspec)    (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G)
-#define CHSPEC_IS2G(chspec)    (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G)
-#define CHSPEC_SB_UPPER(chspec)        \
-       ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) && \
-       (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
-#define CHSPEC_SB_LOWER(chspec)        \
-       ((((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) && \
-       (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40))
-#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G)
-
-/**
- * Number of chars needed for wf_chspec_ntoa() destination character buffer.
- */
-#define CHANSPEC_STR_LEN    20
-
-
-#define CHSPEC_IS_BW_160_WIDE(chspec) (CHSPEC_BW(chspec) == WL_CHANSPEC_BW_160 ||\
-       CHSPEC_BW(chspec) == WL_CHANSPEC_BW_8080)
-
-/* BW inequality comparisons, LE (<=), GE (>=), LT (<), GT (>), comparisons can be made
-* as simple numeric comparisons, with the exception that 160 is the same BW as 80+80,
-* but have different numeric values; (WL_CHANSPEC_BW_160 < WL_CHANSPEC_BW_8080).
-*
-* The LT/LE/GT/GE macros check first checks whether both chspec bandwidth and bw are 160 wide.
-* If both chspec bandwidth and bw is not 160 wide, then the comparison is made.
-*/
-#define CHSPEC_BW_GE(chspec, bw) \
-       ((CHSPEC_IS_BW_160_WIDE(chspec) &&\
-       (bw == WL_CHANSPEC_BW_160 || bw == WL_CHANSPEC_BW_8080)) ||\
-       (CHSPEC_BW(chspec) >= bw))
-
-#define CHSPEC_BW_LE(chspec, bw) \
-       ((CHSPEC_IS_BW_160_WIDE(chspec) &&\
-       (bw == WL_CHANSPEC_BW_160 || bw == WL_CHANSPEC_BW_8080)) ||\
-       (CHSPEC_BW(chspec) <= bw))
-
-#define CHSPEC_BW_GT(chspec, bw) \
-       (!(CHSPEC_IS_BW_160_WIDE(chspec) &&\
-       (bw == WL_CHANSPEC_BW_160 || bw == WL_CHANSPEC_BW_8080)) &&\
-       (CHSPEC_BW(chspec) > bw))
-
-#define CHSPEC_BW_LT(chspec, bw) \
-       (!(CHSPEC_IS_BW_160_WIDE(chspec) &&\
-       (bw == WL_CHANSPEC_BW_160 || bw == WL_CHANSPEC_BW_8080)) &&\
-       (CHSPEC_BW(chspec) < bw))
-
-/* Legacy Chanspec defines
- * These are the defines for the previous format of the chanspec_t
- */
-#define WL_LCHANSPEC_CHAN_MASK         0x00ff
-#define WL_LCHANSPEC_CHAN_SHIFT                     0
-
-#define WL_LCHANSPEC_CTL_SB_MASK       0x0300
-#define WL_LCHANSPEC_CTL_SB_SHIFT           8
-#define WL_LCHANSPEC_CTL_SB_LOWER      0x0100
-#define WL_LCHANSPEC_CTL_SB_UPPER      0x0200
-#define WL_LCHANSPEC_CTL_SB_NONE       0x0300
-
-#define WL_LCHANSPEC_BW_MASK           0x0C00
-#define WL_LCHANSPEC_BW_SHIFT              10
-#define WL_LCHANSPEC_BW_10             0x0400
-#define WL_LCHANSPEC_BW_20             0x0800
-#define WL_LCHANSPEC_BW_40             0x0C00
-
-#define WL_LCHANSPEC_BAND_MASK         0xf000
-#define WL_LCHANSPEC_BAND_SHIFT                    12
-#define WL_LCHANSPEC_BAND_5G           0x1000
-#define WL_LCHANSPEC_BAND_2G           0x2000
-
-#define LCHSPEC_CHANNEL(chspec)        ((uint8)((chspec) & WL_LCHANSPEC_CHAN_MASK))
-#define LCHSPEC_BAND(chspec)   ((chspec) & WL_LCHANSPEC_BAND_MASK)
-#define LCHSPEC_CTL_SB(chspec) ((chspec) & WL_LCHANSPEC_CTL_SB_MASK)
-#define LCHSPEC_BW(chspec)     ((chspec) & WL_LCHANSPEC_BW_MASK)
-#define LCHSPEC_IS10(chspec)   (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_10)
-#define LCHSPEC_IS20(chspec)   (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_20)
-#define LCHSPEC_IS40(chspec)   (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40)
-#define LCHSPEC_IS5G(chspec)   (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_5G)
-#define LCHSPEC_IS2G(chspec)   (((chspec) & WL_LCHANSPEC_BAND_MASK) == WL_LCHANSPEC_BAND_2G)
-
-#define LCHSPEC_SB_UPPER(chspec)       \
-       ((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_UPPER) && \
-       (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
-#define LCHSPEC_SB_LOWER(chspec)       \
-       ((((chspec) & WL_LCHANSPEC_CTL_SB_MASK) == WL_LCHANSPEC_CTL_SB_LOWER) && \
-       (((chspec) & WL_LCHANSPEC_BW_MASK) == WL_LCHANSPEC_BW_40))
-
-#define LCHSPEC_CREATE(chan, band, bw, sb)  ((uint16)((chan) | (sb) | (bw) | (band)))
-
-#define CH20MHZ_LCHSPEC(channel) \
-       (chanspec_t)((chanspec_t)(channel) | WL_LCHANSPEC_BW_20 | \
-       WL_LCHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \
-       WL_LCHANSPEC_BAND_2G : WL_LCHANSPEC_BAND_5G))
-
-/*
- * WF_CHAN_FACTOR_* constants are used to calculate channel frequency
- * given a channel number.
- * chan_freq = chan_factor * 500Mhz + chan_number * 5
- */
-
-/**
- * Channel Factor for the starting frequence of 2.4 GHz channels.
- * The value corresponds to 2407 MHz.
- */
-#define WF_CHAN_FACTOR_2_4_G           4814    /* 2.4 GHz band, 2407 MHz */
-
-/**
- * Channel Factor for the starting frequence of 5 GHz channels.
- * The value corresponds to 5000 MHz.
- */
-#define WF_CHAN_FACTOR_5_G             10000   /* 5   GHz band, 5000 MHz */
-
-/**
- * Channel Factor for the starting frequence of 4.9 GHz channels.
- * The value corresponds to 4000 MHz.
- */
-#define WF_CHAN_FACTOR_4_G             8000    /* 4.9 GHz band for Japan */
-
-#define WLC_2G_25MHZ_OFFSET            5       /* 2.4GHz band channel offset */
-
-/**
- *  No of sub-band vlaue of the specified Mhz chanspec
- */
-#define WF_NUM_SIDEBANDS_40MHZ   2
-#define WF_NUM_SIDEBANDS_80MHZ   4
-#define WF_NUM_SIDEBANDS_8080MHZ 4
-#define WF_NUM_SIDEBANDS_160MHZ  8
-
-/**
- * Convert chanspec to ascii string
- *
- * @param      chspec          chanspec format
- * @param      buf             ascii string of chanspec
- *
- * @return     pointer to buf with room for at least CHANSPEC_STR_LEN bytes
- *             Original chanspec in case of error
- *
- * @see                CHANSPEC_STR_LEN
- */
-extern char * wf_chspec_ntoa_ex(chanspec_t chspec, char *buf);
-
-/**
- * Convert chanspec to ascii string
- *
- * @param      chspec          chanspec format
- * @param      buf             ascii string of chanspec
- *
- * @return     pointer to buf with room for at least CHANSPEC_STR_LEN bytes
- *             NULL in case of error
- *
- * @see                CHANSPEC_STR_LEN
- */
-extern char * wf_chspec_ntoa(chanspec_t chspec, char *buf);
-
-/**
- * Convert ascii string to chanspec
- *
- * @param      a     pointer to input string
- *
- * @return     >= 0 if successful or 0 otherwise
- */
-extern chanspec_t wf_chspec_aton(const char *a);
-
-/**
- * Verify the chanspec fields are valid.
- *
- * Verify the chanspec is using a legal set field values, i.e. that the chanspec
- * specified a band, bw, ctl_sb and channel and that the combination could be
- * legal given some set of circumstances.
- *
- * @param      chanspec   input chanspec to verify
- *
- * @return TRUE if the chanspec is malformed, FALSE if it looks good.
- */
-extern bool wf_chspec_malformed(chanspec_t chanspec);
-
-/**
- * Verify the chanspec specifies a valid channel according to 802.11.
- *
- * @param      chanspec   input chanspec to verify
- *
- * @return TRUE if the chanspec is a valid 802.11 channel
- */
-extern bool wf_chspec_valid(chanspec_t chanspec);
-
-/**
- * Return the primary (control) channel.
- *
- * This function returns the channel number of the primary 20MHz channel. For
- * 20MHz channels this is just the channel number. For 40MHz or wider channels
- * it is the primary 20MHz channel specified by the chanspec.
- *
- * @param      chspec    input chanspec
- *
- * @return Returns the channel number of the primary 20MHz channel
- */
-extern uint8 wf_chspec_ctlchan(chanspec_t chspec);
-
-/**
- * Return the bandwidth string.
- *
- * This function returns the bandwidth string for the passed chanspec.
- *
- * @param      chspec    input chanspec
- *
- * @return Returns the bandwidth string
- */
-extern char * wf_chspec_to_bw_str(chanspec_t chspec);
-
-/**
- * Return the primary (control) chanspec.
- *
- * This function returns the chanspec of the primary 20MHz channel. For 20MHz
- * channels this is just the chanspec. For 40MHz or wider channels it is the
- * chanspec of the primary 20MHZ channel specified by the chanspec.
- *
- * @param      chspec    input chanspec
- *
- * @return Returns the chanspec of the primary 20MHz channel
- */
-extern chanspec_t wf_chspec_ctlchspec(chanspec_t chspec);
-
-/**
- * Return a channel number corresponding to a frequency.
- *
- * This function returns the chanspec for the primary 40MHz of an 80MHz channel.
- * The control sideband specifies the same 20MHz channel that the 80MHz channel is using
- * as the primary 20MHz channel.
- */
-extern chanspec_t wf_chspec_primary40_chspec(chanspec_t chspec);
-
-/*
- * Return the channel number for a given frequency and base frequency.
- * The returned channel number is relative to the given base frequency.
- * If the given base frequency is zero, a base frequency of 5 GHz is assumed for
- * frequencies from 5 - 6 GHz, and 2.407 GHz is assumed for 2.4 - 2.5 GHz.
- *
- * Frequency is specified in MHz.
- * The base frequency is specified as (start_factor * 500 kHz).
- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
- * 2.4 GHz and 5 GHz bands.
- *
- * The returned channel will be in the range [1, 14] in the 2.4 GHz band
- * and [0, 200] otherwise.
- * -1 is returned if the start_factor is WF_CHAN_FACTOR_2_4_G and the
- * frequency is not a 2.4 GHz channel, or if the frequency is not and even
- * multiple of 5 MHz from the base frequency to the base plus 1 GHz.
- *
- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
- *
- * @param      freq          frequency in MHz
- * @param      start_factor  base frequency in 500 kHz units, e.g. 10000 for 5 GHz
- *
- * @return Returns a channel number
- *
- * @see  WF_CHAN_FACTOR_2_4_G
- * @see  WF_CHAN_FACTOR_5_G
- */
-extern int wf_mhz2channel(uint freq, uint start_factor);
-
-/**
- * Return the center frequency in MHz of the given channel and base frequency.
- *
- * Return the center frequency in MHz of the given channel and base frequency.
- * The channel number is interpreted relative to the given base frequency.
- *
- * The valid channel range is [1, 14] in the 2.4 GHz band and [0, 200] otherwise.
- * The base frequency is specified as (start_factor * 500 kHz).
- * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G are defined for
- * 2.4 GHz and 5 GHz bands.
- * The channel range of [1, 14] is only checked for a start_factor of
- * WF_CHAN_FACTOR_2_4_G (4814).
- * Odd start_factors produce channels on .5 MHz boundaries, in which case
- * the answer is rounded down to an integral MHz.
- * -1 is returned for an out of range channel.
- *
- * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
- *
- * @param      channel       input channel number
- * @param      start_factor  base frequency in 500 kHz units, e.g. 10000 for 5 GHz
- *
- * @return Returns a frequency in MHz
- *
- * @see  WF_CHAN_FACTOR_2_4_G
- * @see  WF_CHAN_FACTOR_5_G
- */
-extern int wf_channel2mhz(uint channel, uint start_factor);
-
-/**
- * Returns the chanspec 80Mhz channel corresponding to the following input
- * parameters
- *
- *     primary_channel - primary 20Mhz channel
- *     center_channel   - center frequecny of the 80Mhz channel
- *
- * The center_channel can be one of {42, 58, 106, 122, 138, 155}
- *
- * returns INVCHANSPEC in case of error
- */
-extern chanspec_t wf_chspec_80(uint8 center_channel, uint8 primary_channel);
-
-/**
- * Convert ctl chan and bw to chanspec
- *
- * @param      ctl_ch          channel
- * @param      bw              bandwidth
- *
- * @return     > 0 if successful or 0 otherwise
- *
- */
-extern uint16 wf_channel2chspec(uint ctl_ch, uint bw);
-
-extern uint wf_channel2freq(uint channel);
-extern uint wf_freq2channel(uint freq);
-
-/*
- * Returns the 80+80 MHz chanspec corresponding to the following input parameters
- *
- *    primary_20mhz - Primary 20 MHz channel
- *    chan0_80MHz - center channel number of one frequency segment
- *    chan1_80MHz - center channel number of the other frequency segment
- *
- * Parameters chan0_80MHz and chan1_80MHz are channel numbers in {42, 58, 106, 122, 138, 155}.
- * The primary channel must be contained in one of the 80MHz channels. This routine
- * will determine which frequency segment is the primary 80 MHz segment.
- *
- * Returns INVCHANSPEC in case of error.
- *
- * Refer to IEEE802.11ac section 22.3.14 "Channelization".
- */
-extern chanspec_t wf_chspec_get8080_chspec(uint8 primary_20mhz,
-       uint8 chan0_80Mhz, uint8 chan1_80Mhz);
-
-/*
- * Returns the primary 80 Mhz channel for the provided chanspec
- *
- *    chanspec - Input chanspec for which the 80MHz primary channel has to be retrieved
- *
- *  returns -1 in case the provided channel is 20/40 Mhz chanspec
- */
-extern uint8 wf_chspec_primary80_channel(chanspec_t chanspec);
-
-/*
- * Returns the secondary 80 Mhz channel for the provided chanspec
- *
- *    chanspec - Input chanspec for which the 80MHz secondary channel has to be retrieved
- *
- *  returns -1 in case the provided channel is 20/40 Mhz chanspec
- */
-extern uint8 wf_chspec_secondary80_channel(chanspec_t chanspec);
-
-/*
- * This function returns the chanspec for the primary 80MHz of an 160MHz or 80+80 channel.
- */
-extern chanspec_t wf_chspec_primary80_chspec(chanspec_t chspec);
-
-#ifdef WL11AC_80P80
-/*
- * This function returns the centre chanel for the given chanspec.
- * In case of 80+80 chanspec it returns the primary 80 Mhz centre channel
- */
-extern uint8 wf_chspec_channel(chanspec_t chspec);
-#endif
-#endif /* _bcmwifi_channels_h_ */
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmwifi_rates.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/bcmwifi_rates.h
deleted file mode 100755 (executable)
index cf5f88d..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
- *
- * $Copyright Open Broadcom Corporation$
- *
- * $Id: bcmwifi_rates.h 5187 2012-06-29 06:17:50Z $
- */
-
-#ifndef _bcmwifi_rates_h_
-#define _bcmwifi_rates_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#define WL_RATESET_SZ_DSSS             4
-#define WL_RATESET_SZ_OFDM             8
-#define WL_RATESET_SZ_VHT_MCS  10
-
-#if defined(WLPROPRIETARY_11N_RATES)
-#define WL_RATESET_SZ_HT_MCS   WL_RATESET_SZ_VHT_MCS
-#else
-#define WL_RATESET_SZ_HT_MCS   8
-#endif
-
-#define WL_RATESET_SZ_HT_IOCTL 8       /* MAC histogram, compatibility with wl utility */
-
-#define WL_TX_CHAINS_MAX       3
-
-#define WL_RATE_DISABLED               (-128) /* Power value corresponding to unsupported rate */
-
-/* Transmit channel bandwidths */
-typedef enum wl_tx_bw {
-       WL_TX_BW_20,
-       WL_TX_BW_40,
-       WL_TX_BW_80,
-       WL_TX_BW_20IN40,
-       WL_TX_BW_20IN80,
-       WL_TX_BW_40IN80,
-       WL_TX_BW_160,
-       WL_TX_BW_20IN160,
-       WL_TX_BW_40IN160,
-       WL_TX_BW_80IN160,
-       WL_TX_BW_ALL,
-       WL_TX_BW_8080,
-       WL_TX_BW_8080CHAN2,
-       WL_TX_BW_20IN8080,
-       WL_TX_BW_40IN8080,
-       WL_TX_BW_80IN8080
-} wl_tx_bw_t;
-
-
-/*
- * Transmit modes.
- * Not all modes are listed here, only those required for disambiguation. e.g. SPEXP is not listed
- */
-typedef enum wl_tx_mode {
-       WL_TX_MODE_NONE,
-       WL_TX_MODE_STBC,
-       WL_TX_MODE_CDD,
-       WL_TX_MODE_TXBF,
-       WL_NUM_TX_MODES
-} wl_tx_mode_t;
-
-
-/* Number of transmit chains */
-typedef enum wl_tx_chains {
-       WL_TX_CHAINS_1 = 1,
-       WL_TX_CHAINS_2,
-       WL_TX_CHAINS_3
-} wl_tx_chains_t;
-
-
-/* Number of transmit streams */
-typedef enum wl_tx_nss {
-       WL_TX_NSS_1 = 1,
-       WL_TX_NSS_2,
-       WL_TX_NSS_3
-} wl_tx_nss_t;
-
-
-typedef enum clm_rates {
-       /************
-       * 1 chain  *
-       ************
-       */
-
-       /* 1 Stream */
-       WL_RATE_1X1_DSSS_1         = 0,
-       WL_RATE_1X1_DSSS_2         = 1,
-       WL_RATE_1X1_DSSS_5_5       = 2,
-       WL_RATE_1X1_DSSS_11        = 3,
-
-       WL_RATE_1X1_OFDM_6         = 4,
-       WL_RATE_1X1_OFDM_9         = 5,
-       WL_RATE_1X1_OFDM_12        = 6,
-       WL_RATE_1X1_OFDM_18        = 7,
-       WL_RATE_1X1_OFDM_24        = 8,
-       WL_RATE_1X1_OFDM_36        = 9,
-       WL_RATE_1X1_OFDM_48        = 10,
-       WL_RATE_1X1_OFDM_54        = 11,
-
-       WL_RATE_1X1_MCS0           = 12,
-       WL_RATE_1X1_MCS1           = 13,
-       WL_RATE_1X1_MCS2           = 14,
-       WL_RATE_1X1_MCS3           = 15,
-       WL_RATE_1X1_MCS4           = 16,
-       WL_RATE_1X1_MCS5           = 17,
-       WL_RATE_1X1_MCS6           = 18,
-       WL_RATE_1X1_MCS7           = 19,
-
-       WL_RATE_1X1_VHT0SS1        = 12,
-       WL_RATE_1X1_VHT1SS1        = 13,
-       WL_RATE_1X1_VHT2SS1        = 14,
-       WL_RATE_1X1_VHT3SS1        = 15,
-       WL_RATE_1X1_VHT4SS1        = 16,
-       WL_RATE_1X1_VHT5SS1        = 17,
-       WL_RATE_1X1_VHT6SS1        = 18,
-       WL_RATE_1X1_VHT7SS1        = 19,
-       WL_RATE_1X1_VHT8SS1        = 20,
-       WL_RATE_1X1_VHT9SS1        = 21,
-
-
-       /************
-       * 2 chains *
-       ************
-       */
-
-       /* 1 Stream expanded + 1 */
-       WL_RATE_1X2_DSSS_1         = 22,
-       WL_RATE_1X2_DSSS_2         = 23,
-       WL_RATE_1X2_DSSS_5_5       = 24,
-       WL_RATE_1X2_DSSS_11        = 25,
-
-       WL_RATE_1X2_CDD_OFDM_6     = 26,
-       WL_RATE_1X2_CDD_OFDM_9     = 27,
-       WL_RATE_1X2_CDD_OFDM_12    = 28,
-       WL_RATE_1X2_CDD_OFDM_18    = 29,
-       WL_RATE_1X2_CDD_OFDM_24    = 30,
-       WL_RATE_1X2_CDD_OFDM_36    = 31,
-       WL_RATE_1X2_CDD_OFDM_48    = 32,
-       WL_RATE_1X2_CDD_OFDM_54    = 33,
-
-       WL_RATE_1X2_CDD_MCS0       = 34,
-       WL_RATE_1X2_CDD_MCS1       = 35,
-       WL_RATE_1X2_CDD_MCS2       = 36,
-       WL_RATE_1X2_CDD_MCS3       = 37,
-       WL_RATE_1X2_CDD_MCS4       = 38,
-       WL_RATE_1X2_CDD_MCS5       = 39,
-       WL_RATE_1X2_CDD_MCS6       = 40,
-       WL_RATE_1X2_CDD_MCS7       = 41,
-
-       WL_RATE_1X2_VHT0SS1        = 34,
-       WL_RATE_1X2_VHT1SS1        = 35,
-       WL_RATE_1X2_VHT2SS1        = 36,
-       WL_RATE_1X2_VHT3SS1        = 37,
-       WL_RATE_1X2_VHT4SS1        = 38,
-       WL_RATE_1X2_VHT5SS1        = 39,
-       WL_RATE_1X2_VHT6SS1        = 40,
-       WL_RATE_1X2_VHT7SS1        = 41,
-       WL_RATE_1X2_VHT8SS1        = 42,
-       WL_RATE_1X2_VHT9SS1        = 43,
-
-       /* 2 Streams */
-       WL_RATE_2X2_STBC_MCS0      = 44,
-       WL_RATE_2X2_STBC_MCS1      = 45,
-       WL_RATE_2X2_STBC_MCS2      = 46,
-       WL_RATE_2X2_STBC_MCS3      = 47,
-       WL_RATE_2X2_STBC_MCS4      = 48,
-       WL_RATE_2X2_STBC_MCS5      = 49,
-       WL_RATE_2X2_STBC_MCS6      = 50,
-       WL_RATE_2X2_STBC_MCS7      = 51,
-
-       WL_RATE_2X2_STBC_VHT0SS1   = 44,
-       WL_RATE_2X2_STBC_VHT1SS1   = 45,
-       WL_RATE_2X2_STBC_VHT2SS1   = 46,
-       WL_RATE_2X2_STBC_VHT3SS1   = 47,
-       WL_RATE_2X2_STBC_VHT4SS1   = 48,
-       WL_RATE_2X2_STBC_VHT5SS1   = 49,
-       WL_RATE_2X2_STBC_VHT6SS1   = 50,
-       WL_RATE_2X2_STBC_VHT7SS1   = 51,
-       WL_RATE_2X2_STBC_VHT8SS1   = 52,
-       WL_RATE_2X2_STBC_VHT9SS1   = 53,
-
-       WL_RATE_2X2_SDM_MCS8       = 54,
-       WL_RATE_2X2_SDM_MCS9       = 55,
-       WL_RATE_2X2_SDM_MCS10      = 56,
-       WL_RATE_2X2_SDM_MCS11      = 57,
-       WL_RATE_2X2_SDM_MCS12      = 58,
-       WL_RATE_2X2_SDM_MCS13      = 59,
-       WL_RATE_2X2_SDM_MCS14      = 60,
-       WL_RATE_2X2_SDM_MCS15      = 61,
-
-       WL_RATE_2X2_VHT0SS2        = 54,
-       WL_RATE_2X2_VHT1SS2        = 55,
-       WL_RATE_2X2_VHT2SS2        = 56,
-       WL_RATE_2X2_VHT3SS2        = 57,
-       WL_RATE_2X2_VHT4SS2        = 58,
-       WL_RATE_2X2_VHT5SS2        = 59,
-       WL_RATE_2X2_VHT6SS2        = 60,
-       WL_RATE_2X2_VHT7SS2        = 61,
-       WL_RATE_2X2_VHT8SS2        = 62,
-       WL_RATE_2X2_VHT9SS2        = 63,
-
-       /************
-       * 3 chains *
-       ************
-       */
-
-       /* 1 Stream expanded + 2 */
-       WL_RATE_1X3_DSSS_1         = 64,
-       WL_RATE_1X3_DSSS_2         = 65,
-       WL_RATE_1X3_DSSS_5_5       = 66,
-       WL_RATE_1X3_DSSS_11        = 67,
-
-       WL_RATE_1X3_CDD_OFDM_6     = 68,
-       WL_RATE_1X3_CDD_OFDM_9     = 69,
-       WL_RATE_1X3_CDD_OFDM_12    = 70,
-       WL_RATE_1X3_CDD_OFDM_18    = 71,
-       WL_RATE_1X3_CDD_OFDM_24    = 72,
-       WL_RATE_1X3_CDD_OFDM_36    = 73,
-       WL_RATE_1X3_CDD_OFDM_48    = 74,
-       WL_RATE_1X3_CDD_OFDM_54    = 75,
-
-       WL_RATE_1X3_CDD_MCS0       = 76,
-       WL_RATE_1X3_CDD_MCS1       = 77,
-       WL_RATE_1X3_CDD_MCS2       = 78,
-       WL_RATE_1X3_CDD_MCS3       = 79,
-       WL_RATE_1X3_CDD_MCS4       = 80,
-       WL_RATE_1X3_CDD_MCS5       = 81,
-       WL_RATE_1X3_CDD_MCS6       = 82,
-       WL_RATE_1X3_CDD_MCS7       = 83,
-
-       WL_RATE_1X3_VHT0SS1        = 76,
-       WL_RATE_1X3_VHT1SS1        = 77,
-       WL_RATE_1X3_VHT2SS1        = 78,
-       WL_RATE_1X3_VHT3SS1        = 79,
-       WL_RATE_1X3_VHT4SS1        = 80,
-       WL_RATE_1X3_VHT5SS1        = 81,
-       WL_RATE_1X3_VHT6SS1        = 82,
-       WL_RATE_1X3_VHT7SS1        = 83,
-       WL_RATE_1X3_VHT8SS1        = 84,
-       WL_RATE_1X3_VHT9SS1        = 85,
-
-       /* 2 Streams expanded + 1 */
-       WL_RATE_2X3_STBC_MCS0      = 86,
-       WL_RATE_2X3_STBC_MCS1      = 87,
-       WL_RATE_2X3_STBC_MCS2      = 88,
-       WL_RATE_2X3_STBC_MCS3      = 89,
-       WL_RATE_2X3_STBC_MCS4      = 90,
-       WL_RATE_2X3_STBC_MCS5      = 91,
-       WL_RATE_2X3_STBC_MCS6      = 92,
-       WL_RATE_2X3_STBC_MCS7      = 93,
-
-       WL_RATE_2X3_STBC_VHT0SS1   = 86,
-       WL_RATE_2X3_STBC_VHT1SS1   = 87,
-       WL_RATE_2X3_STBC_VHT2SS1   = 88,
-       WL_RATE_2X3_STBC_VHT3SS1   = 89,
-       WL_RATE_2X3_STBC_VHT4SS1   = 90,
-       WL_RATE_2X3_STBC_VHT5SS1   = 91,
-       WL_RATE_2X3_STBC_VHT6SS1   = 92,
-       WL_RATE_2X3_STBC_VHT7SS1   = 93,
-       WL_RATE_2X3_STBC_VHT8SS1   = 94,
-       WL_RATE_2X3_STBC_VHT9SS1   = 95,
-
-       WL_RATE_2X3_SDM_MCS8       = 96,
-       WL_RATE_2X3_SDM_MCS9       = 97,
-       WL_RATE_2X3_SDM_MCS10      = 98,
-       WL_RATE_2X3_SDM_MCS11      = 99,
-       WL_RATE_2X3_SDM_MCS12      = 100,
-       WL_RATE_2X3_SDM_MCS13      = 101,
-       WL_RATE_2X3_SDM_MCS14      = 102,
-       WL_RATE_2X3_SDM_MCS15      = 103,
-
-       WL_RATE_2X3_VHT0SS2        = 96,
-       WL_RATE_2X3_VHT1SS2        = 97,
-       WL_RATE_2X3_VHT2SS2        = 98,
-       WL_RATE_2X3_VHT3SS2        = 99,
-       WL_RATE_2X3_VHT4SS2        = 100,
-       WL_RATE_2X3_VHT5SS2        = 101,
-       WL_RATE_2X3_VHT6SS2        = 102,
-       WL_RATE_2X3_VHT7SS2        = 103,
-       WL_RATE_2X3_VHT8SS2        = 104,
-       WL_RATE_2X3_VHT9SS2        = 105,
-
-       /* 3 Streams */
-       WL_RATE_3X3_SDM_MCS16      = 106,
-       WL_RATE_3X3_SDM_MCS17      = 107,
-       WL_RATE_3X3_SDM_MCS18      = 108,
-       WL_RATE_3X3_SDM_MCS19      = 109,
-       WL_RATE_3X3_SDM_MCS20      = 110,
-       WL_RATE_3X3_SDM_MCS21      = 111,
-       WL_RATE_3X3_SDM_MCS22      = 112,
-       WL_RATE_3X3_SDM_MCS23      = 113,
-
-       WL_RATE_3X3_VHT0SS3        = 106,
-       WL_RATE_3X3_VHT1SS3        = 107,
-       WL_RATE_3X3_VHT2SS3        = 108,
-       WL_RATE_3X3_VHT3SS3        = 109,
-       WL_RATE_3X3_VHT4SS3        = 110,
-       WL_RATE_3X3_VHT5SS3        = 111,
-       WL_RATE_3X3_VHT6SS3        = 112,
-       WL_RATE_3X3_VHT7SS3        = 113,
-       WL_RATE_3X3_VHT8SS3        = 114,
-       WL_RATE_3X3_VHT9SS3        = 115,
-
-
-       /****************************
-        * TX Beamforming, 2 chains *
-        ****************************
-        */
-
-       /* 1 Stream expanded + 1 */
-
-       WL_RATE_1X2_TXBF_OFDM_6    = 116,
-       WL_RATE_1X2_TXBF_OFDM_9    = 117,
-       WL_RATE_1X2_TXBF_OFDM_12   = 118,
-       WL_RATE_1X2_TXBF_OFDM_18   = 119,
-       WL_RATE_1X2_TXBF_OFDM_24   = 120,
-       WL_RATE_1X2_TXBF_OFDM_36   = 121,
-       WL_RATE_1X2_TXBF_OFDM_48   = 122,
-       WL_RATE_1X2_TXBF_OFDM_54   = 123,
-
-       WL_RATE_1X2_TXBF_MCS0      = 124,
-       WL_RATE_1X2_TXBF_MCS1      = 125,
-       WL_RATE_1X2_TXBF_MCS2      = 126,
-       WL_RATE_1X2_TXBF_MCS3      = 127,
-       WL_RATE_1X2_TXBF_MCS4      = 128,
-       WL_RATE_1X2_TXBF_MCS5      = 129,
-       WL_RATE_1X2_TXBF_MCS6      = 130,
-       WL_RATE_1X2_TXBF_MCS7      = 131,
-
-       WL_RATE_1X2_TXBF_VHT0SS1   = 124,
-       WL_RATE_1X2_TXBF_VHT1SS1   = 125,
-       WL_RATE_1X2_TXBF_VHT2SS1   = 126,
-       WL_RATE_1X2_TXBF_VHT3SS1   = 127,
-       WL_RATE_1X2_TXBF_VHT4SS1   = 128,
-       WL_RATE_1X2_TXBF_VHT5SS1   = 129,
-       WL_RATE_1X2_TXBF_VHT6SS1   = 130,
-       WL_RATE_1X2_TXBF_VHT7SS1   = 131,
-       WL_RATE_1X2_TXBF_VHT8SS1   = 132,
-       WL_RATE_1X2_TXBF_VHT9SS1   = 133,
-
-       /* 2 Streams */
-
-       WL_RATE_2X2_TXBF_SDM_MCS8  = 134,
-       WL_RATE_2X2_TXBF_SDM_MCS9  = 135,
-       WL_RATE_2X2_TXBF_SDM_MCS10 = 136,
-       WL_RATE_2X2_TXBF_SDM_MCS11 = 137,
-       WL_RATE_2X2_TXBF_SDM_MCS12 = 138,
-       WL_RATE_2X2_TXBF_SDM_MCS13 = 139,
-       WL_RATE_2X2_TXBF_SDM_MCS14 = 140,
-       WL_RATE_2X2_TXBF_SDM_MCS15 = 141,
-
-       WL_RATE_2X2_TXBF_VHT0SS2   = 134,
-       WL_RATE_2X2_TXBF_VHT1SS2   = 135,
-       WL_RATE_2X2_TXBF_VHT2SS2   = 136,
-       WL_RATE_2X2_TXBF_VHT3SS2   = 137,
-       WL_RATE_2X2_TXBF_VHT4SS2   = 138,
-       WL_RATE_2X2_TXBF_VHT5SS2   = 139,
-       WL_RATE_2X2_TXBF_VHT6SS2   = 140,
-       WL_RATE_2X2_TXBF_VHT7SS2   = 141,
-
-
-       /****************************
-        * TX Beamforming, 3 chains *
-        ****************************
-        */
-
-       /* 1 Stream expanded + 2 */
-
-       WL_RATE_1X3_TXBF_OFDM_6    = 142,
-       WL_RATE_1X3_TXBF_OFDM_9    = 143,
-       WL_RATE_1X3_TXBF_OFDM_12   = 144,
-       WL_RATE_1X3_TXBF_OFDM_18   = 145,
-       WL_RATE_1X3_TXBF_OFDM_24   = 146,
-       WL_RATE_1X3_TXBF_OFDM_36   = 147,
-       WL_RATE_1X3_TXBF_OFDM_48   = 148,
-       WL_RATE_1X3_TXBF_OFDM_54   = 149,
-
-       WL_RATE_1X3_TXBF_MCS0      = 150,
-       WL_RATE_1X3_TXBF_MCS1      = 151,
-       WL_RATE_1X3_TXBF_MCS2      = 152,
-       WL_RATE_1X3_TXBF_MCS3      = 153,
-       WL_RATE_1X3_TXBF_MCS4      = 154,
-       WL_RATE_1X3_TXBF_MCS5      = 155,
-       WL_RATE_1X3_TXBF_MCS6      = 156,
-       WL_RATE_1X3_TXBF_MCS7      = 157,
-
-       WL_RATE_1X3_TXBF_VHT0SS1   = 150,
-       WL_RATE_1X3_TXBF_VHT1SS1   = 151,
-       WL_RATE_1X3_TXBF_VHT2SS1   = 152,
-       WL_RATE_1X3_TXBF_VHT3SS1   = 153,
-       WL_RATE_1X3_TXBF_VHT4SS1   = 154,
-       WL_RATE_1X3_TXBF_VHT5SS1   = 155,
-       WL_RATE_1X3_TXBF_VHT6SS1   = 156,
-       WL_RATE_1X3_TXBF_VHT7SS1   = 157,
-       WL_RATE_1X3_TXBF_VHT8SS1   = 158,
-       WL_RATE_1X3_TXBF_VHT9SS1   = 159,
-
-       /* 2 Streams expanded + 1 */
-
-       WL_RATE_2X3_TXBF_SDM_MCS8  = 160,
-       WL_RATE_2X3_TXBF_SDM_MCS9  = 161,
-       WL_RATE_2X3_TXBF_SDM_MCS10 = 162,
-       WL_RATE_2X3_TXBF_SDM_MCS11 = 163,
-       WL_RATE_2X3_TXBF_SDM_MCS12 = 164,
-       WL_RATE_2X3_TXBF_SDM_MCS13 = 165,
-       WL_RATE_2X3_TXBF_SDM_MCS14 = 166,
-       WL_RATE_2X3_TXBF_SDM_MCS15 = 167,
-
-       WL_RATE_2X3_TXBF_VHT0SS2   = 160,
-       WL_RATE_2X3_TXBF_VHT1SS2   = 161,
-       WL_RATE_2X3_TXBF_VHT2SS2   = 162,
-       WL_RATE_2X3_TXBF_VHT3SS2   = 163,
-       WL_RATE_2X3_TXBF_VHT4SS2   = 164,
-       WL_RATE_2X3_TXBF_VHT5SS2   = 165,
-       WL_RATE_2X3_TXBF_VHT6SS2   = 166,
-       WL_RATE_2X3_TXBF_VHT7SS2   = 167,
-       WL_RATE_2X3_TXBF_VHT8SS2   = 168,
-       WL_RATE_2X3_TXBF_VHT9SS2   = 169,
-
-       /* 3 Streams */
-
-       WL_RATE_3X3_TXBF_SDM_MCS16 = 170,
-       WL_RATE_3X3_TXBF_SDM_MCS17 = 171,
-       WL_RATE_3X3_TXBF_SDM_MCS18 = 172,
-       WL_RATE_3X3_TXBF_SDM_MCS19 = 173,
-       WL_RATE_3X3_TXBF_SDM_MCS20 = 174,
-       WL_RATE_3X3_TXBF_SDM_MCS21 = 175,
-       WL_RATE_3X3_TXBF_SDM_MCS22 = 176,
-       WL_RATE_3X3_TXBF_SDM_MCS23 = 177,
-
-       WL_RATE_3X3_TXBF_VHT0SS3   = 170,
-       WL_RATE_3X3_TXBF_VHT1SS3   = 171,
-       WL_RATE_3X3_TXBF_VHT2SS3   = 172,
-       WL_RATE_3X3_TXBF_VHT3SS3   = 173,
-       WL_RATE_3X3_TXBF_VHT4SS3   = 174,
-       WL_RATE_3X3_TXBF_VHT5SS3   = 175,
-       WL_RATE_3X3_TXBF_VHT6SS3   = 176,
-       WL_RATE_3X3_TXBF_VHT7SS3   = 177
-} clm_rates_t;
-
-/* Number of rate codes */
-#define WL_NUMRATES 178
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _bcmwifi_rates_h_ */
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/circularbuf.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/circularbuf.h
deleted file mode 100755 (executable)
index fa939ca..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Initialization and support routines for self-booting compressed image.
- *
- * $Copyright Open Broadcom Corporation$
- *
- * $Id: circularbuf.h 452258 2014-01-29 19:17:57Z $
- */
-
-#ifndef __CIRCULARBUF_H_INCLUDED__
-#define __CIRCULARBUF_H_INCLUDED__
-
-#include <osl.h>
-#include <typedefs.h>
-#include <bcmendian.h>
-
-/* Enumerations of return values provided by MsgBuf implementation */
-typedef enum {
-       CIRCULARBUF_FAILURE = -1,
-       CIRCULARBUF_SUCCESS
-} circularbuf_ret_t;
-
-/* Core circularbuf circular buffer structure */
-typedef struct circularbuf_s
-{
-       uint16 depth;   /* Depth of circular buffer */
-       uint16 r_ptr;   /* Read Ptr */
-       uint16 w_ptr;   /* Write Ptr */
-       uint16 e_ptr;   /* End Ptr */
-       uint16 wp_ptr;  /* wp_ptr/pending - scheduled for DMA. But, not yet complete. */
-       uint16 rp_ptr;  /* rp_ptr/pending - scheduled for DMA. But, not yet complete. */
-
-       uint8  *buf_addr;
-       void  *mb_ctx;
-       void  (*mb_ring_bell)(void *ctx);
-} circularbuf_t;
-
-#define CBUF_ERROR_VAL   0x00000001      /* Error level tracing */
-#define CBUF_TRACE_VAL   0x00000002      /* Function level tracing */
-#define CBUF_INFORM_VAL  0x00000004      /* debug level tracing */
-
-extern int cbuf_msg_level;
-
-#define CBUF_ERROR(args)         do {if (cbuf_msg_level & CBUF_ERROR_VAL) printf args;} while (0)
-#define CBUF_TRACE(args)         do {if (cbuf_msg_level & CBUF_TRACE_VAL) printf args;} while (0)
-#define CBUF_INFO(args)          do {if (cbuf_msg_level & CBUF_INFORM_VAL) printf args;} while (0)
-
-#define     CIRCULARBUF_START(x)     ((x)->buf_addr)
-#define     CIRCULARBUF_WRITE_PTR(x) ((x)->w_ptr)
-#define     CIRCULARBUF_READ_PTR(x)  ((x)->r_ptr)
-#define     CIRCULARBUF_END_PTR(x)   ((x)->e_ptr)
-
-#define circularbuf_debug_print(handle)                                 \
-                       CBUF_INFO(("%s:%d:\t%p  rp=%4d  r=%4d  wp=%4d  w=%4d  e=%4d\n", \
-                                       __FUNCTION__, __LINE__,                             \
-                                       (void *) CIRCULARBUF_START(handle),                 \
-                                       (int) (handle)->rp_ptr, (int) (handle)->r_ptr,          \
-                                       (int) (handle)->wp_ptr, (int) (handle)->w_ptr,          \
-                                       (int) (handle)->e_ptr));
-
-
-/* Callback registered by application/mail-box with the circularbuf implementation.
- * This will be invoked by the circularbuf implementation when write is complete and
- * ready for informing the peer
- */
-typedef void (*mb_ring_t)(void *ctx);
-
-
-/* Public Functions exposed by circularbuf */
-void
-circularbuf_init(circularbuf_t *handle, void *buf_base_addr, uint16 total_buf_len);
-void
-circularbuf_register_cb(circularbuf_t *handle, mb_ring_t mb_ring_func, void *ctx);
-
-/* Write Functions */
-void *
-circularbuf_reserve_for_write(circularbuf_t *handle, uint16 size);
-void
-circularbuf_write_complete(circularbuf_t *handle, uint16 bytes_written);
-
-/* Read Functions */
-void *
-circularbuf_get_read_ptr(circularbuf_t *handle, uint16 *avail_len);
-circularbuf_ret_t
-circularbuf_read_complete(circularbuf_t *handle, uint16 bytes_read);
-
-/*
- * circularbuf_get_read_ptr() updates rp_ptr by the amount that the consumer
- * is supposed to read. The consumer may not read the entire amount.
- * In such a case, circularbuf_revert_rp_ptr() call follows a corresponding
- * circularbuf_get_read_ptr() call to revert the rp_ptr back to
- * the point till which data has actually been processed.
- * It is not valid if it is preceded by multiple get_read_ptr() calls
- */
-circularbuf_ret_t
-circularbuf_revert_rp_ptr(circularbuf_t *handle, uint16 bytes);
-
-#endif /* __CIRCULARBUF_H_INCLUDED__ */
index 85427b5ccc82f01df4ebf3ff33427ae453166207..16cedc48a7e126ed1547cf24d248e1a9a1bd5df3 100755 (executable)
@@ -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.1 (r)"
+#define        EPI_VERSION_STR         "1.363.59.144.7 (r)"
 
 #endif /* _epivers_h_ */
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h.in b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h.in
deleted file mode 100755 (executable)
index 9897e98..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * $Copyright Open Broadcom Corporation$
- *
- * $Id: epivers.h.in,v 13.33 2010-09-08 22:08:53 $
- *
-*/
-
-#ifndef _epivers_h_
-#define _epivers_h_
-
-#define        EPI_MAJOR_VERSION       @EPI_MAJOR_VERSION@
-
-#define        EPI_MINOR_VERSION       @EPI_MINOR_VERSION@
-
-#define        EPI_RC_NUMBER           @EPI_RC_NUMBER@
-
-#define        EPI_INCREMENTAL_NUMBER  @EPI_INCREMENTAL_NUMBER@
-
-#define        EPI_BUILD_NUMBER        @EPI_BUILD_NUMBER@
-
-#define        EPI_VERSION             @EPI_VERSION@
-
-#define        EPI_VERSION_NUM         @EPI_VERSION_NUM@
-
-#define EPI_VERSION_DEV                @EPI_VERSION_DEV@
-
-/* Driver Version String, ASCII, 32 chars max */
-#define        EPI_VERSION_STR         "@EPI_VERSION_STR@@EPI_VERSION_TYPE@ (@VC_VERSION_NUM@)"
-
-#endif /* _epivers_h_ */
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.sh b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.sh
deleted file mode 100755 (executable)
index 25ff49b..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-#! /bin/bash
-#
-# Create the epivers.h file from epivers.h.in
-#
-# Epivers.h version support svn/sparse/gclient workspaces
-#
-# $Id: epivers.sh 389103 2013-03-05 17:24:49Z $
-#
-# Version generation works off of svn property HeadURL, if
-# not set it keys its versions from current svn workspace or
-# via .gclient_info deps contents
-#
-# GetCompVer.py return value and action needed
-#    i. trunk => use current date as version string
-#   ii. local => use SVNURL expanded by HeadURL keyword
-#  iii. <tag> => use it as as is
-#                (some components can override and say give me native ver)
-#   iv. empty =>
-#             a) If TAG is specified use it
-#             a) If no TAG is specified use date
-#
-# Contact: Prakash Dhavali
-# Contact: hnd-software-scm-list
-#
-
-# If the version header file already exists, increment its build number.
-# Otherwise, create a new file.
-if [ -f epivers.h ]; then
-
-       # If REUSE_VERSION is set, epivers iteration is not incremented
-       # This can be used precommit and continuous integration projects
-       if [ -n "$REUSE_VERSION" ]; then
-               echo "Previous epivers.h exists. Skipping version increment"
-               exit 0
-       fi
-
-       build=$(grep EPI_BUILD_NUMBER epivers.h | sed -e "s,.*BUILD_NUMBER[     ]*,,")
-       build=$(expr ${build} + 1)
-       echo build=${build}
-       sed -e "s,.*_BUILD_NUMBER.*,#define EPI_BUILD_NUMBER    ${build}," \
-               < epivers.h > epivers.h.new
-       cp -p epivers.h epivers.h.prev
-       mv epivers.h.new epivers.h
-       exit 0
-
-else # epivers.h doesn't exist
-
-       SVNCMD=${SVNCMD:-"svn --non-interactive"}
-       SRCBASE=${SRCBASE:-..}
-       NULL=/dev/null
-       [ -z "$VERBOSE" ] || NULL=/dev/stderr
-
-       # Check for the in file, if not there we're in the wrong directory
-       if [ ! -f epivers.h.in ]; then
-               echo "ERROR: No epivers.h.in found"
-               exit 1
-       fi
-
-       # Following SVNURL should be expanded on checkout
-       SVNURL='$HeadURL: http://svn.sj.broadcom.com/svn/wlansvn/proj/tags/DHD/DHD_REL_1_201_59/src/include/epivers.sh $'
-
-       # .gclient_info is created by gclient checkout/sync steps
-       # and contains "DEPS='<deps-url1> <deps-url2> ..." entry
-       GCLIENT_INFO=${GCLIENT_INFO:-${SRCBASE}/../.gclient_info}
-
-       # In gclient, derive SVNURL from gclient_info file
-       if [ -s "${GCLIENT_INFO}" ]; then
-               source ${GCLIENT_INFO}
-               if [ -z "$DEPS" ]; then
-                       echo "ERROR: DEPS entry missing in $GCLIENT_INFO"
-                       exit 1
-               else
-                       for dep in $DEPS; do
-                               SVNURL=${SVNURL:-$dep}
-                               # Set SVNURL to first DEPS with /tags/ (if any)
-                               if [[ $dep == */tags/* ]]; then
-                                       SVNURL=$dep
-                                       echo "INFO: Found gclient DEPS: $SVNURL"
-                                       break
-                               fi
-                       done
-               fi
-       elif [ -f "${GCLIENT_INFO}" ]; then
-               echo "ERROR: $GCLIENT_INFO exists, but it is empty"
-               exit 1
-       fi
-
-       # If SVNURL isn't expanded, extract it from svn info
-       if echo "$SVNURL" | egrep -vq 'HeadURL.*epivers.sh.*|http://.*/DEPS'; then
-               [ -n "$VERBOSE" ] && \
-                       echo "DBG: SVN URL ($SVNURL) wasn't expanded. Getting it from svn info"
-               SVNURL=$($SVNCMD info epivers.sh 2> $NULL | egrep "^URL:")
-       fi
-
-       if echo "${TAG}" | grep -q "_BRANCH_\|_TWIG_"; then
-               branchtag=$TAG
-       else
-               branchtag=""
-       fi
-
-       # If this is a tagged build, use the tag to supply the numbers
-       # Tag should be in the form
-       #    <NAME>_REL_<MAJ>_<MINOR>
-       # or
-       #    <NAME>_REL_<MAJ>_<MINOR>_RC<RCNUM>
-       # or
-       #    <NAME>_REL_<MAJ>_<MINOR>_RC<RCNUM>_<INCREMENTAL>
-
-       MERGERLOG=${SRCBASE}/../merger_sources.log
-       GETCOMPVER=getcompver.py
-       GETCOMPVER_NET=/projects/hnd_software/gallery/src/tools/build/$GETCOMPVER
-       GETCOMPVER_NET_WIN=Z:${GETCOMPVER_NET}
-
-       #
-       # If there is a local copy GETCOMPVER use it ahead of network copy
-       #
-       if [ -s "$GETCOMPVER" ]; then
-               GETCOMPVER_PATH="$GETCOMPVER"
-       elif [ -s "${SRCBASE}/../src/tools/build/$GETCOMPVER" ]; then
-               GETCOMPVER_PATH="${SRCBASE}/../src/tools/build/$GETCOMPVER"
-       elif [ -s "$GETCOMPVER_NET" ]; then
-               GETCOMPVER_PATH="$GETCOMPVER_NET"
-       elif [ -s "$GETCOMPVER_NET_WIN" ]; then
-               GETCOMPVER_PATH="$GETCOMPVER_NET_WIN"
-       fi
-
-       #
-       # If $GETCOMPVER isn't found, fetch it from SVN
-       # (this should be very rare)
-       #
-       if [ ! -s "$GETCOMPVER_PATH" ]; then
-               [ -n "$VERBOSE" ] && \
-                       echo "DBG: Fetching $GETCOMPVER from trunk"
-
-               $SVNCMD export -q \
-                       ^/proj/trunk/src/tools/build/${GETCOMPVER} \
-                       ${GETCOMPVER} 2> $NULL
-
-               GETCOMPVER_PATH=$GETCOMPVER
-       fi
-
-       # Now get tag for src/include from automerger log
-       [ -n "$VERBOSE" ] && \
-               echo "DBG: python $GETCOMPVER_PATH $MERGERLOG src/include"
-
-       COMPTAG=$(python $GETCOMPVER_PATH $MERGERLOG src/include 2> $NULL | sed -e 's/[[:space:]]*//g')
-
-       echo "DBG: Component Tag String Derived = $COMPTAG"
-
-       # Process COMPTAG values
-       # Rule:
-       # If trunk is returned, use date as component tag
-       # If LOCAL_COMPONENT is returned, use SVN URL to get native tag
-       # If component is returned or empty, assign it to SVNTAG
-       # GetCompVer.py return value and action needed
-       #    i. trunk => use current date as version string
-       #   ii. local => use SVNURL expanded by HeadURL keyword
-       #  iii. <tag> => use it as as is
-       #   iv. empty =>
-       #             a) If TAG is specified use it
-       #             a) If no TAG is specified use SVNURL from HeadURL
-
-       SVNURL_VER=false
-
-       if [ "$COMPTAG" == "" ]; then
-               SVNURL_VER=true
-       elif [ "$COMPTAG" == "LOCAL_COMPONENT" ]; then
-               SVNURL_VER=true
-       elif [ "$COMPTAG" == "trunk" ]; then
-               SVNTAG=$(date '+TRUNKCOMP_REL_%Y_%m_%d')
-       else
-               SVNTAG=$COMPTAG
-       fi
-
-       # Given SVNURL path conventions or naming conventions, derive SVNTAG
-       # TO-DO: SVNTAG derivation logic can move to a central common API
-       # TO-DO: ${SRCBASE}/tools/build/svnurl2tag.sh
-       if [ "$SVNURL_VER" == "true" ]; then
-               case "${SVNURL}" in
-                       *_BRANCH_*)
-                               SVNTAG=$(echo $SVNURL | tr '/' '\n' | awk '/_BRANCH_/{printf "%s",$1}')
-                               ;;
-                       *_TWIG_*)
-                               SVNTAG=$(echo $SVNURL | tr '/' '\n' | awk '/_TWIG_/{printf "%s",$1}')
-                               ;;
-                       *_REL_*)
-                               SVNTAG=$(echo $SVNURL | tr '/' '\n' | awk '/_REL_/{printf "%s",$1}')
-                               ;;
-                       */branches/*)
-                               SVNTAG=${SVNURL#*/branches/}
-                               SVNTAG=${SVNTAG%%/*}
-                               ;;
-                       */proj/tags/*|*/deps/tags/*)
-                               SVNTAG=${SVNURL#*/tags/*/}
-                               SVNTAG=${SVNTAG%%/*}
-                               ;;
-                       */trunk/*)
-                               SVNTAG=$(date '+TRUNKURL_REL_%Y_%m_%d')
-                               ;;
-                       *)
-                               SVNTAG=$(date '+OTHER_REL_%Y_%m_%d')
-                               ;;
-               esac
-               echo "DBG: Native Tag String Derived from URL: $SVNTAG"
-       else
-               echo "DBG: Native Tag String Derived: $SVNTAG"
-       fi
-
-       TAG=${SVNTAG}
-
-       # Normalize the branch name portion to "D11" in case it has underscores in it
-       branch_name=$(expr match "$TAG" '\(.*\)_\(BRANCH\|TWIG\|REL\)_.*')
-               TAG=$(echo $TAG | sed -e "s%^$branch_name%D11%")
-
-       # Split the tag into an array on underbar or whitespace boundaries.
-       IFS="_       " tag=(${TAG})
-       unset IFS
-
-       tagged=1
-       if [ ${#tag[*]} -eq 0 ]; then
-          tag=($(date '+TOT REL %Y %m %d 0 %y'));
-          # reconstruct a TAG from the date
-          TAG=${tag[0]}_${tag[1]}_${tag[2]}_${tag[3]}_${tag[4]}_${tag[5]}
-          tagged=0
-       fi
-
-       # Allow environment variable to override values.
-       # Missing values default to 0
-       #
-       maj=${EPI_MAJOR_VERSION:-${tag[2]:-0}}
-       min=${EPI_MINOR_VERSION:-${tag[3]:-0}}
-       rcnum=${EPI_RC_NUMBER:-${tag[4]:-0}}
-
-       # If increment field is 0, set it to date suffix if on TOB
-       if [ -n "$branchtag" ]; then
-               [ "${tag[5]:-0}" -eq 0 ] && echo "Using date suffix for incr"
-               today=${EPI_DATE_STR:-$(date '+%Y%m%d')}
-               incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-${today:-0}}}
-       else
-               incremental=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}}
-       fi
-       origincr=${EPI_INCREMENTAL_NUMBER:-${tag[5]:-0}}
-       build=${EPI_BUILD_NUMBER:-0}
-
-       # Strip 'RC' from front of rcnum if present
-       rcnum=${rcnum/#RC/}
-
-       # strip leading zero off the number (otherwise they look like octal)
-       maj=${maj/#0/}
-       min=${min/#0/}
-       rcnum=${rcnum/#0/}
-       incremental=${incremental/#0/}
-       origincr=${origincr/#0/}
-       build=${build/#0/}
-
-       # some numbers may now be null.  replace with with zero.
-       maj=${maj:-0}
-       min=${min:-0}
-
-       rcnum=${rcnum:-0}
-       incremental=${incremental:-0}
-       origincr=${origincr:-0}
-       build=${build:-0}
-
-       if [ -n "$EPI_VERSION_NUM" ]; then
-           vernum=$EPI_VERSION_NUM
-       elif [ ${tagged} -eq 1 ]; then
-           # vernum is 32chars max
-           vernum=$(printf "0x%02x%02x%02x%02x" ${maj} ${min} ${rcnum} ${origincr})
-       else
-           vernum=$(printf "0x00%02x%02x%02x" ${tag[7]} ${min} ${rcnum})
-       fi
-
-       # make sure the size of vernum is under 32 bits.
-       # Otherwise, truncate. The string will keep full information.
-       vernum=${vernum:0:10}
-
-       # build the string directly from the tag, irrespective of its length
-       # remove the name , the tag type, then replace all _ by .
-       tag_ver_str=${TAG/${tag[0]}_}
-       tag_ver_str=${tag_ver_str/${tag[1]}_}
-       tag_ver_str=${tag_ver_str//_/.}
-
-       # record tag type
-       tagtype=
-
-       if [ "${tag[1]}" = "BRANCH" -o "${tag[1]}" = "TWIG" ]; then
-          tagtype=" (TOB)"
-          echo "tag type: $tagtype"
-       fi
-
-       echo "Effective version string: $tag_ver_str"
-
-       if [ "$(uname -s)" == "Darwin" ]; then
-          # Mac does not like 2-digit numbers so convert the number to single
-          # digit. 5.100 becomes 5.1
-          if [ $min -gt 99 ]; then
-              minmac=$(expr $min / 100)
-          else
-              minmac=$min
-          fi
-          epi_ver_dev="${maj}.${minmac}.0"
-       else
-          epi_ver_dev="${maj}.${min}.${rcnum}"
-       fi
-
-       # Finally get version control revision number of <SRCBASE> (if any)
-       vc_version_num=$($SVNCMD info ${SRCBASE} 2> $NULL | awk -F': ' '/^Last Changed Rev: /{printf "%s", $2}')
-
-       # OK, go do it
-       echo "maj=${maj}, min=${min}, rc=${rcnum}, inc=${incremental}, build=${build}"
-
-       sed \
-               -e "s;@EPI_MAJOR_VERSION@;${maj};" \
-               -e "s;@EPI_MINOR_VERSION@;${min};" \
-               -e "s;@EPI_RC_NUMBER@;${rcnum};" \
-               -e "s;@EPI_INCREMENTAL_NUMBER@;${incremental};" \
-               -e "s;@EPI_BUILD_NUMBER@;${build};" \
-               -e "s;@EPI_VERSION@;${maj}, ${min}, ${rcnum}, ${incremental};" \
-               -e "s;@EPI_VERSION_STR@;${tag_ver_str};" \
-               -e "s;@EPI_VERSION_TYPE@;${tagtype};" \
-               -e "s;@VERSION_TYPE@;${tagtype};" \
-               -e "s;@EPI_VERSION_NUM@;${vernum};" \
-               -e "s;@EPI_VERSION_DEV@;${epi_ver_dev};" \
-               -e "s;@VC_VERSION_NUM@;r${vc_version_num};" \
-               < epivers.h.in > epivers.h
-
-       # In shared workspaces across different platforms, ensure that
-       # windows generated file is made platform neutral without CRLF
-       if uname -s | egrep -i -q "cygwin"; then
-          dos2unix epivers.h > $NULL 2>&1
-       fi
-fi # epivers.h
index 539a2fa771d78775891e3058eec0164293744ea3..d560feca11e8094b00631490721cfa3ae231b769 100755 (executable)
@@ -446,10 +446,10 @@ extern int osl_error(int bcmerror);
 #define PKTSETID(skb, id)       ({BCM_REFERENCE(skb); BCM_REFERENCE(id);})
 #define PKTSHRINK(osh, m)              ({BCM_REFERENCE(osh); m;})
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) && defined(TSQ_MULTIPLIER)
-#define PKTORPHAN(skb)          osl_pkt_orphan_partial(skb)
-extern void osl_pkt_orphan_partial(struct sk_buff *skb);
+#define PKTORPHAN(skb, tsq)          osl_pkt_orphan_partial(skb, tsq)
+extern void osl_pkt_orphan_partial(struct sk_buff *skb, int tsq);
 #else
-#define PKTORPHAN(skb)          ({BCM_REFERENCE(skb); 0;})
+#define PKTORPHAN(skb, tsq)          ({BCM_REFERENCE(skb); 0;})
 #endif /* LINUX VERSION >= 3.6 */
 
 
index 15b74abec9ea29c02690c6b7705d4d6a16eda9d4..335e53a2f65bfc9b742c331fec318db9908b14c7 100755 (executable)
@@ -52,6 +52,7 @@ typedef struct sdreg {
 #define SDH_CTRL_VAL           0x0020  /* Control Regs */
 #define SDH_LOG_VAL            0x0040  /* Enable bcmlog */
 #define SDH_DMA_VAL            0x0080  /* DMA */
+#define SDH_COST_VAL           0x8000  /* Control Regs */
 
 #define NUM_PREV_TRANSACTIONS  16
 
index 4b7584c4119194c044f1e4e068f8a1b9455b83b5..16d873f81643a518037c913f6d32c14537f104fe 100755 (executable)
@@ -2615,11 +2615,14 @@ osl_sec_dma_free_consistent(osl_t *osh, void *va, uint size, dmaaddr_t pa)
 #include <linux/kallsyms.h>
 #include <net/sock.h>
 void
-osl_pkt_orphan_partial(struct sk_buff *skb)
+osl_pkt_orphan_partial(struct sk_buff *skb, int tsq)
 {
        uint32 fraction;
        static void *p_tcp_wfree = NULL;
 
+       if (tsq <= 0)
+               return;
+
        if (!skb->destructor || skb->destructor == sock_wfree)
                return;
 
@@ -2640,7 +2643,7 @@ osl_pkt_orphan_partial(struct sk_buff *skb)
         * sk_wmem_alloc to allow more skb can be allocated for this
         * socket for better cusion meeting WiFi device requirement
         */
-       fraction = skb->truesize * (TSQ_MULTIPLIER - 1) / TSQ_MULTIPLIER;
+       fraction = skb->truesize * (tsq - 1) / tsq;
        skb->truesize -= fraction;
        atomic_sub(fraction, &skb->sk->sk_wmem_alloc);
 }
index 1a54e5ff738d1cb3204f76fe7026eac392fa4ffb..1961e6a7795cfcc751c518879168de588c5738b0 100644 (file)
@@ -116,13 +116,6 @@ uint android_msg_level = ANDROID_ERROR_LEVEL;
 #define CMD_ULB_MODE "ULB_MODE"
 #define CMD_ULB_BW "ULB_BW"
 #endif /* WL11ULB */
-#define CMD_GET_CHANNEL                        "GET_CHANNEL"
-#define CMD_SET_ROAM                   "SET_ROAM_TRIGGER"
-#define CMD_GET_ROAM                   "GET_ROAM_TRIGGER"
-#define CMD_GET_KEEP_ALIVE             "GET_KEEP_ALIVE"
-#define CMD_GET_PM                             "GET_PM"
-#define CMD_SET_PM                             "SET_PM"
-#define CMD_MONITOR                    "MONITOR"
 
 #if defined(WL_SUPPORT_AUTO_CHANNEL)
 #define CMD_GET_BEST_CHANNELS  "GET_BEST_CHANNELS"
@@ -524,6 +517,7 @@ static int wl_android_set_suspendmode(struct net_device *dev, char *command, int
        return ret;
 }
 
+#ifdef WL_CFG80211
 int wl_android_get_80211_mode(struct net_device *dev, char *command, int total_len)
 {
        uint8 mode[4];
@@ -606,6 +600,7 @@ int wl_android_get_chanspec(struct net_device *dev, char *command, int total_len
        return bytes_written;
 
 }
+#endif
 
 /* returns current datarate datarate returned from firmware are in 500kbps */
 int wl_android_get_datarate(struct net_device *dev, char *command, int total_len)
@@ -651,6 +646,8 @@ int wl_android_get_assoclist(struct net_device *dev, char *command, int total_le
        return bytes_written;
 
 }
+
+#ifdef WL_CFG80211
 extern chanspec_t
 wl_chspec_host_to_driver(chanspec_t chanspec);
 static int wl_android_set_csa(struct net_device *dev, char *command, int total_len)
@@ -725,6 +722,8 @@ static int wl_android_set_csa(struct net_device *dev, char *command, int total_l
        }
        return 0;
 }
+#endif
+
 static int wl_android_get_band(struct net_device *dev, char *command, int total_len)
 {
        uint band;
@@ -1325,6 +1324,10 @@ int wl_android_wifi_on(struct net_device *dev)
 {
        int ret = 0;
        int retry = POWERUP_MAX_RETRY;
+#ifdef IAPSTA_PREINIT
+       int bytes_written = 0;
+       struct dhd_conf *conf;
+#endif
 
        if (!dev) {
                ANDROID_ERROR(("%s: dev is null\n", __FUNCTION__));
@@ -1372,6 +1375,15 @@ int wl_android_wifi_on(struct net_device *dev)
                        }
                }
 #endif /* !BCMPCIE */
+
+#ifdef IAPSTA_PREINIT
+               conf = dhd_get_conf(dev);
+               if (conf) {
+                       wl_android_ext_priv_cmd(dev, conf->iapsta_init, 0, &bytes_written);
+                       wl_android_ext_priv_cmd(dev, conf->iapsta_config, 0, &bytes_written);
+                       wl_android_ext_priv_cmd(dev, conf->iapsta_enable, 0, &bytes_written);
+               }
+#endif
                g_wifi_on = TRUE;
        }
 
@@ -2646,6 +2658,7 @@ int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len)
        return res;
 }
 
+#ifdef WL_CFG80211
 static const char *
 get_string_by_separator(char *result, int result_len, const char *src, char separator)
 {
@@ -2660,7 +2673,6 @@ get_string_by_separator(char *result, int result_len, const char *src, char sepa
        return src;
 }
 
-#ifdef WL_CFG80211
 int
 wl_android_set_roam_offload_bssid_list(struct net_device *dev, const char *cmd)
 {
@@ -2837,172 +2849,6 @@ wl_android_murx_bfe_cap(struct net_device *dev, int val)
 }
 #endif
 
-int
-wl_android_get_channel(
-struct net_device *dev, char* command, int total_len)
-{
-       int ret;
-       channel_info_t ci;
-       int bytes_written = 0;
-
-       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));
-       }
-
-       return bytes_written;
-}
-
-int
-wl_android_set_roam_trigger(
-struct net_device *dev, char* command, int total_len)
-{
-       int ret = 0;
-       int roam_trigger[2];
-
-       sscanf(command, "%*s %10d", &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));
-
-       return ret;
-}
-
-int
-wl_android_get_roam_trigger(
-struct net_device *dev, char *command, int total_len)
-{
-       int ret;
-       int bytes_written;
-       int roam_trigger[2] = {0, 0};
-       int trigger[2]= {0, 0};
-
-       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]);
-
-       return bytes_written;
-}
-
-s32
-wl_android_get_keep_alive(struct net_device *dev, char *command, int total_len) {
-
-       wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
-       int bytes_written = -1;
-       int res = -1, len, i = 0;
-       char* str = "mkeep_alive";
-
-       ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command));
-
-       len = WLC_IOCTL_MEDLEN;
-       mkeep_alive_pktp = kmalloc(len, GFP_KERNEL);
-       memset(mkeep_alive_pktp, 0, len);
-       strcpy((char*)mkeep_alive_pktp, str);
-
-       if ((res = wldev_ioctl(dev, WLC_GET_VAR, mkeep_alive_pktp, len, FALSE))<0) {
-               ANDROID_ERROR(("%s: GET mkeep_alive ERROR %d\n", __FUNCTION__, res));
-               goto exit;
-       } else {
-               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));
-
-exit:
-       kfree(mkeep_alive_pktp);
-       return bytes_written;
-}
-
-int
-wl_android_set_pm(struct net_device *dev,char *command, int total_len)
-{
-       int pm, ret = -1;
-
-       ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command));
-
-       sscanf(command, "%*s %d", &pm);
-
-       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));
-
-       return ret;
-}
-
-int
-wl_android_get_pm(struct net_device *dev,char *command, int total_len)
-{
-
-       int ret = 0;
-       int pm_local;
-       char *pm;
-       int bytes_written=-1;
-
-       ret = wldev_ioctl(dev, WLC_GET_PM, &pm_local, sizeof(pm_local),FALSE);
-       if (!ret) {
-               ANDROID_TRACE(("%s: PM = %d\n", __func__, pm_local));
-               if (pm_local == PM_OFF)
-                       pm = "PM_OFF";
-               else if(pm_local == PM_MAX)
-                       pm = "PM_MAX";
-               else if(pm_local == PM_FAST)
-                       pm = "PM_FAST";
-               else {
-                       pm_local = 0;
-                       pm = "Invalid";
-               }
-               bytes_written = snprintf(command, total_len, "PM %s", pm);
-               ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
-       }
-       return bytes_written;
-}
-
-static int
-wl_android_set_monitor(struct net_device *dev, char *command, int total_len)
-{
-       int val;
-       int ret = 0;
-       int bytes_written;
-
-       sscanf(command, "%*s %d", &val);
-       bytes_written = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1);
-       if (bytes_written)
-               ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret));
-       return bytes_written;
-}
-
 int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
 {
 #define PRIVATE_COMMAND_MAX_LEN        8192
@@ -3019,7 +2865,12 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
        }
 
 #ifdef CONFIG_COMPAT
-       if (is_compat_task()) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
+       if (in_compat_syscall())
+#else
+       if (is_compat_task())
+#endif
+       {
                compat_android_wifi_priv_cmd compat_priv_cmd;
                if (copy_from_user(&compat_priv_cmd, ifr->ifr_data,
                        sizeof(compat_android_wifi_priv_cmd))) {
@@ -3170,14 +3021,15 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
                }
 #endif /* FCC_PWR_LIMIT_2G */
        }
-#endif /* WL_CFG80211 */
        else if (strnicmp(command, CMD_SET_CSA, strlen(CMD_SET_CSA)) == 0) {
                bytes_written = wl_android_set_csa(net, command, priv_cmd.total_len);
        } else if (strnicmp(command, CMD_80211_MODE, strlen(CMD_80211_MODE)) == 0) {
                bytes_written = wl_android_get_80211_mode(net, command, priv_cmd.total_len);
        } else if (strnicmp(command, CMD_CHANSPEC, strlen(CMD_CHANSPEC)) == 0) {
                bytes_written = wl_android_get_chanspec(net, command, priv_cmd.total_len);
-       } else if (strnicmp(command, CMD_DATARATE, strlen(CMD_DATARATE)) == 0) {
+       }
+#endif /* WL_CFG80211 */
+       else if (strnicmp(command, CMD_DATARATE, strlen(CMD_DATARATE)) == 0) {
                bytes_written = wl_android_get_datarate(net, command, priv_cmd.total_len);
        } else if (strnicmp(command, CMD_ASSOC_CLIENTS, strlen(CMD_ASSOC_CLIENTS)) == 0) {
                bytes_written = wl_android_get_assoclist(net, command, priv_cmd.total_len);
@@ -3501,28 +3353,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
 #endif /* DHD_DEBUG && BCMPCIE && DHD_FW_COREDUMP */
        }
 #endif /* DHD_LOG_DUMP */
-       else if(strnicmp(command, CMD_GET_CHANNEL, strlen(CMD_GET_CHANNEL)) == 0) {
-               bytes_written = wl_android_get_channel(net, command, priv_cmd.total_len);
+       else if (wl_android_ext_priv_cmd(net, command, priv_cmd.total_len, &bytes_written) == 0) {
        }
-       else if (strnicmp(command, CMD_SET_ROAM, strlen(CMD_SET_ROAM)) == 0) {
-               bytes_written = wl_android_set_roam_trigger(net, command, priv_cmd.total_len);
-       }
-       else if (strnicmp(command, CMD_GET_ROAM, strlen(CMD_GET_ROAM)) == 0) {
-               bytes_written = wl_android_get_roam_trigger(net, command, priv_cmd.total_len);
-       }
-       else if (strnicmp(command, CMD_GET_KEEP_ALIVE, strlen(CMD_GET_KEEP_ALIVE)) == 0) {
-               int skip = strlen(CMD_GET_KEEP_ALIVE) + 1;
-               bytes_written = wl_android_get_keep_alive(net, command+skip, priv_cmd.total_len-skip);
-       }
-       else if (strnicmp(command, CMD_GET_PM, strlen(CMD_GET_PM)) == 0) {
-               bytes_written = wl_android_get_pm(net, command, priv_cmd.total_len);
-       }
-       else if (strnicmp(command, CMD_SET_PM, strlen(CMD_SET_PM)) == 0) {
-               bytes_written = wl_android_set_pm(net, command, priv_cmd.total_len);
-       }
-       else if (strnicmp(command, CMD_MONITOR, strlen(CMD_MONITOR)) == 0) {
-               bytes_written = wl_android_set_monitor(net, command, priv_cmd.total_len);
-       } else {
+       else {
                ANDROID_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
                snprintf(command, 3, "OK");
                bytes_written = strlen("OK");
@@ -3606,581 +3439,3 @@ void wl_android_post_init(void)
        if (!dhd_download_fw_on_driverload)
                g_wifi_on = FALSE;
 }
-
-#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;
-       scb_val_t scbval;
-       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(("%s: Could not get bssid (%d)\n", __FUNCTION__, error));
-       }
-       memset(&scbval, 0, sizeof(scb_val_t));
-       error = wldev_get_rssi(net, &scbval);
-       rssi = scbval.val;
-       if (error) {
-               ANDROID_ERROR(("%s: Could not get rssi (%d)\n", __FUNCTION__, 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 11252fd85ac86df7398d56d13c3298b4901b0c1d..4bfc6be08adbd63de6358ba16da983e1c1dcccfb 100644 (file)
@@ -86,6 +86,83 @@ void wl_android_post_init(void);
 int wl_android_wifi_on(struct net_device *dev);
 int wl_android_wifi_off(struct net_device *dev, bool on_failure);
 int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd);
+#ifdef WL_EXT_IAPSTA
+int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx);
+int wl_android_ext_dettach_netdev(void);
+void wl_android_ext_iapsta_disconnect_sta(u32 channel);
+#endif
+int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
+       int *bytes_written);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
+#define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len))
+#endif
+
+typedef enum ACTION {
+       ACTION_INIT = 1,
+       ACTION_DISABLE,
+       ACTION_ENABLE
+} action_t;
+
+typedef enum APSTAMODE {
+       ISTAONLY_MODE = 1,
+       IAPONLY_MODE,
+       IAPSTA_MODE,
+       IDUALAP_MODE
+} apstamode_t;
+
+typedef enum IFMODE {
+       ISTA_MODE = 1,
+       IAP_MODE
+} ifmode_t;
+
+typedef enum BGNMODE {
+       IEEE80211B = 1,
+       IEEE80211G,
+       IEEE80211BG,
+       IEEE80211BGN,
+       IEEE80211BGNAC
+} bgnmode_t;
+
+typedef enum AUTHMODE {
+       AUTH_OPEN,
+       AUTH_SHARED,
+       AUTH_WPAPSK,
+       AUTH_WPA2PSK,
+       AUTH_WPAWPA2PSK
+} authmode_t;
+
+typedef enum ENCMODE {
+       ENC_NONE,
+       ENC_WEP,
+       ENC_TKIP,
+       ENC_AES,
+       ENC_TKIPAES
+} encmode_t;
+
+/* i/f query */
+typedef struct wl_if_info {
+       struct net_device *dev;
+       ifmode_t ifmode;
+       uint bssidx;
+       char ifname[IFNAMSIZ+1];
+       char ssid[DOT11_MAX_SSID_LEN];
+       struct ether_addr bssid;
+       bgnmode_t bgnmode;
+       int hidden;
+       int maxassoc;
+       uint16 channel;
+       authmode_t amode;
+       encmode_t emode;
+       char key[100];
+} wl_apsta_if_t;
+
+typedef struct wl_apsta_params {
+       struct wl_if_info pif; // primary device
+       struct wl_if_info vif; // virtual device
+       int ioctl_ver;
+       action_t action;
+       apstamode_t apstamode;
+} wl_apsta_params_t;
 
 s32 wl_netlink_send_msg(int pid, int type, int seq, void *data, size_t size);
 
@@ -185,7 +262,7 @@ void wl_free_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl);
 void wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl);
 void wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid);
 void wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl);
-void wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl,  
+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
diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c
new file mode 100644 (file)
index 0000000..1ff7bd5
--- /dev/null
@@ -0,0 +1,2128 @@
+\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
+#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
+
+/* Return a legacy chanspec given a new chanspec
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_ext_chspec_to_legacy(chanspec_t chspec)\r
+{
+       chanspec_t lchspec;
+
+       if (wf_chspec_malformed(chspec)) {
+               ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n",\r
+                       chspec));
+               return INVCHANSPEC;
+       }
+
+       /* get the channel number */
+       lchspec = CHSPEC_CHANNEL(chspec);
+
+       /* convert the band */
+       if (CHSPEC_IS2G(chspec)) {
+               lchspec |= WL_LCHANSPEC_BAND_2G;
+       } else {
+               lchspec |= WL_LCHANSPEC_BAND_5G;
+       }
+
+       /* convert the bw and sideband */
+       if (CHSPEC_IS20(chspec)) {
+               lchspec |= WL_LCHANSPEC_BW_20;
+               lchspec |= WL_LCHANSPEC_CTL_SB_NONE;
+       } else if (CHSPEC_IS40(chspec)) {
+               lchspec |= WL_LCHANSPEC_BW_40;
+               if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_L) {
+                       lchspec |= WL_LCHANSPEC_CTL_SB_LOWER;
+               } else {
+                       lchspec |= WL_LCHANSPEC_CTL_SB_UPPER;
+               }
+       } 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
+                       "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
+{
+       if (ioctl_ver == 1) {\r
+               chanspec = wl_ext_chspec_to_legacy(chanspec);\r
+               if (chanspec == INVCHANSPEC) {
+                       return 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
+       chanspec_t chspec = 0;
+       chanspec_t fw_chspec = 0;\r
+       u32 bw = WL_CHANSPEC_BW_20;\r
+       s32 err = BCME_OK;
+       s32 bw_cap = 0;\r
+       s8 iovar_buf[WLC_IOCTL_SMLEN];\r
+       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.band = WLC_BAND_5G;
+               err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
+                       iovar_buf, WLC_IOCTL_SMLEN, NULL);\r
+               if (err) {
+                       if (err != BCME_UNSUPPORTED) {
+                               ANDROID_ERROR(("bw_cap failed, %d\n", err));\r
+                               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
+                               }
+                               if (bw_cap != WLC_N_BW_20ALL)
+                                       bw = WL_CHANSPEC_BW_40;
+                       }
+               } else {
+                       if (WL_BW_CAP_80MHZ(iovar_buf[0]))\r
+                               bw = WL_CHANSPEC_BW_80;
+                       else if (WL_BW_CAP_40MHZ(iovar_buf[0]))\r
+                               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
+set_channel:
+       chspec = wf_channel2chspec(_chan, bw);
+       if (wf_chspec_valid(chspec)) {
+               fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec);\r
+               if (fw_chspec != INVCHANSPEC) {
+                       if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) {\r
+                               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
+                       } 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
+               } else {
+                       ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__));\r
+                       err = BCME_ERROR;
+               }
+       } else {
+change_bw:
+               if (bw == WL_CHANSPEC_BW_80)
+                       bw = WL_CHANSPEC_BW_40;
+               else if (bw == WL_CHANSPEC_BW_40)
+                       bw = WL_CHANSPEC_BW_20;
+               else
+                       bw = 0;
+               if (bw)
+                       goto set_channel;
+               ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec));\r
+               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
+       if (apsta_params->apstamode == IAPONLY_MODE) // fix for 43455\r
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
+\r
+       wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth);\r
+\r
+       if (apsta_params->apstamode == IAPONLY_MODE) // fix for 43455\r
+               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);;\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
+               /* OPEN-WEP */\r
+               /* 43438a1: wl0: Feb 23 2017 11:24:58 version 7.46.57.8 (r1174) FWID 01-62ddbfa1\r
+                 * sta only wlan0 TBD\r
+                 * ap only wlan0 OK\r
+                 * apsta wlan0 TBD, wlan1 OK\r
+                 */\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
+                       /* WPA2-PSK-AES */\r
+                       /* 43438a1:\r
+                         *  wl0: Feb 23 2017 11:24:58 version 7.46.57.8 (r1174) FWID 01-62ddbfa1\r
+                         *  wl0: Nov 25 2016 15:06:56 version 7.46.57.5.apsta.r4.o12 (Station/Softap) FWID 01-64fb9fe8 es6.c5.n4.a3\r
+                         * sta only: wlan0 OK\r
+                         * ap only: wlan0 OK\r
+                         * apsta: wlan0 OK, wlan1 NG(condigured ok, ping NG, same as dhd_helper)\r
+                         */\r
+                       /* 43455c0: wl0: Feb 20 2017 15:38:37 version 7.45.69.3 (r) FWID 01-485b0401\r
+                         * sta only: wlan0 OK\r
+                         * ap only: wlan0 OK\r
+                         * apsta: wlan0 OK, wlan1 OK\r
+                         */\r
+                       /* 4359c0: wl0: Mar  6 2017 10:16:06 version 9.87.51.7 (r686312) FWID 01-4dcc75d9\r
+                         * sta only: wlan0 OK\r
+                         * ap only: wlan0 OK\r
+                         * apsta: wlan0 OK, wlan1 OK\r
+                         * dualap: wlan0 and wlan1 OK\r
+                         */\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
+/*\r
+terence 20170326:\r
+dhd_priv iapsta_init mode [sta|ap|apsta|dualap] vifname [wlan1]\r
+dhd_priv 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
+dhd_priv iapsta_enable ifname [wlan0|wlan1]\r
+dhd_priv iapsta_disable ifname [wlan0|wlan1]\r
+dhd_priv iapsta_config ifname wlan0 ssid ttt_apsta chan 1 amode wpa2psk emode aes key 12345678 ifname wlan1 ssid ttt_apsta chan 149 amode wpa2psk emode aes key 12345678\r
+\r
+For dualAP procedure:\r
+  1) you must disable both wlan0 and wlan1 first when you would like to enable\r
+    dhd_priv iapsta_disable ifname wlan0; dhd_priv iapsta_disable ifname wlan1\r
+  2) you must enable both wlan0 first and then wlan1\r
+    dhd_priv iapsta_enable ifname wlan0; dhd_priv iapsta_disable ifname wlan1\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
+\r
+       if (apsta_params->action >= ACTION_INIT) {\r
+               ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__));\r
+               return -1;\r
+       }\r
+\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 {\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
+               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
+               wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);\r
+               /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */\r
+               wl_ext_iovar_setint(dev, "arp_ol", 0);\r
+               wl_ext_iovar_setint(dev, "arpoe", 0);\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->vif.ifmode = IAP_MODE;\r
+               /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */\r
+               wl_ext_iovar_setint(dev, "arp_ol", 0);\r
+               wl_ext_iovar_setint(dev, "arpoe", 0);\r
+               wl_ext_iovar_setint(dev, "mpc", 0);\r
+               wl_ext_iovar_setint(dev, "apsta", 1);\r
+               val = 0;\r
+               wl_ext_ioctl(dev, WLC_SET_PM, &val, sizeof(val), 1);\r
+               dhd = dhd_get_pub(dev);\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
+       } else if (apsta_params->apstamode == IDUALAP_MODE) {\r
+               apsta_params->pif.ifmode = IAP_MODE;\r
+               apsta_params->vif.ifmode = IAP_MODE;\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
+               wl_ext_iovar_setint(dev, "arp_ol", 0);\r
+               wl_ext_iovar_setint(dev, "arpoe", 0);\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
+\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->action = ACTION_INIT;\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->action < ACTION_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
+               s32 cfg;
+               s32 val;
+       } bss_setbuf;\r
+       struct wl_apsta_params *apsta_params = &g_apsta_params;\r
+       char ifname[IFNAMSIZ+1];\r
+       struct wl_if_info *cur_if;\r
+\r
+       if (apsta_params->action < ACTION_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_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 (apsta_params->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 (apsta_params->apstamode == IAPSTA_MODE && 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
+       } else if (apsta_params->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
+       apsta_params->action = ACTION_DISABLE;\r
+       printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apsta_params->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
+               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->action < ACTION_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_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
+       if (apstamode == IAPONLY_MODE) {\r
+               wl_ext_iovar_setint(dev, "mpc", 0);\r
+               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
+       } else if (apstamode == IAPSTA_MODE) {\r
+               wl_ext_iovar_setint(dev, "mpc", 0);\r
+               wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid),\r
+                       iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL);\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) {\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(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) {\r
+               wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
+       } else if (apstamode == IAPONLY_MODE) {\r
+               wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
+               wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1);\r
+       } else if (apstamode == IAPSTA_MODE) {\r
+               if (cur_if->ifmode == ISTA_MODE) {\r
+                       wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
+               } else {\r
+                       dhd = dhd_get_pub(dev);\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
+               }\r
+       } else if (apstamode == IDUALAP_MODE) {\r
+               wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);\r
+       }\r
+       printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid);\r
+\r
+       apsta_params->action = ACTION_ENABLE;\r
+\r
+exit:\r
+       return ret;\r
+}\r
+
+void\r
+wl_android_ext_iapsta_disconnect_sta(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
+\r
+       if (apsta_params->apstamode==IAPSTA_MODE && apsta_params->action==ACTION_ENABLE) {\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
+
+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
+       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
old mode 100755 (executable)
new mode 100644 (file)
index 7106db1..f00db47
@@ -255,7 +255,7 @@ static const struct ieee80211_iface_limit common_if_limits[] = {
 #else
 #define NUM_DIFF_CHANNELS 2
 #endif
-static const struct ieee80211_iface_combination
+static struct ieee80211_iface_combination
 common_iface_combinations[] = {
        {
        .num_different_channels = NUM_DIFF_CHANNELS,
@@ -625,7 +625,7 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
             uint8 ie_id, uint8 *data, uint8 data_len);
 #endif /* WL11U */
 
-static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev, void *data);
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev, dhd_pub_t *data);
 static void wl_free_wdev(struct bcm_cfg80211 *cfg);
 #ifdef CONFIG_CFG80211_INTERNAL_REGDB
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
@@ -800,6 +800,13 @@ static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
 };
 #endif                         /* WL_DBG_LEVEL */
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#define ieee80211_band nl80211_band
+#define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ
+#define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ
+#define IEEE80211_NUM_BANDS NUM_NL80211_BANDS
+#endif
+
 #define CHAN2G(_channel, _freq, _flags) {                      \
        .band                   = IEEE80211_BAND_2GHZ,          \
        .center_freq            = (_freq),                      \
@@ -2032,7 +2039,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
        }
 
        if (wl_check_dongle_idle(wiphy) != TRUE) {
-               WL_ERR(("FW is busy to add interface"));
+               WL_ERR(("FW is busy to add interface\n"));
                return -EINVAL;
        }
        if (ap) {
@@ -2049,7 +2056,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                         */
                        if ((cfg->p2p->p2p_go_count > 0) && (type == NL80211_IFTYPE_P2P_GO)) {
                                wl_set_mode_by_netdev(cfg, ndev, WL_MODE_BSS);
-                               WL_ERR(("Fw doesnot support  multiple GO "));
+                               WL_ERR(("Fw doesnot support  multiple GO\n"));
                                return BCME_ERROR;
                        }
                        /* In concurrency case, STA may be already associated in a particular
@@ -2099,7 +2106,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                 */
                if (ndev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
                        wl_set_mode_by_netdev(cfg, ndev, mode);
-               WL_DBG(("Change_virtual_iface for transition from GO/AP to client/STA"));
+               WL_DBG(("Change_virtual_iface for transition from GO/AP to client/STA\n"));
 #ifdef SUPPORT_AP_POWERSAVE
                dhd_set_ap_powersave(dhd, 0, FALSE);
 #endif /* SUPPORT_AP_POWERSAVE */
@@ -2693,7 +2700,6 @@ exit:
        return err;
 }
 
-
 static s32
 wl_do_escan(struct bcm_cfg80211 *cfg, struct wiphy *wiphy, struct net_device *ndev,
        struct cfg80211_scan_request *request)
@@ -2792,7 +2798,8 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
         */
        if (request && (scan_req_iftype(request) == NL80211_IFTYPE_AP)) {
                WL_INFORM(("Scan Command on SoftAP Interface. Ignoring...\n"));
-               return 0;
+// terence 20161023: let it scan in SoftAP mode
+//             return 0;
        }
 
        ndev = ndev_to_wlc_ndev(ndev, cfg);
@@ -2925,7 +2932,8 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
                                        request->ie_len);
 
                                if (unlikely(err)) {
-                                       goto scan_out;
+// terence 20161023: let it scan in SoftAP mode
+//                                     goto scan_out;
                                }
 
                        }
@@ -4576,6 +4584,9 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                kfree(ext_join_params);
                return BCME_ERROR;
        }
+#ifdef WL_EXT_IAPSTA
+       wl_android_ext_iapsta_disconnect_sta(cfg->channel);
+#endif
        err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size,
                cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);
 
@@ -5195,6 +5206,13 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
                        params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
                        WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
                        break;
+#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED)
+               /* to connect to mixed mode AP */
+               case (AES_ENABLED | TKIP_ENABLED): /* TKIP CCMP */
+                       params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+                       WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
+                       break;
+#endif
                default:
                        WL_ERR(("Invalid algo (0x%x)\n", wsec));
                        return -EINVAL;
@@ -5541,6 +5559,10 @@ wl_cfg80211_suspend(struct wiphy *wiphy)
        struct net_info *iter, *next;
        struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
        unsigned long flags;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+       struct cfg80211_scan_info info;
+#endif
+
        if (unlikely(!wl_get_drv_status(cfg, READY, ndev))) {
                WL_INFORM(("device is not ready : status (%d)\n",
                        (int)cfg->status));
@@ -5553,7 +5575,12 @@ wl_cfg80211_suspend(struct wiphy *wiphy)
                }
        spin_lock_irqsave(&cfg->cfgdrv_lock, flags);
        if (cfg->scan_request) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+               info.aborted = true;
+               cfg80211_scan_done(cfg->scan_request, &info);
+#else
                cfg80211_scan_done(cfg->scan_request, true);
+#endif
                cfg->scan_request = NULL;
        }
        for_each_ndev(cfg, iter, next) {
@@ -7209,6 +7236,249 @@ exit:
        return 0;
 }
 
+#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED)
+static u32 wl_get_cipher_type(uint8 type)
+{
+       u32 ret = 0;
+       switch (type) {
+               case WPA_CIPHER_NONE:
+                       ret = 0;
+                       break;
+               case WPA_CIPHER_WEP_40:
+               case WPA_CIPHER_WEP_104:
+                       ret = WEP_ENABLED;
+                       break;
+               case WPA_CIPHER_TKIP:
+                       ret = TKIP_ENABLED;
+                       break;
+               case WPA_CIPHER_AES_CCM:
+                       ret = AES_ENABLED;
+                       break;
+#ifdef BCMWAPI_WPI
+               case WAPI_CIPHER_SMS4:
+                       ret = SMS4_ENABLED;
+                       break;
+#endif
+               default:
+                       WL_ERR(("No Security Info\n"));
+       }
+       return ret;
+}
+
+static u32 wl_get_suite_auth_key_mgmt_type(uint8 type)
+{
+       u32 ret = 0;
+       switch (type) {
+               case RSN_AKM_NONE:
+                       ret = WPA_AUTH_NONE;
+                       break;
+               case RSN_AKM_UNSPECIFIED:
+                       ret = WPA_AUTH_UNSPECIFIED;
+                       break;
+               case RSN_AKM_PSK:
+                       ret = WPA_AUTH_PSK;
+                       break;
+               default:
+                       WL_ERR(("No Key Mgmt Info\n"));
+       }
+       return ret;
+}
+
+static u32 wl_get_suite_auth2_key_mgmt_type(uint8 type)
+{
+       u32 ret = 0;
+       switch (type) {
+               case RSN_AKM_NONE:
+                       ret = WPA_AUTH_NONE;
+                       break;
+               case RSN_AKM_UNSPECIFIED:
+                       ret = WPA2_AUTH_UNSPECIFIED;
+                       break;
+               case RSN_AKM_PSK:
+                       ret = WPA2_AUTH_PSK;
+                       break;
+               default:
+                       WL_ERR(("No Key Mgmt Info\n"));
+       }
+       return ret;
+}
+
+static s32
+wl_validate_wpaie_wpa2ie(struct net_device *dev, wpa_ie_fixed_t *wpaie,
+       bcm_tlv_t *wpa2ie, s32 bssidx)
+{
+       wpa_suite_mcast_t *mcast;
+       wpa_suite_ucast_t *ucast;
+       wpa_suite_auth_key_mgmt_t *mgmt;
+       u16 auth = 0; /* d11 open authentication */
+       u16 count;
+       s32 err = BCME_OK;
+       u32 wme_bss_disable;
+       u16 suite_count;
+       u8 rsn_cap[2];
+       s32 len = 0;
+       u32 i;
+       u32 wsec1, wsec2, wsec;
+       u32 pval = 0;
+       u32 gval = 0;
+       u32 wpa_auth = 0;
+       u32 wpa_auth1 = 0;
+       u32 wpa_auth2 = 0;
+       u8* ptmp;
+
+       if (wpaie == NULL || wpa2ie == NULL)
+               goto exit;
+
+       WL_DBG(("Enter \n"));
+       len = wpaie->length;    /* value length */
+       len -= WPA_IE_TAG_FIXED_LEN;
+       /* check for multicast cipher suite */
+       if (len < WPA_SUITE_LEN) {
+               WL_INFORM(("no multicast cipher suite\n"));
+               goto exit;
+       }
+
+       /* pick up multicast cipher */
+       mcast = (wpa_suite_mcast_t *)&wpaie[1];
+       len -= WPA_SUITE_LEN;
+       if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
+               if (IS_WPA_CIPHER(mcast->type)) {
+                       gval |= wl_get_cipher_type(mcast->type);
+               }
+       }
+       WL_ERR(("\nwpa ie validate\n"));
+       WL_ERR(("wpa ie mcast cipher = 0x%X\n", gval));
+
+       /* Check for unicast suite(s) */
+       if (len < WPA_IE_SUITE_COUNT_LEN) {
+               WL_INFORM(("no unicast suite\n"));
+               goto exit;
+       }
+
+       /* walk thru unicast cipher list and pick up what we recognize */
+       ucast = (wpa_suite_ucast_t *)&mcast[1];
+       count = ltoh16_ua(&ucast->count);
+       len -= WPA_IE_SUITE_COUNT_LEN;
+       for (i = 0; i < count && len >= WPA_SUITE_LEN;
+               i++, len -= WPA_SUITE_LEN) {
+               if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
+                       if (IS_WPA_CIPHER(ucast->list[i].type)) {
+                               pval |= wl_get_cipher_type(ucast->list[i].type);
+                       }
+               }
+       }
+       WL_ERR(("wpa ie ucast count =%d, cipher = 0x%X\n", count, pval));
+
+       /* FOR WPS , set SEC_OW_ENABLED */
+       wsec1 = (pval | gval | SES_OW_ENABLED);
+       WL_ERR(("wpa ie wsec = 0x%X\n", wsec1));
+
+       len -= (count - i) * WPA_SUITE_LEN;
+       /* Check for auth key management suite(s) */
+       if (len < WPA_IE_SUITE_COUNT_LEN) {
+               WL_INFORM((" no auth key mgmt suite\n"));
+               goto exit;
+       }
+       /* walk thru auth management suite list and pick up what we recognize */
+       mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count];
+       count = ltoh16_ua(&mgmt->count);
+       len -= WPA_IE_SUITE_COUNT_LEN;
+       for (i = 0; i < count && len >= WPA_SUITE_LEN;
+               i++, len -= WPA_SUITE_LEN) {
+               if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
+                       if (IS_WPA_AKM(mgmt->list[i].type)) {
+
+                               wpa_auth1 |= wl_get_suite_auth_key_mgmt_type(mgmt->list[i].type);
+                       }
+               }
+
+       }
+       WL_ERR(("wpa ie wpa_suite_auth_key_mgmt count=%d, key_mgmt = 0x%X\n", count, wpa_auth1));
+       WL_ERR(("\nwpa2 ie validate\n"));
+
+       pval = 0;
+       gval = 0;
+       len =  wpa2ie->len;
+       /* check the mcast cipher */
+       mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
+       ptmp = mcast->oui;
+       gval = wl_get_cipher_type(ptmp[DOT11_OUI_LEN]);
+
+       WL_ERR(("wpa2 ie mcast cipher = 0x%X\n", gval));
+       if ((len -= WPA_SUITE_LEN) <= 0)
+       {
+               WL_ERR(("P:wpa2 ie len[%d]", len));
+               return BCME_BADLEN;
+       }
+
+       /* check the unicast cipher */
+       ucast = (wpa_suite_ucast_t *)&mcast[1];
+       suite_count = ltoh16_ua(&ucast->count);
+       WL_ERR((" WPA2 ucast cipher count=%d\n", suite_count));
+       pval |= wl_get_cipher_type(ucast->list[0].type);
+
+       if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) <= 0)
+               return BCME_BADLEN;
+
+       WL_ERR(("wpa2 ie ucast cipher = 0x%X\n", pval));
+
+       /* FOR WPS , set SEC_OW_ENABLED */
+       wsec2 = (pval | gval | SES_OW_ENABLED);
+       WL_ERR(("wpa2 ie wsec = 0x%X\n", wsec2));
+
+       /* check the AKM */
+       mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count];
+       suite_count = ltoh16_ua(&mgmt->count);
+       ptmp = (u8 *)&mgmt->list[0];
+       wpa_auth2 = wl_get_suite_auth2_key_mgmt_type(ptmp[DOT11_OUI_LEN]);
+       WL_ERR(("wpa ie wpa_suite_auth_key_mgmt count=%d, key_mgmt = 0x%X\n", count, wpa_auth2));
+
+       if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) {
+               rsn_cap[0] = *(u8 *)&mgmt->list[suite_count];
+               rsn_cap[1] = *((u8 *)&mgmt->list[suite_count] + 1);
+               if (rsn_cap[0] & (RSN_CAP_16_REPLAY_CNTRS << RSN_CAP_PTK_REPLAY_CNTR_SHIFT)) {
+                       wme_bss_disable = 0;
+               } else {
+                       wme_bss_disable = 1;
+               }
+               WL_DBG(("P:rsn_cap[0]=[0x%X]:wme_bss_disabled[%d]\n", rsn_cap[0], wme_bss_disable));
+
+               /* set wme_bss_disable to sync RSN Capabilities */
+               err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx);
+               if (err < 0) {
+                       WL_ERR(("wme_bss_disable error %d\n", err));
+                       return BCME_ERROR;
+               }
+       } else {
+               WL_DBG(("There is no RSN Capabilities. remained len %d\n", len));
+       }
+
+       wsec = (wsec1 | wsec2);
+       wpa_auth = (wpa_auth1 | wpa_auth2);
+       WL_ERR(("wpa_wpa2 wsec=0x%X wpa_auth=0x%X\n", wsec, wpa_auth));
+
+       /* set auth */
+       err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
+       if (err < 0) {
+               WL_ERR(("auth error %d\n", err));
+               return BCME_ERROR;
+       }
+       /* set wsec */
+       err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
+       if (err < 0) {
+               WL_ERR(("wsec error %d\n", err));
+               return BCME_ERROR;
+       }
+       /* set upper-layer auth */
+       err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
+       if (err < 0) {
+               WL_ERR(("wpa_auth error %d\n", err));
+               return BCME_ERROR;
+       }
+exit:
+       return 0;
+}
+#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */
 
 static s32
 wl_cfg80211_bcn_validate_sec(
@@ -7237,6 +7507,15 @@ wl_cfg80211_bcn_validate_sec(
                WL_DBG(("SoftAP: validating security"));
                /* If wpa2_ie or wpa_ie is present validate it */
 
+#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED)
+               if ((ies->wpa_ie != NULL && ies->wpa2_ie != NULL)) {
+                       if (wl_validate_wpaie_wpa2ie(dev, ies->wpa_ie, ies->wpa2_ie, bssidx)  < 0) {
+                               bss->security_mode = false;
+                               return BCME_ERROR;
+                       }
+               }
+               else {
+#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */
                if ((ies->wpa2_ie || ies->wpa_ie) &&
                        ((wl_validate_wpa2ie(dev, ies->wpa2_ie, bssidx)  < 0 ||
                        wl_validate_wpaie(dev, ies->wpa_ie, bssidx) < 0))) {
@@ -7270,6 +7549,9 @@ wl_cfg80211_bcn_validate_sec(
                                ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
                                GFP_KERNEL);
                }
+#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED)
+               }
+#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */
                if (!ies->wpa2_ie && !ies->wpa_ie) {
                        wl_validate_opensecurity(dev, bssidx, privacy);
                        bss->security_mode = false;
@@ -7697,6 +7979,75 @@ static s32 wl_cfg80211_hostapd_sec(
                        bss->wps_ie = kmemdup(ies->wps_ie, ies->wps_ie_len, GFP_KERNEL);
                }
 
+#if defined(SUPPORT_SOFTAP_WPAWPA2_MIXED)
+               if (ies->wpa_ie != NULL && ies->wpa2_ie != NULL) {
+                       WL_ERR(("update bss - wpa_ie and  wpa2_ie is not null\n"));
+                       if (!bss->security_mode) {
+                               /* change from open mode to security mode */
+                               update_bss = true;
+                               bss->wpa_ie =
+                                       kmemdup(ies->wpa_ie,
+                                       ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
+                                       GFP_KERNEL);
+                               bss->rsn_ie =
+                                       kmemdup(ies->wpa2_ie,
+                                       ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
+                                       GFP_KERNEL);
+                       } else {
+                               /* change from (WPA or WPA2 or WPA/WPA2) to WPA/WPA2 mixed mode */
+                               if (bss->wpa_ie) {
+                                       if (memcmp(bss->wpa_ie,
+                                       ies->wpa_ie, ies->wpa_ie->length +
+                                       WPA_RSN_IE_TAG_FIXED_LEN)) {
+                                               kfree(bss->wpa_ie);
+                                               update_bss = true;
+                                               bss->wpa_ie = kmemdup(ies->wpa_ie,
+                                               ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
+                                               GFP_KERNEL);
+                                       }
+                               }
+                               else {
+                                       update_bss = true;
+                                       bss->wpa_ie =
+                                               kmemdup(ies->wpa_ie,
+                                               ies->wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
+                                               GFP_KERNEL);
+                               }
+                               if (bss->rsn_ie) {
+                                       if (memcmp(bss->rsn_ie,
+                                       ies->wpa2_ie,
+                                       ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) {
+                                               update_bss = true;
+                                               kfree(bss->rsn_ie);
+                                               bss->rsn_ie =
+                                                       kmemdup(ies->wpa2_ie,
+                                                       ies->wpa2_ie->len +
+                                                       WPA_RSN_IE_TAG_FIXED_LEN,
+                                                       GFP_KERNEL);
+                                       }
+                               }
+                               else {
+                                       update_bss = true;
+                                       bss->rsn_ie =
+                                               kmemdup(ies->wpa2_ie,
+                                               ies->wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
+                                               GFP_KERNEL);
+                               }
+                       }
+                       WL_ERR(("update_bss=%d\n", update_bss));
+                       if (update_bss) {
+                               bss->security_mode = true;
+                               wl_cfgp2p_bss(cfg, dev, bssidx, 0);
+                               if (wl_validate_wpaie_wpa2ie(dev, ies->wpa_ie,
+                                       ies->wpa2_ie, bssidx)  < 0) {
+                                       return BCME_ERROR;
+                               }
+                               wl_cfgp2p_bss(cfg, dev, bssidx, 1);
+                       }
+
+               }
+               else
+#endif /* SUPPORT_SOFTAP_WPAWPA2_MIXED */
                if ((ies->wpa_ie != NULL || ies->wpa2_ie != NULL)) {
                        if (!bss->security_mode) {
                                /* change from open mode to security mode */
@@ -8034,7 +8385,7 @@ wl_cfg80211_start_ap(
        /* Set GC/STA SCB expiry timings. */
        if ((err = wl_cfg80211_set_scb_timings(cfg, dev))) {
                WL_ERR(("scb setting failed \n"));
-               /*goto fail;*/
+//             goto fail;
        }
 
        WL_DBG(("** AP/GO Created **\n"));
@@ -8169,9 +8520,8 @@ wl_cfg80211_stop_ap(
                                }
                        }
                } else if (is_rsdb_supported == 0) {
-                       /* terence 20160426: fix softap issue */
-                       err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true);
-                       if (err < 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;
@@ -8428,7 +8778,7 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
        /* Set GC/STA SCB expiry timings. */
        if ((err = wl_cfg80211_set_scb_timings(cfg, dev))) {
                WL_ERR(("scb setting failed \n"));
-               goto fail;
+//             goto fail;
        }
 
        if (wl_get_drv_status(cfg, AP_CREATED, dev)) {
@@ -8941,8 +9291,12 @@ 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
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
 static struct cfg80211_wowlan brcm_wowlan_config = {
        .disconnect = true,
        .gtk_rekey_failure = true,
@@ -8950,13 +9304,12 @@ static struct cfg80211_wowlan brcm_wowlan_config = {
        .four_way_handshake = true,
 };
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */
-#endif
 #endif /* CONFIG_PM */
 
-static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev, void *context)
+static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev, dhd_pub_t *context)
 {
        s32 err = 0;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
+//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
        dhd_pub_t *dhd = (dhd_pub_t *)context;
        BCM_REFERENCE(dhd);
 
@@ -8965,7 +9318,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
                err = -ENODEV;
                return err;
        }
-#endif 
+//#endif 
 
        wdev->wiphy =
            wiphy_new(&wl_cfg80211_ops, sizeof(struct bcm_cfg80211));
@@ -9003,6 +9356,8 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \
        (defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF))
        WL_DBG(("Setting interface combinations for common mode\n"));
+       if (dhd->conf->num_different_channels >= 0)
+               common_iface_combinations[0].num_different_channels = dhd->conf->num_different_channels;
        wdev->wiphy->iface_combinations = common_iface_combinations;
        wdev->wiphy->n_iface_combinations =
                ARRAY_SIZE(common_iface_combinations);
@@ -9090,7 +9445,11 @@ 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.
         */
-       //wdev->wiphy->wowlan_config = &brcm_wowlan_config;
+       /* 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;
 #else
        wdev->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
        wdev->wiphy->wowlan.n_patterns = WL_WOWLAN_MAX_PATTERNS;
@@ -9145,12 +9504,14 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg)
 #if defined(WL_VENDOR_EXT_SUPPORT)
                wl_cfgvendor_detach(wdev->wiphy);
 #endif /* if defined(WL_VENDOR_EXT_SUPPORT) */
+#if defined(CONFIG_PM) && defined(WL_CFG80211_P2P_DEV_IF)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
                /* 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);
                wdev->wiphy->dev.parent = NULL;
                wdev->wiphy = NULL;
@@ -9334,7 +9695,7 @@ static s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, struct wl_bss_info *bi
                offsetof(struct wl_cfg80211_bss_info, frame_buf));
        notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
                u.beacon.variable) + wl_get_ielen(cfg);
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
        freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
        (void)band->band;
 #else
@@ -9573,7 +9934,7 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                        kfree(body);
                return -EINVAL;
        }
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
        freq = ieee80211_channel_to_frequency(channel);
        (void)band->band;
 #else
@@ -9873,7 +10234,7 @@ int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, uint8 *mac
        bi = (struct wl_bss_info *)(cfg->extra_buf + 4);
        channel = wf_chspec_ctlchan(bi->chanspec);
 
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
        freq = ieee80211_channel_to_frequency(channel);
 #else
        if (channel > 14) {
@@ -10126,7 +10487,7 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                                        printf("wl_bss_connect_done succeeded with " MACDBG "\n",
                                                MAC2STRDBG((const u8*)(&e->addr)));
                                        wl_bss_connect_done(cfg, ndev, e, data, true);
-                                       dhd_conf_set_fw_string_cmd(cfg->pub, "phy_oclscdenable", cfg->pub->conf->phy_oclscdenable, 0, FALSE);
+                                       dhd_conf_set_intiovar(cfg->pub, WLC_SET_VAR, "phy_oclscdenable", cfg->pub->conf->phy_oclscdenable, 0, FALSE);
                                        WL_DBG(("joined in BSS network \"%s\"\n",
                                        ((struct wlc_ssid *)
                                         wl_read_prof(cfg, ndev, WL_PROF_SSID))->SSID));
@@ -10222,6 +10583,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
                                }
                                memcpy(&cfg->disconnected_bssid, curbssid, ETHER_ADDR_LEN);
                                wl_clr_drv_status(cfg, CONNECTED, ndev);
@@ -10787,6 +11154,8 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
 #endif 
 
 
+// terence 20161014: fix for roaming issue
+#if 0
        if (memcmp(&cfg->last_roamed_addr, &e->addr, ETHER_ADDR_LEN) == 0) {
                WL_INFORM(("BSSID already updated\n"));
                return err;
@@ -10803,6 +11172,7 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
 #endif  /* DHD_LOSSLESS_ROAMING */
                return  err;
        }
+#endif
 
        wl_get_assoc_ies(cfg, ndev);
        wl_update_prof(cfg, ndev, NULL, (const void *)(e->addr.octet), WL_PROF_BSSID);
@@ -11090,6 +11460,9 @@ wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        u32 len = WL_SCAN_BUF_MAX;
        s32 err = 0;
        unsigned long flags;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+       struct cfg80211_scan_info info;
+#endif
 
        WL_DBG(("Enter \n"));
        if (!wl_get_drv_status(cfg, SCANNING, ndev)) {
@@ -11132,7 +11505,12 @@ scan_done_out:
        del_timer_sync(&cfg->scan_timeout);
        spin_lock_irqsave(&cfg->cfgdrv_lock, flags);
        if (cfg->scan_request) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+               info.aborted = false;
+               cfg80211_scan_done(cfg->scan_request, &info);
+#else
                cfg80211_scan_done(cfg->scan_request, false);
+#endif
                cfg->scan_request = NULL;
        }
        spin_unlock_irqrestore(&cfg->cfgdrv_lock, flags);
@@ -11293,7 +11671,7 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                WL_ERR(("No valid band\n"));
                return -EINVAL;
        }
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
        freq = ieee80211_channel_to_frequency(channel);
        (void)band->band;
 #else
@@ -11943,9 +12321,9 @@ static void wl_scan_timeout(unsigned long data)
 #endif /* CUSTOMER_HW4_DEBUG */
 
        // terence 20130729: workaround to fix out of memory in firmware
-//     if (dhd_conf_get_chip(dhd_get_pub(dev)) == BCM43362_CHIP_ID) {
+//     if (dhd_conf_get_chip(dhd_get_pub(ndev)) == BCM43362_CHIP_ID) {
 //             WL_ERR(("Send hang event\n"));
-//             net_os_send_hang_message(dev);
+//             net_os_send_hang_message(ndev);
 //     }
 }
 
@@ -12136,6 +12514,10 @@ static s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg,
        s32 err = BCME_OK;
        unsigned long flags;
        struct net_device *dev;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+       struct cfg80211_scan_info info;
+       info.aborted = aborted;
+#endif
 
        WL_DBG(("Enter \n"));
 
@@ -12194,7 +12576,11 @@ static s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg,
        }
 #endif /* WL_SCHED_SCAN */
        if (likely(cfg->scan_request)) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+               cfg80211_scan_done(cfg->scan_request, &info);
+#else
                cfg80211_scan_done(cfg->scan_request, aborted);
+#endif
                cfg->scan_request = NULL;
                DHD_OS_SCAN_WAKE_UNLOCK((dhd_pub_t *)(cfg->pub));
                DHD_ENABLE_RUNTIME_PM((dhd_pub_t *)(cfg->pub));
@@ -12299,7 +12685,7 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 
        }
        if (!ndev || (!wl_get_drv_status(cfg, SCANNING, ndev) && !cfg->sched_scan_running)) {
-               WL_DBG(("escan is not ready ndev %p drv_status 0x%x e_type %d e_states %d\n",
+               WL_ERR(("escan is not ready ndev %p drv_status 0x%x e_type %d e_states %d\n",
                        ndev, wl_get_drv_status(cfg, SCANNING, ndev),
                        ntoh32(e->event_type), ntoh32(e->status)));
                goto exit;
@@ -12788,6 +13174,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                wl_cfg80211_determine_vsdb_mode(cfg);
                if (primary_dev == _net_info->ndev) {
                        pm = PM_FAST;
+                       if (dhd_conf_get_pm(dhd) >= 0)
+                               pm = dhd_conf_get_pm(dhd);
                        if ((err = wldev_ioctl(_net_info->ndev, WLC_SET_PM, &pm,
                                        sizeof(pm), true)) != 0) {
                                if (err == -ENODEV)
@@ -13608,7 +13996,7 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap)
                if (!dhd_conf_match_channel(cfg->pub, channel))
                        continue;
                if (index <  array_size) {
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
                        band_chan_arr[index].center_freq =
                                ieee80211_channel_to_frequency(channel);
 #else
@@ -14003,6 +14391,10 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg)
        dhd_pub_t *dhd =  (dhd_pub_t *)(cfg->pub);
 #endif
 #endif /* PROP_TXSTATUS_VSDB */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+       struct cfg80211_scan_info info;
+#endif
+
        WL_DBG(("In\n"));
        /* Delete pm_enable_work */
        wl_add_remove_pm_enable_work(cfg, WL_PM_WORKQ_DEL);
@@ -14062,7 +14454,12 @@ _Pragma("GCC diagnostic pop")
 
        spin_lock_irqsave(&cfg->cfgdrv_lock, flags);
        if (cfg->scan_request) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+               info.aborted = true;
+               cfg80211_scan_done(cfg->scan_request, &info);
+#else
                cfg80211_scan_done(cfg->scan_request, true);
+#endif
                cfg->scan_request = NULL;
        }
        spin_unlock_irqrestore(&cfg->cfgdrv_lock, flags);
@@ -14600,7 +14997,7 @@ s32 wl_cfg80211_channel_to_freq(u32 channel)
 {
        int freq = 0;
 
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
        freq = ieee80211_channel_to_frequency(channel);
 #else
        {
@@ -14933,6 +15330,7 @@ wl_cfg80211_set_auto_channel_scan_state(struct net_device *ndev)
        ret = wl_notify_escan_complete(cfg, ndev, true, true);
        if (ret < 0) {
                WL_ERR(("set scan abort failed, error = %d\n", ret));
+               ret = BCME_OK; // terence 20140115: fix escan_complete error
                goto done;
        }
 
@@ -15161,61 +15559,71 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len)
                goto done;
        }
 
-       /* Best channel selection in 2.4GHz band. */
-       ret = wl_cfg80211_get_chanspecs_2g(ndev, (void *)buf, CHANSPEC_BUF_SIZE);
-       if (ret < 0) {
-               WL_ERR(("can't get chanspecs in 2.4GHz, error = %d\n", ret));
-               goto done;
-       }
+       ret = wldev_ioctl(dev, WLC_GET_BAND, &band_cur, sizeof(band_cur), false);
+       if (band_cur != WLC_BAND_5G) {
+               /* Best channel selection in 2.4GHz band. */
+               ret = wl_cfg80211_get_chanspecs_2g(ndev, (void *)buf, CHANSPEC_BUF_SIZE);
+               if (ret < 0) {
+                       WL_ERR(("can't get chanspecs in 2.4GHz, error = %d\n", ret));
+                       goto done;
+               }
 
-       ret = wl_cfg80211_get_best_channel(ndev, (void *)buf, CHANSPEC_BUF_SIZE,
-               &channel);
-       if (ret < 0) {
-               WL_ERR(("can't select best channel scan in 2.4GHz, error = %d\n", ret));
-               goto done;
-       }
+               ret = wl_cfg80211_get_best_channel(ndev, (void *)buf, CHANSPEC_BUF_SIZE,
+                       &channel);
+               if (ret < 0) {
+                       WL_ERR(("can't select best channel scan in 2.4GHz, error = %d\n", ret));
+                       goto done;
+               }
 
-       if (CHANNEL_IS_2G(channel)) {
-               channel = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
-       } else {
-               WL_ERR(("invalid 2.4GHz channel, channel = %d\n", channel));
-               channel = 0;
+               if (CHANNEL_IS_2G(channel)) {
+#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
+               } else {
+                       WL_ERR(("invalid 2.4GHz channel, channel = %d\n", channel));
+                       channel = 0;
+               }
        }
-
        pos += snprintf(pos, total_len, "%04d ", channel);
 
-       // terence 20140120: fix for some chipsets only return 2.4GHz channel (4330b2/43341b0/4339a0)
-       ret = wldev_ioctl(dev, WLC_GET_BAND, &band_cur, sizeof(band_cur), false);
-       band = band_cur==WLC_BAND_2G ? band_cur : WLC_BAND_5G;
-       ret = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), true);
-       if (ret < 0)
-               WL_ERR(("WLC_SET_BAND error %d\n", ret));
+       if (band_cur != WLC_BAND_2G) {
+               // terence 20140120: fix for some chipsets only return 2.4GHz channel (4330b2/43341b0/4339a0)
+               band = band_cur==WLC_BAND_2G ? band_cur : WLC_BAND_5G;
+               ret = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), true);
+               if (ret < 0)
+                       WL_ERR(("WLC_SET_BAND error %d\n", ret));
 
-       /* Best channel selection in 5GHz band. */
-       ret = wl_cfg80211_get_chanspecs_5g(ndev, (void *)buf, CHANSPEC_BUF_SIZE);
-       if (ret < 0) {
-               WL_ERR(("can't get chanspecs in 5GHz, error = %d\n", ret));
-               goto done;
-       }
-
-       ret = wl_cfg80211_get_best_channel(ndev, (void *)buf, CHANSPEC_BUF_SIZE,
-               &channel);
-       if (ret < 0) {
-               WL_ERR(("can't select best channel scan in 5GHz, error = %d\n", ret));
-               goto done;
-       }
+               /* Best channel selection in 5GHz band. */
+               ret = wl_cfg80211_get_chanspecs_5g(ndev, (void *)buf, CHANSPEC_BUF_SIZE);
+               if (ret < 0) {
+                       WL_ERR(("can't get chanspecs in 5GHz, error = %d\n", ret));
+                       goto done;
+               }
 
-       if (CHANNEL_IS_5G(channel)) {
-               channel = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
-       } else {
-               WL_ERR(("invalid 5GHz channel, channel = %d\n", channel));
-               channel = 0;
-       }
+               ret = wl_cfg80211_get_best_channel(ndev, (void *)buf, CHANSPEC_BUF_SIZE,
+                       &channel);
+               if (ret < 0) {
+                       WL_ERR(("can't select best channel scan in 5GHz, error = %d\n", ret));
+                       goto done;
+               }
 
-       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));
+               if (CHANNEL_IS_5G(channel)) {
+#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
+               } else {
+                       WL_ERR(("invalid 5GHz channel, channel = %d\n", channel));
+                       channel = 0;
+               }
 
+               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, "%04d ", channel);
 
        /* Set overall best channel same as 5GHz best channel. */
@@ -16073,6 +16481,9 @@ int wl_cfg80211_scan_stop(bcm_struct_cfgdev *cfgdev)
        unsigned long flags;
        int clear_flag = 0;
        int ret = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+       struct cfg80211_scan_info info;
+#endif
 
        WL_TRACE(("Enter\n"));
 
@@ -16089,7 +16500,12 @@ int wl_cfg80211_scan_stop(bcm_struct_cfgdev *cfgdev)
        if (cfg->scan_request && cfg->scan_request->dev == cfgdev)
 #endif
        {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+               info.aborted = true;
+               cfg80211_scan_done(cfg->scan_request, &info);
+#else
                cfg80211_scan_done(cfg->scan_request, true);
+#endif
                cfg->scan_request = NULL;
                clear_flag = 1;
        }
@@ -16154,6 +16570,7 @@ static void wl_cfg80211_work_handler(struct work_struct * work)
        struct net_info *iter, *next;
        s32 err = BCME_OK;
        s32 pm = PM_FAST;
+       dhd_pub_t *dhd;
        BCM_SET_CONTAINER_OF(cfg, work, struct bcm_cfg80211, pm_enable_work.work);
        WL_DBG(("Enter \n"));
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
@@ -16169,6 +16586,9 @@ _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
                                wl_get_mode_by_netdev(cfg, iter->ndev) != WL_MODE_IBSS))
                                continue;
                        if (iter->ndev) {
+                               dhd = (dhd_pub_t *)(cfg->pub);
+                               if (dhd_conf_get_pm(dhd) >= 0)
+                                       pm = dhd_conf_get_pm(dhd);
                                if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM,
                                                &pm, sizeof(pm), true)) != 0) {
                                        if (err == -ENODEV)
@@ -17432,6 +17852,7 @@ wl_check_dongle_idle(struct wiphy *wiphy)
        struct channel_info ci;
        if (!cfg)
                return FALSE;
+       return TRUE; // terence 20160426
        /* Use primary I/F for sending cmds down to firmware */
        primary_ndev = bcmcfg_to_prmry_ndev(cfg);
 
index 7e2dc0daa18c4381c1cf7f882b0f73467d5d8a05..9e970400175a3fe1fa6b31791495c411bebc848d 100755 (executable)
@@ -192,6 +192,18 @@ enum wl_cfgp2p_status {
                add_timer(timer); \
        } while (0);
 
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 0, 8))
+#ifdef WL_SUPPORT_BACKPORTED_KPATCHES
+#undef WL_SUPPORT_BACKPORTED_KPATCHES
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#ifdef WL_CFG80211_STA_EVENT
+#undef WL_CFG80211_STA_EVENT
+#endif
+#endif
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) && !defined(WL_CFG80211_P2P_DEV_IF)
 #define WL_CFG80211_P2P_DEV_IF
 
index 25ac1158d6e736fe807a698506351bf0c2dbbe3c..6be090acae8ecfc91a9b25c536d839644c0ec60f 100644 (file)
@@ -1,75 +1,75 @@
-
-#ifndef _wl_escan_
-#define _wl_escan_
-
-#include <linux/wireless.h>
-#include <wl_iw.h>
-#include <dngl_stats.h>
-#include <dhd.h>
-#include <linux/time.h>
-
-
-#ifdef DHD_MAX_IFS
-#define WL_MAX_IFS DHD_MAX_IFS
-#else
-#define WL_MAX_IFS 16
-#endif
-
-#define ESCAN_BUF_SIZE (64 * 1024)
-
-#define WL_ESCAN_TIMER_INTERVAL_MS     10000 /* Scan timeout */
-
-/* event queue for cfg80211 main event */
-struct escan_event_q {
-       struct list_head eq_list;
-       u32 etype;
-       wl_event_msg_t emsg;
-       s8 edata[1];
-};
-
-/* donlge escan state */
-enum escan_state {
-       ESCAN_STATE_IDLE,
-       ESCAN_STATE_SCANING
-};
-
-struct wl_escan_info;
-
-typedef s32(*ESCAN_EVENT_HANDLER) (struct wl_escan_info *escan,
-                            const wl_event_msg_t *e, void *data);
-
-typedef struct wl_escan_info {
-       struct net_device *dev;
-       dhd_pub_t *pub;
-       struct timer_list scan_timeout;   /* Timer for catch scan event timeout */
-       int    escan_state;
-       int ioctl_ver;
-
-       char ioctlbuf[WLC_IOCTL_SMLEN];
-       u8 escan_buf[ESCAN_BUF_SIZE];
-       struct wl_scan_results *bss_list;
-       struct wl_scan_results *scan_results;
-       struct ether_addr disconnected_bssid;
-       u8 *escan_ioctl_buf;
-       spinlock_t eq_lock;     /* for event queue synchronization */
-       struct list_head eq_list;       /* used for event queue */
-       tsk_ctl_t event_tsk;            /* task of main event handler thread */
-       ESCAN_EVENT_HANDLER evt_handler[WLC_E_LAST];
-       struct mutex usr_sync;  /* maily for up/down synchronization */
-} wl_escan_info_t;
-
-void wl_escan_event(struct net_device *ndev, const wl_event_msg_t * e, void *data);
-
-int wl_escan_set_scan(
-       struct net_device *dev,
-       struct iw_request_info *info,
-       union iwreq_data *wrqu,
-       char *extra
-);
-int wl_escan_get_scan(struct net_device *dev,  struct iw_request_info *info,
-       struct iw_point *dwrq, char *extra);
-int wl_escan_attach(struct net_device *dev, void * dhdp);
-void wl_escan_detach(void);
-
-#endif /* _wl_escan_ */
-
+\r
+#ifndef _wl_escan_\r
+#define _wl_escan_\r
+\r
+#include <linux/wireless.h>\r
+#include <wl_iw.h>\r
+#include <dngl_stats.h>\r
+#include <dhd.h>\r
+#include <linux/time.h>\r
+\r
+\r
+#ifdef DHD_MAX_IFS\r
+#define WL_MAX_IFS DHD_MAX_IFS\r
+#else\r
+#define WL_MAX_IFS 16\r
+#endif\r
+\r
+#define ESCAN_BUF_SIZE (64 * 1024)\r
+\r
+#define WL_ESCAN_TIMER_INTERVAL_MS     10000 /* Scan timeout */\r
+\r
+/* event queue for cfg80211 main event */\r
+struct escan_event_q {\r
+       struct list_head eq_list;\r
+       u32 etype;\r
+       wl_event_msg_t emsg;\r
+       s8 edata[1];\r
+};\r
+\r
+/* donlge escan state */\r
+enum escan_state {\r
+       ESCAN_STATE_IDLE,\r
+       ESCAN_STATE_SCANING\r
+};\r
+\r
+struct wl_escan_info;\r
+\r
+typedef s32(*ESCAN_EVENT_HANDLER) (struct wl_escan_info *escan,\r
+                            const wl_event_msg_t *e, void *data);\r
+\r
+typedef struct wl_escan_info {\r
+       struct net_device *dev;\r
+       dhd_pub_t *pub;\r
+       struct timer_list scan_timeout;   /* Timer for catch scan event timeout */\r
+       int    escan_state;\r
+       int ioctl_ver;\r
+\r
+       char ioctlbuf[WLC_IOCTL_SMLEN];\r
+       u8 escan_buf[ESCAN_BUF_SIZE];\r
+       struct wl_scan_results *bss_list;\r
+       struct wl_scan_results *scan_results;\r
+       struct ether_addr disconnected_bssid;\r
+       u8 *escan_ioctl_buf;\r
+       spinlock_t eq_lock;     /* for event queue synchronization */\r
+       struct list_head eq_list;       /* used for event queue */\r
+       tsk_ctl_t event_tsk;            /* task of main event handler thread */\r
+       ESCAN_EVENT_HANDLER evt_handler[WLC_E_LAST];\r
+       struct mutex usr_sync;  /* maily for up/down synchronization */\r
+} wl_escan_info_t;\r
+\r
+void wl_escan_event(struct net_device *ndev, const wl_event_msg_t * e, void *data);\r
+\r
+int wl_escan_set_scan(\r
+       struct net_device *dev,\r
+       struct iw_request_info *info,\r
+       union iwreq_data *wrqu,\r
+       char *extra\r
+);\r
+int wl_escan_get_scan(struct net_device *dev,  struct iw_request_info *info,\r
+       struct iw_point *dwrq, char *extra);\r
+int wl_escan_attach(struct net_device *dev, void * dhdp);\r
+void wl_escan_detach(void);\r
+\r
+#endif /* _wl_escan_ */\r
+\r
index 9f5163cc223f11a574f128ddb3daacabf6e77dd7..393711419b5f4b0a96f6afb2ebb6baac3f437e9e 100644 (file)
@@ -610,7 +610,7 @@ wl_iw_set_freq(
        WL_ERROR(("%s: chan=%d\n", __FUNCTION__, chan));
        chan = htod32(chan);
        if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) {
-               WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
+               WL_ERROR(("%s: WLC_SET_CHANNEL failed (%d).\n", __FUNCTION__, error));
                return error;
        }
 
@@ -1494,7 +1494,7 @@ wl_iw_get_scan(
                // terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
                rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
                channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
-               WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, merge broadcast SSID=\"%s\"\n",
+               WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, SSID=\"%s\"\n",
                __FUNCTION__, MAC2STR(bi->BSSID.octet), channel, rssi, bi->SSID));
 
                /* First entry must be the BSSID */
@@ -1628,7 +1628,7 @@ wl_iw_iscan_get_scan(
                        // terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
                        rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
                        channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
-                       WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, merge broadcast SSID=\"%s\"\n",
+                       WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, SSID=\"%s\"\n",
                        __FUNCTION__, MAC2STR(bi->BSSID.octet), channel, rssi, bi->SSID));
 
                        /* First entry must be the BSSID */
@@ -3546,6 +3546,7 @@ int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstat
                goto done;
 
        rssi = dtoh32(scb_val.val);
+       rssi = MIN(rssi, RSSI_MAXVAL);
        WL_TRACE(("wl_iw_get_wireless_stats rssi=%d ****** \n", rssi));
        if (rssi <= WL_IW_RSSI_NO_SIGNAL)
                wstats->qual.qual = 0;
@@ -3879,7 +3880,6 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
        iscan->dev = dev;
        iscan->iscan_state = ISCAN_STATE_IDLE;
 
-
        /* Set up the timer */
        iscan->timer_ms    = 2000;
        init_timer(&iscan->timer);
old mode 100755 (executable)
new mode 100644 (file)
index 247e0df..c09e451
@@ -355,6 +355,7 @@ int wldev_get_datarate(struct net_device *dev, int *datarate)
        return error;
 }
 
+#ifdef WL_CFG80211
 extern chanspec_t
 wl_chspec_driver_to_host(chanspec_t chanspec);
 #define WL_EXTRA_BUF_MAX 2048
@@ -406,6 +407,8 @@ int wldev_get_mode(
        }
        return error;
 }
+#endif
+
 int wldev_set_country(
        struct net_device *dev, char *country_code, bool notify, bool user_enforced, int revinfo)
 {
@@ -441,9 +444,9 @@ int wldev_set_country(
                cspec.rev = revinfo;
                memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
                memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
-               error = dhd_conf_get_country_from_config(dhd_get_pub(dev), &cspec);\r
-               if (error)\r
-                       dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);\r
+               error = dhd_conf_get_country_from_config(dhd_get_pub(dev), &cspec);
+               if (error)
+                       dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
                error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
                        smbuf, sizeof(smbuf), NULL);
                if (error < 0) {