bcmdhd_1_77: Import A320F (A320FLXXU2CRE3) Oreo driver
authorDanny Wood <danwood76@gmail.com>
Tue, 30 Oct 2018 08:43:30 +0000 (08:43 +0000)
committerDanny Wood <danwood76@gmail.com>
Fri, 30 Nov 2018 11:00:58 +0000 (11:00 +0000)
164 files changed:
drivers/net/wireless/bcmdhd_1_77/Kconfig
drivers/net/wireless/bcmdhd_1_77/Makefile
drivers/net/wireless/bcmdhd_1_77/Makefile.jb
drivers/net/wireless/bcmdhd_1_77/Makefile.jbp
drivers/net/wireless/bcmdhd_1_77/Makefile.kk
drivers/net/wireless/bcmdhd_1_77/Makefile.lp
drivers/net/wireless/bcmdhd_1_77/aiutils.c
drivers/net/wireless/bcmdhd_1_77/bcm_app_utils.c
drivers/net/wireless/bcmdhd_1_77/bcmevent.c
drivers/net/wireless/bcmdhd_1_77/bcmsdh.c
drivers/net/wireless/bcmdhd_1_77/bcmsdh_linux.c
drivers/net/wireless/bcmdhd_1_77/bcmsdh_sdmmc.c
drivers/net/wireless/bcmdhd_1_77/bcmsdh_sdmmc_linux.c
drivers/net/wireless/bcmdhd_1_77/bcmutils.c
drivers/net/wireless/bcmdhd_1_77/bcmwifi_channels.c
drivers/net/wireless/bcmdhd_1_77/bcmwifi_channels.h
drivers/net/wireless/bcmdhd_1_77/bcmwifi_rates.h
drivers/net/wireless/bcmdhd_1_77/bcmxtlv.c
drivers/net/wireless/bcmdhd_1_77/dhd.h
drivers/net/wireless/bcmdhd_1_77/dhd_bus.h
drivers/net/wireless/bcmdhd_1_77/dhd_cdc.c
drivers/net/wireless/bcmdhd_1_77/dhd_cfg80211.c
drivers/net/wireless/bcmdhd_1_77/dhd_cfg80211.h
drivers/net/wireless/bcmdhd_1_77/dhd_common.c
drivers/net/wireless/bcmdhd_1_77/dhd_custom_cis.c
drivers/net/wireless/bcmdhd_1_77/dhd_custom_exynos.c
drivers/net/wireless/bcmdhd_1_77/dhd_custom_gpio.c
drivers/net/wireless/bcmdhd_1_77/dhd_custom_memprealloc.c
drivers/net/wireless/bcmdhd_1_77/dhd_custom_msm.c
drivers/net/wireless/bcmdhd_1_77/dhd_custom_sec.c
drivers/net/wireless/bcmdhd_1_77/dhd_dbg.h
drivers/net/wireless/bcmdhd_1_77/dhd_debug.c
drivers/net/wireless/bcmdhd_1_77/dhd_debug.h
drivers/net/wireless/bcmdhd_1_77/dhd_debug_linux.c
drivers/net/wireless/bcmdhd_1_77/dhd_flowring.c
drivers/net/wireless/bcmdhd_1_77/dhd_flowring.h
drivers/net/wireless/bcmdhd_1_77/dhd_ip.c
drivers/net/wireless/bcmdhd_1_77/dhd_ip.h
drivers/net/wireless/bcmdhd_1_77/dhd_linux.c
drivers/net/wireless/bcmdhd_1_77/dhd_linux.h
drivers/net/wireless/bcmdhd_1_77/dhd_linux_platdev.c
drivers/net/wireless/bcmdhd_1_77/dhd_linux_sched.c
drivers/net/wireless/bcmdhd_1_77/dhd_linux_wq.c
drivers/net/wireless/bcmdhd_1_77/dhd_linux_wq.h
drivers/net/wireless/bcmdhd_1_77/dhd_mschdbg.c
drivers/net/wireless/bcmdhd_1_77/dhd_mschdbg.h
drivers/net/wireless/bcmdhd_1_77/dhd_msgbuf.c
drivers/net/wireless/bcmdhd_1_77/dhd_pcie.c
drivers/net/wireless/bcmdhd_1_77/dhd_pcie.h
drivers/net/wireless/bcmdhd_1_77/dhd_pcie_linux.c
drivers/net/wireless/bcmdhd_1_77/dhd_pktlog.c [new file with mode: 0644]
drivers/net/wireless/bcmdhd_1_77/dhd_pktlog.h [new file with mode: 0644]
drivers/net/wireless/bcmdhd_1_77/dhd_pno.c
drivers/net/wireless/bcmdhd_1_77/dhd_pno.h
drivers/net/wireless/bcmdhd_1_77/dhd_proto.h
drivers/net/wireless/bcmdhd_1_77/dhd_rtt.c
drivers/net/wireless/bcmdhd_1_77/dhd_rtt.h
drivers/net/wireless/bcmdhd_1_77/dhd_sdio.c
drivers/net/wireless/bcmdhd_1_77/dhd_sec_feature.h
drivers/net/wireless/bcmdhd_1_77/dhd_wlfc.c
drivers/net/wireless/bcmdhd_1_77/dhd_wlfc.h
drivers/net/wireless/bcmdhd_1_77/dngl_stats.h
drivers/net/wireless/bcmdhd_1_77/document/ChangeHistory.txt
drivers/net/wireless/bcmdhd_1_77/hnd_pktpool.c
drivers/net/wireless/bcmdhd_1_77/hnd_pktq.c
drivers/net/wireless/bcmdhd_1_77/hndpmu.c
drivers/net/wireless/bcmdhd_1_77/include/802.11.h
drivers/net/wireless/bcmdhd_1_77/include/802.11s.h
drivers/net/wireless/bcmdhd_1_77/include/802.1d.h
drivers/net/wireless/bcmdhd_1_77/include/802.3.h
drivers/net/wireless/bcmdhd_1_77/include/aidmp.h
drivers/net/wireless/bcmdhd_1_77/include/bcm_cfg.h
drivers/net/wireless/bcmdhd_1_77/include/bcm_mpool_pub.h
drivers/net/wireless/bcmdhd_1_77/include/bcm_ring.h
drivers/net/wireless/bcmdhd_1_77/include/bcmcdc.h
drivers/net/wireless/bcmdhd_1_77/include/bcmdefs.h
drivers/net/wireless/bcmdhd_1_77/include/bcmdevs.h
drivers/net/wireless/bcmdhd_1_77/include/bcmendian.h
drivers/net/wireless/bcmdhd_1_77/include/bcmeth.h
drivers/net/wireless/bcmdhd_1_77/include/bcmevent.h
drivers/net/wireless/bcmdhd_1_77/include/bcmip.h
drivers/net/wireless/bcmdhd_1_77/include/bcmipv6.h
drivers/net/wireless/bcmdhd_1_77/include/bcmmsgbuf.h
drivers/net/wireless/bcmdhd_1_77/include/bcmpcie.h
drivers/net/wireless/bcmdhd_1_77/include/bcmsdbus.h
drivers/net/wireless/bcmdhd_1_77/include/bcmsdh.h
drivers/net/wireless/bcmdhd_1_77/include/bcmsdh_sdmmc.h
drivers/net/wireless/bcmdhd_1_77/include/bcmsdpcm.h
drivers/net/wireless/bcmdhd_1_77/include/bcmsdstd.h
drivers/net/wireless/bcmdhd_1_77/include/bcmtcp.h
drivers/net/wireless/bcmdhd_1_77/include/bcmutils.h
drivers/net/wireless/bcmdhd_1_77/include/brcm_nl80211.h
drivers/net/wireless/bcmdhd_1_77/include/dhd_daemon.h
drivers/net/wireless/bcmdhd_1_77/include/dhdioctl.h
drivers/net/wireless/bcmdhd_1_77/include/dnglevent.h
drivers/net/wireless/bcmdhd_1_77/include/epivers.h
drivers/net/wireless/bcmdhd_1_77/include/ethernet.h
drivers/net/wireless/bcmdhd_1_77/include/event_log.h
drivers/net/wireless/bcmdhd_1_77/include/event_log_payload.h
drivers/net/wireless/bcmdhd_1_77/include/event_log_set.h
drivers/net/wireless/bcmdhd_1_77/include/event_log_tag.h
drivers/net/wireless/bcmdhd_1_77/include/event_trace.h
drivers/net/wireless/bcmdhd_1_77/include/hnd_armtrap.h
drivers/net/wireless/bcmdhd_1_77/include/hnd_cons.h
drivers/net/wireless/bcmdhd_1_77/include/hnd_debug.h
drivers/net/wireless/bcmdhd_1_77/include/hnd_pktpool.h
drivers/net/wireless/bcmdhd_1_77/include/hnd_pktq.h
drivers/net/wireless/bcmdhd_1_77/include/hndpmu.h
drivers/net/wireless/bcmdhd_1_77/include/hndsoc.h
drivers/net/wireless/bcmdhd_1_77/include/linux_osl.h
drivers/net/wireless/bcmdhd_1_77/include/linuxver.h
drivers/net/wireless/bcmdhd_1_77/include/msgtrace.h
drivers/net/wireless/bcmdhd_1_77/include/nan.h
drivers/net/wireless/bcmdhd_1_77/include/osl.h
drivers/net/wireless/bcmdhd_1_77/include/osl_decl.h
drivers/net/wireless/bcmdhd_1_77/include/osl_ext.h
drivers/net/wireless/bcmdhd_1_77/include/p2p.h
drivers/net/wireless/bcmdhd_1_77/include/packed_section_end.h
drivers/net/wireless/bcmdhd_1_77/include/packed_section_start.h
drivers/net/wireless/bcmdhd_1_77/include/pcicfg.h
drivers/net/wireless/bcmdhd_1_77/include/pcie_core.h
drivers/net/wireless/bcmdhd_1_77/include/sbchipc.h
drivers/net/wireless/bcmdhd_1_77/include/sbconfig.h
drivers/net/wireless/bcmdhd_1_77/include/sbgci.h
drivers/net/wireless/bcmdhd_1_77/include/sbhnddma.h
drivers/net/wireless/bcmdhd_1_77/include/sbpcmcia.h
drivers/net/wireless/bcmdhd_1_77/include/sbsdio.h
drivers/net/wireless/bcmdhd_1_77/include/sbsdpcmdev.h
drivers/net/wireless/bcmdhd_1_77/include/sbsocram.h
drivers/net/wireless/bcmdhd_1_77/include/sbsysmem.h
drivers/net/wireless/bcmdhd_1_77/include/sdio.h
drivers/net/wireless/bcmdhd_1_77/include/sdioh.h
drivers/net/wireless/bcmdhd_1_77/include/sdiovar.h
drivers/net/wireless/bcmdhd_1_77/include/siutils.h
drivers/net/wireless/bcmdhd_1_77/include/typedefs.h
drivers/net/wireless/bcmdhd_1_77/include/vlan.h
drivers/net/wireless/bcmdhd_1_77/include/wlfc_proto.h
drivers/net/wireless/bcmdhd_1_77/include/wlioctl.h
drivers/net/wireless/bcmdhd_1_77/include/wlioctl_defs.h
drivers/net/wireless/bcmdhd_1_77/include/wlioctl_utils.h
drivers/net/wireless/bcmdhd_1_77/include/wpa.h
drivers/net/wireless/bcmdhd_1_77/linux_osl.c
drivers/net/wireless/bcmdhd_1_77/pcie_core.c
drivers/net/wireless/bcmdhd_1_77/sbutils.c
drivers/net/wireless/bcmdhd_1_77/siutils.c
drivers/net/wireless/bcmdhd_1_77/siutils_priv.h
drivers/net/wireless/bcmdhd_1_77/wl_android.c
drivers/net/wireless/bcmdhd_1_77/wl_android.h
drivers/net/wireless/bcmdhd_1_77/wl_cfg80211.c
drivers/net/wireless/bcmdhd_1_77/wl_cfg80211.h
drivers/net/wireless/bcmdhd_1_77/wl_cfg_btcoex.c
drivers/net/wireless/bcmdhd_1_77/wl_cfgnan.c
drivers/net/wireless/bcmdhd_1_77/wl_cfgnan.h
drivers/net/wireless/bcmdhd_1_77/wl_cfgp2p.c
drivers/net/wireless/bcmdhd_1_77/wl_cfgp2p.h
drivers/net/wireless/bcmdhd_1_77/wl_cfgvendor.c
drivers/net/wireless/bcmdhd_1_77/wl_cfgvendor.h
drivers/net/wireless/bcmdhd_1_77/wl_linux_mon.c
drivers/net/wireless/bcmdhd_1_77/wl_roam.c
drivers/net/wireless/bcmdhd_1_77/wl_statreport.c [new file with mode: 0644]
drivers/net/wireless/bcmdhd_1_77/wl_statreport.h [new file with mode: 0644]
drivers/net/wireless/bcmdhd_1_77/wlc_types.h
drivers/net/wireless/bcmdhd_1_77/wldev_common.c
drivers/net/wireless/bcmdhd_1_77/wldev_common.h

index 4f76c4606a3e85bdc599c5892d06543ce5f296cf..3bb868fb11d85ac766f111e03314115a1f612127 100644 (file)
@@ -82,6 +82,13 @@ config BCM43241
          This module adds support for wireless adapters based on
          Broadcom 43241 chipset.
 
+config BCM43456
+        tristate "Broadcom 43456 wireless cards support"
+        depends on BROADCOM_WIFI
+        ---help---
+          This module adds support for wireless adapters based on
+          Broadcom 43456 chipset.
+
 config BCM43455
         tristate "Broadcom 43455 wireless cards support"
         depends on BROADCOM_WIFI
@@ -106,16 +113,16 @@ config BCM43454
 config BCMDHD_FW_PATH
        depends on BROADCOM_WIFI
        string "Firmware path"
-       default "/system/etc/firmware/fw_bcmdhd.bin"
+       default "/etc/wifi/bcmdhd_sta.bin"
        ---help---
          Path to the firmware file.
 
 config BCMDHD_NVRAM_PATH
        depends on BROADCOM_WIFI
        string "NVRAM path"
-       default "/system/etc/wifi/bcmdhd.cal"
+       default "/etc/wifi/nvram_net.txt"
        ---help---
-         Path to the calibration file.
+         Path to the nvram file.
 
 config BROADCOM_WIFI_RESERVED_MEM
        bool "BROADCOM Reserved memory for wifi device"
@@ -125,7 +132,7 @@ config BROADCOM_WIFI_RESERVED_MEM
 
 config WIFI_BROADCOM_COB
         bool "BROADCOM WIFI COB"
-        depends on (BCM43455 || BCM4343 || BCM43454 || BCM43012)
+        depends on (BCM43456 || BCM43455 || BCM4343 || BCM43454 || BCM43012)
         ---help---
           This is a configuration for Broadcom WIFI COB Type.
 
@@ -190,9 +197,22 @@ config BCMDHD_PREALLOC_MEMDUMP
        ---help---
          Preallocated memory support for dongle memory dump
 
+config WLAN_HERO
+       bool "model code for hero"
+       depends on BROADCOM_WIFI
+       ---help---
+         This is configuration for USA regrev
+
+config WLAN_HERO2
+       bool "model code for hero2"
+       depends on BROADCOM_WIFI
+       ---help---
+         This is configuration for USA regrev
+
 config BCMDHD_OOB_HOST_WAKE
        bool "Use the external WLAN_HOST_WAKE pin"
        depends on BROADCOM_WIFI
+       default y
        ---help---
          Use the external GPIO pin to wake up host
 
@@ -201,3 +221,36 @@ config SPLIT_ARGOS_SET
        depends on BROADCOM_WIFI
        ---help---
        To support SPLIT_ARGOS_SET
+
+config WLAN_GRACE
+       bool "Model code for GRACE"
+       depends on BROADCOM_WIFI
+       ---help---
+       This is configuration for Grace feature
+
+config WLAN_GREAT
+       bool "model code for GREAT"
+       depends on BROADCOM_WIFI
+       ---help---
+       This is configuration for Great feature
+
+config BCM_DETECT_CONSECUTIVE_HANG
+       bool "Detect consecutive hang event"
+       depends on BROADCOM_WIFI
+       default n
+       ---help---
+       Detecting defect module from consecutive hang event
+
+config WLAN_VHTDISABLE
+       bool "WLAN Disable 11ac"
+       depends on BCM43456
+       default n
+       ---help---
+       This is a configuration to disable 11ac.
+
+config WLAN_5GDISABLE
+       bool "Enable to block Band A(5G)"
+       depends on BROADCOM_WIFI
+       default n
+       ---help---
+       This is configuration for block band A
index f699aba0bfe4863254e31715c1f2700dcdd691f4..17a5e8246dae6859b96ce5d5c4a80ed45e20bc1f 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2018, Broadcom Corporation
 # 
 #      Unless you and Broadcom execute a separate written software license
 # agreement governing use of this software, this software is licensed to you
@@ -60,7 +60,7 @@ endif
        # SKB TAILPAD to avoid out of boundary memory access
        DHDCFLAGS += -DDHDENABLE_TAILPAD
        # Enable PROP_TXSTATUS
-       DHDCFLAGS += -DPROP_TXSTATUS
+       DHDCFLAGS += -DPROP_TXSTATUS -DLIMIT_BORROW
        DHDCFLAGS += -DSUPPORT_P2P_GO_PS
        # Debug for DPC Thread watchdog bark
        DHDCFLAGS += -DDEBUG_DPC_THREAD_WATCHDOG
@@ -89,6 +89,8 @@ endif
        DHDCFLAGS += -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL
        # Enable Link down recovery
        DHDCFLAGS += -DSUPPORT_LINKDOWN_RECOVERY
+       # Enable Dongle Isolation
+       DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
        # Enable Firmware Coredump
        DHDCFLAGS += -DDHD_FW_COREDUMP
         # Enable PKTID AUDIT
@@ -97,11 +99,11 @@ endif
        # DHD_LB_RXP - Perform RX Packet processing in parallel
        # DHD_LB_STATS - To display the Load Blancing statistics
        DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_TXP -DDHD_LB_STATS
-       # Enable wakelock for legacy scan
-       DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
        # Extended HANG event with reason codes
        DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON
        DHDCFLAGS += -DDHD_RECOVER_TIMEOUT
+       # HEAP ASLR
+       DHDCFLAGS += -DBCM_ASLR_HEAP
 
 ifneq ($(CONFIG_SOC_EXYNOS8895),)
        # Default Tx LB Enable
@@ -129,6 +131,8 @@ endif
 # Debug
 DHDCFLAGS += -DSIMPLE_MAC_PRINT
 DHDCFLAGS += -DDEBUGFS_CFG80211
+# Enable wakelock for legacy scan
+DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
 # Enable wakelock debug function
 DHDCFLAGS += -DDHD_TRACE_WAKE_LOCK
 # Print out kernel panic point of file and line info when assertion happened
@@ -162,7 +166,7 @@ DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-80
 DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-85
 
 # Roaming
-DHDCFLAGS += -DROAM_AP_ENV_DETECTION
+DHDCFLAGS += -DROAM_AP_ENV_DETECTION -DKEEP_CUSTOM_ROAM_TRIGGER
 DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API
 DHDCFLAGS += -DENABLE_FW_ROAM_SUSPEND
 DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
@@ -194,7 +198,7 @@ DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
 DHDCFLAGS += -DDHD_USE_ATOMIC_PKTGET
 DHDCFLAGS += -DTDLS_MSG_ONLY_WFD
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=30000
-DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=20
+DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=30
 DHDCFLAGS += -DENABLE_TDLS_AUTO_MODE
 DHDCFLAGS += -DP2P_SKIP_DFS
 DHDCFLAGS += -DKEEP_WIFION_OPTION
@@ -203,6 +207,7 @@ DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
 DHDCFLAGS += -DSKIP_WLFC_ON_CONCURRENT
 DHDCFLAGS += -DP2P_LISTEN_OFFLOADING
 DHDCFLAGS += -DUNSET_FW_ROAM_WIPHY_FLAG
+DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 
 # For special PNO Event keep wake lock for 10sec
 DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -253,7 +258,8 @@ DHDCFLAGS += -DCONFIG_HAS_WAKELOCK
 # Used short dwell time during initial scan
 DHDCFLAGS += -DUSE_INITIAL_SHORT_DWELL_TIME
 
-# Japan ccode revision will be fixed by nvram's value
+# Korea and Japan ccode revision will be fixed by nvram's value
+DHDCFLAGS += -DKEEP_KR_REGREV
 DHDCFLAGS += -DKEEP_JP_REGREV
 
 # NAN feature
@@ -282,6 +288,41 @@ DHDCFLAGS += -DSUPPORT_TRIGGER_HANG_EVENT
 # Enable Checking Blob existence
 DHDCFLAGS += -DDHD_BLOB_EXISTENCE_CHECK
 
+# Random mac scan
+DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+# WLC_E_SET_SSID fail
+DHDCFLAGS += -DSET_SSID_FAIL_CUSTOM_RC=100
+
+# Enable to block Band A(5G), Only support Band B(2G)
+ifeq ($(CONFIG_WLAN_5GDISABLE),y)
+DHDCFLAGS += -DDHD_2G_ONLY_SUPPORT
+endif
+# Disable VHT(5G HT80) mode
+ifeq ($(CONFIG_WLAN_VHTDISABLE),y)
+DHDCFLAGS += -DDHD_DISABLE_VHTMODE
+endif
+
+# Android Version Check from Platform source
+ifneq ($(PLATFORM_VERSION),)
+MAJOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -d "." -f 1)
+DHDCFLAGS += -DANDROID_PLATFORM_VERSION=$(MAJOR_VERSION)
+endif
+
+ifneq ($(PLATFORM_VERSION),)
+# Android O-OS (version 8) support
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+DHDCFLAGS += -DCUSTOM_ASSOC_TIMEOUT=20
+endif
+endif
+
+# Use Legacy dump path
+ifneq ($(USE_LEGACY_DUMP_PATH),)
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/media/wifi/log/\""
+else
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/log/wifi/\""
+endif
+
 ##############################
 # Android Platform Definition
 ##############################
@@ -356,7 +397,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
  DHDCFLAGS += -DDHD_SSSR_DUMP
- DHDCFLAGS += -DDISABLE_SETBAND
 # tput enhancement for common
  DHDCFLAGS += -DUSE_WL_TXBF
  DHDCFLAGS += -DUSE_WL_FRAMEBURST
@@ -368,7 +408,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE
 # Customer ocl disabe
  DHDCFLAGS += -DCUSTOM_SET_OCLOFF
-
 # tput enhancement for PCIE
 ifeq ($(BUS_IFACE_PCIE),y)
   DHDCFLAGS += -DCUSTOM_TCPACK_SUPP_RATIO=15
@@ -389,13 +428,14 @@ endif
   DHDCFLAGS += -DWLFBT
   DHDCFLAGS += -DDHD_ENABLE_LPC
   DHDCFLAGS += -DWLAIBSS -DWLAIBSS_PS
-  DHDCFLAGS += -DWLADPS
-  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS
+#  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS_SEAK_AP_WAR
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
   DHDCFLAGS += -DWL_RELMCAST
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT -DSUPPORT_5G_1024QAM_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
 # disable pruned scan
@@ -412,11 +452,10 @@ endif
 # LOGTRACE_EVENT
   DHDCFLAGS += -DSHOW_LOGTRACE
   DHDCFLAGS += -DLOGTRACE_FROM_FILE
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
 ifeq ($(CONFIG_ARCH_MSM8998),y)
 # Use SMMU for IOMEM
   DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
 endif
 # Expand TCP tx queue to 10 times of default size
   DHDCFLAGS += -DTSQ_MULTIPLIER=10
@@ -425,20 +464,70 @@ endif
 ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895) $(CONFIG_ARCH_TEGRA)),y)
 # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
-# Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
 # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
 # Enable LQCM
   DHDCFLAGS += -DSUPPORT_LQCM
 endif
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895)), y)
+# DHD_LB_IRQSET - CPU migration by IRQ Affinity Set
+  DHDCFLAGS += -DDHD_LB_IRQSET
+endif
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+
+ifneq ($(PLATFORM_VERSION),)
+# DREAM Android N OS should not use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \< 8.0),1)
+ifneq ($(filter y,$(CONFIG_WLAN_GREAT) $(CONFIG_SEC_GREATQLTE_PROJECT)),y)
+ DREAM_NOS_DISCARD_FEATURES := y
+endif
+endif
+
+# Feature Set used for GREAT N OS and Android O OS
+ifneq ($(DREAM_NOS_DISCARD_FEATURES),y)
+# Debugaility
+  DHDCFLAGS += -DDEBUGABILITY
+  DHDCFLAGS += -DDHD_PKT_LOGGING
+# Debug Wakeup pkt reason
+  DHDCFLAGS += -DDHD_WAKE_STATUS -DDHD_WAKE_RX_STATUS -DDHD_WAKE_EVENT_STATUS
+  DHDCFLAGS += -DDHD_WAKEPKT_DUMP
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+# LAST ROAM EVENT LOG
+  DHDCFLAGS += -DWL_LASTEVT
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+#STAT REPORT
+#stat report shall be defined only if LINK STAT is defined
+  DHDCFLAGS += -DSTAT_REPORT
+#define temp static only when SDK doesn't support static memory for STAT REPORT
+#  DHDCFLAGS += -DSTAT_REPORT_TEMP_STATIC
+# Enable DHD_DUMP_MNGR
+  DHDCFLAGS += -DDHD_DUMP_MNGR
+endif
+
+# RSSI_SUM_REPORT is used over Android O OS only
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# RSSI Logging
+  DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
+# Enable NDO_CONFIG_SUPPORT in HAL
+  DHDCFLAGS += -DNDO_CONFIG_SUPPORT
+endif
+endif
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4361),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -447,7 +536,7 @@ ifneq ($(CONFIG_BCM4359),)
   DHDCFLAGS += -DMIMO_ANT_SETTING
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=4
+  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
   DHDCFLAGS += -DSOFTAP_UAPSD_OFF
 # tput enhancement for common
   DHDCFLAGS += -DUSE_WL_TXBF
@@ -484,9 +573,13 @@ endif
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
+  DHDCFLAGS += -DWL11ULB
  #DHDCFLAGS += -DSUPPORT_SENSORHUB
  # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
+ # virtual interface support for BCM4359 only
+  DHDCFLAGS += -DDHD_USE_CHECK_DONGLE_IDLE
+  DHDCFLAGS += -DDHD_ABORT_SCAN_CREATE_INTERFACE
  # disable pruned scan
   DHDCFLAGS += -DDISABLE_PRUNED_SCAN
  # Remove common feature for BCM4359
@@ -498,26 +591,68 @@ endif
  # Use restricted channels on STA/SoftAP concurrent mode
   DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
   DHDCFLAGS += -DDHD_LOG_DUMP
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
-ifneq ($(CONFIG_WLAN_GRACE),)
-  DHDCFLAGS += -DWBTEXT
-endif
-ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_SOC_EXYNOS8890)),y)
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+  DHDCFLAGS += -DSUPPORT_CUSTOM_SET_CAC
+# To support Enable EVENT SDB Transition log.
+  DHDCFLAGS += -DSUPPORT_EVT_SDB_LOG
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_ARCH_TEGRA)),y)
  # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
- # Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
+ # IRQ affinity setting for RX Load Balance
+ # DHDCFLAGS += -DDHD_LB_IRQSET
  # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
+ # CLM
+  DHDCFLAGS += -DDHD_SUPPORT_GB_999
+ # Configure MU-MIMO capability
+ifeq ($(CONFIG_SOC_EXYNOS8890),y)
+  DHDCFLAGS += -DDYNAMIC_MUMIMO_CONTROL
+endif
+ifeq ($(CONFIG_ARCH_MSM8998),y)
+# Use SMMU for IOMEM
+  DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
+endif
 endif
 
+ifeq ($(filter y,$(CONFIG_WLAN_HERO) $(CONFIG_SEC_HEROQLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_949
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO2) $(CONFIG_SEC_HERO2QLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_945
+endif
+# HANG simulation
+  DHDCFLAGS += -DDHD_HANG_SEND_UP_TEST
+
+ifeq ($(filter y,$(CONFIG_WLAN_GRACE) $(CONFIG_SEC_GRACEQLTE_PROJECT)),y)
+  # WBTEXT (11kv) feature
+  DHDCFLAGS += -DWBTEXT
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+endif
+
+ # RSDB mode from file config
+  DHDCFLAGS += -DRSDB_MODE_FROM_FILE
+ # LOGTRACE_EVENT
+  DHDCFLAGS += -DSHOW_LOGTRACE
+  DHDCFLAGS += -DLOGTRACE_FROM_FILE
+
+# Enable concate blob path
+    DHDCFLAGS += -DCONCATE_BLOB
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
+
 ifeq ($(CONFIG_BCM4359),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -590,9 +725,6 @@ ifeq ($(CONFIG_BCM4358),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 ifneq ($(CONFIG_BCM4354),)
@@ -609,6 +741,7 @@ ifneq ($(CONFIG_BCM4354),)
 # tput enhancement for SDIO
 ifeq ($(BUS_IFACE_SDIO),y)
   DHDCFLAGS += -DHW_OOB
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
   DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
   DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
@@ -651,9 +784,6 @@ ifeq ($(CONFIG_BCM4354),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 # Chipsets supported SDIO only
@@ -671,6 +801,7 @@ ifneq ($(CONFIG_BCM4339),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -700,11 +831,22 @@ ifeq ($(CONFIG_BCM4339),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
 endif
 
+ifneq ($(CONFIG_BCM43456),)
+  DHDCFLAGS += -DBCM43456_CHIP
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
+endif
 ifneq ($(CONFIG_BCM43455),)
-  DHDCFLAGS += -DBCM43455_CHIP -DHW_OOB
+  DHDCFLAGS += -DBCM43455_CHIP
+endif
+ifneq ($(CONFIG_BCM43454),)
+  DHDCFLAGS += -DBCM43454_CHIP
+endif
+
+# BCM43454/43455/43456 common difine.
+ifneq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)))
+  DHDCFLAGS += -DHW_OOB
   DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
@@ -717,6 +859,7 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -735,12 +878,11 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
   DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43455),y)
+ifeq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
   DHDCFLAGS += -DDHD_LOG_DUMP
 
   # FCC power limit control on ch12/13.
@@ -752,64 +894,38 @@ endif
   DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
   DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
+
+ifneq ($(filter y,$(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43455) $(CONFIG_BCM43456)))
 # Enable Firmware Coredump
-  DHDCFLAGS += -DDHD_FW_COREDUMP
+    DHDCFLAGS += -DDHD_FW_COREDUMP
 ifeq ($(CONFIG_BCMDHD_PREALLOC_MEMDUMP),y)
-  DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+    DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
 endif
 
 # Enable concate blob path
-  DHDCFLAGS += -DCONCATE_BLOB
-endif
-
-ifneq ($(CONFIG_BCM43454),)
-  DHDCFLAGS += -DBCM43454_CHIP -DHW_OOB
-  DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
-  DHDCFLAGS += -DUSE_CID_CHECK
-  DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DUSE_SDIOFIFO_IOVAR
-
-  # tput enhancement
-  DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
-  DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
-  DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
-  DHDCFLAGS += -DDHDTCPACK_SUPPRESS
-  DHDCFLAGS += -DUSE_WL_TXBF
-  DHDCFLAGS += -DUSE_WL_FRAMEBURST
-  DHDCFLAGS += -DRXFRAME_THREAD
-  DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
-  DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
-  DHDCFLAGS += -DPROP_TXSTATUS_VSDB
+    DHDCFLAGS += -DCONCATE_BLOB
+# Generate .softap.info
+    DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
 
-  # New Features
-  DHDCFLAGS += -DWL11U -DMFP
-  DHDCFLAGS += -DBCMCCX
-  DHDCFLAGS += -DWES_SUPPORT
-  DHDCFLAGS += -DOKC_SUPPORT
-  DHDCFLAGS += -DWLTDLS -DWLTDLS_AUTO_ENABLE
-  DHDCFLAGS += -DWLFBT
-  DHDCFLAGS += -DDHD_ENABLE_LPC
-  DHDCFLAGS += -DWLAIBSS
-  DHDCFLAGS += -DSUPPORT_LTECX
-  DHDCFLAGS += -DSUPPORT_2G_VHT
-  DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43454),y)
-  DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
-  DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
-  DRIVER_TYPE = y
+ifneq ($(CONFIG_BCM43456),)
+# STA/SoftAP Concurrent Mode Support for legacy chip
+  DHDCFLAGS += -DWL_VIRTUAL_APSTA
+  DHDCFLAGS += -DWL_RESTRICTED_APSTA_SCC
+  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
+  DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
+# Use restricted channels on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
+# Block ARP during DHCP on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_BLOCK_ARP_DURING_DHCP
+endif
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-  DHDCFLAGS += -DDHD_LOG_DUMP
-
-  # FCC power limit control on ch12/13.
-  #   DHDCFLAGS += -DFCC_PWR_LIMIT_2G
-  #
-  # Enable Roam time thresh
-  DHDCFLAGS += -DENABLE_MAX_DTIM_IN_SUSPEND
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT_IN_SUSPEND=10
-  DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
-  DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 endif
 
 ifneq ($(CONFIG_BCM4335),)
@@ -826,6 +942,7 @@ ifneq ($(CONFIG_BCM4335),)
 # DHDCFLAGS += -DDHD_SET_FW_HIGHSPEED
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DREPEAT_READFRAME
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64
@@ -943,6 +1060,15 @@ endif
   # Remove common feature for BCM4343
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DSUPPORT_P2P_GO_PS,$(DHDCFLAGS))
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
 endif
 
 ifneq ($(CONFIG_BCM43012),)
@@ -978,6 +1104,8 @@ ifeq ($(CONFIG_SOLIS),y)
   DHDCFLAGS += -DPLATFORM_SLP
   DHDCFLAGS += -UCONFIG_HAS_WAKELOCK
   DHDCFLAGS += -UDHD_TRACE_WAKE_LOCK
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+  DHDCFLAGS += -DDISCARD_UDPNETBIOS
 endif
   # Remove common feature for 43012
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
@@ -998,6 +1126,7 @@ endif
   DHDCFLAGS :=$(filter-out -DSUPPORT_AMPDU_MPDU_CMD,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DVSDB,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DPROP_TXSTATUS,$(DHDCFLAGS))
+  DHDCFLAGS :=$(filter-out -DLIMIT_BORROW,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDHD_USE_IDLECOUNT,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
@@ -1087,6 +1216,7 @@ endif
 ifneq ($(CONFIG_MACH_EXSOM7420),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
+DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 obj-$(CONFIG_MACH_EXSOM7420) += dhd_custom_exynos.o dhd_custom_memprealloc.o
 endif
 ifneq ($(CONFIG_SOC_EXYNOS8890),)
@@ -1097,10 +1227,10 @@ DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5430),)
-obj-$(CONFIG_MACH_UNIVERSAL5430) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5422),)
-obj-$(CONFIG_MACH_UNIVERSAL5422) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_ARCH_MSM8994),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
@@ -1123,6 +1253,10 @@ ifneq ($(CONFIG_SOC_EXYNOS7870),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -Wno-date-time
 endif
+ifneq ($(CONFIG_SOC_EXYNOS7885),)
+DHDCFLAGS += -DDHD_OF_SUPPORT
+DHDCFLAGS += -Wno-date-time
+endif
 ifneq ($(CONFIG_SOC_EXYNOS7570),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
@@ -1146,6 +1280,7 @@ DHDCFLAGS := $(filter-out -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL,$(DHDCFLAGS)
 DHDCFLAGS := $(filter-out -DWL_VENDOR_EXT_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DGSCAN_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DRTT_SUPPORT,$(DHDCFLAGS))
+DHDCFLAGS := $(filter-out -DDHD_LB_IRQSET,$(DHDCFLAGS))
 DHD_ANDROID_OFILES := $(filter-out wl_cfgvendor.o,$(DHD_ANDROID_OFILES))
 DHD_ANDROID_OFILES := $(filter-out dhd_rtt.o,$(DHD_ANDROID_OFILES))
 endif
@@ -1173,8 +1308,8 @@ DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o dhd_custom_sec.o
        bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \
        wl_android.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o \
        wl_linux_mon.o wl_roam.o dhd_linux_platdev.o dhd_linux_wq.o wl_cfg_btcoex.o \
-       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o
-
+       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o \
+       dhd_pktlog.o
 
 ifeq ($(BUS_IFACE_SDIO),y)
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o
@@ -1203,6 +1338,10 @@ ifeq ($(CONFIG_WL_NAN),y)
 # DHDOFILES += wl_cfgnan.o bcmxtlv.o
 endif
 
+ifneq ($(filter -DSTAT_REPORT,$(DHDCFLAGS)),)
+DHDOFILES += wl_statreport.o
+endif
+
 dhd-y := $(DHDOFILES)
 obj-$(DRIVER_TYPE)   += dhd.o
 
index edbef7788b0b9e921e6af1bb2ba023b1c8a30e84..453a609efc0f819912b5bf595b5794b1c95dec70 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2018, Broadcom Corporation
 # 
 #      Unless you and Broadcom execute a separate written software license
 # agreement governing use of this software, this software is licensed to you
@@ -60,7 +60,7 @@ endif
        # SKB TAILPAD to avoid out of boundary memory access
        DHDCFLAGS += -DDHDENABLE_TAILPAD
        # Enable PROP_TXSTATUS
-       DHDCFLAGS += -DPROP_TXSTATUS
+       DHDCFLAGS += -DPROP_TXSTATUS -DLIMIT_BORROW
        DHDCFLAGS += -DSUPPORT_P2P_GO_PS
        # Debug for DPC Thread watchdog bark
        DHDCFLAGS += -DDEBUG_DPC_THREAD_WATCHDOG
@@ -89,6 +89,8 @@ endif
        DHDCFLAGS += -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL
        # Enable Link down recovery
        DHDCFLAGS += -DSUPPORT_LINKDOWN_RECOVERY
+       # Enable Dongle Isolation
+       DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
        # Enable Firmware Coredump
        DHDCFLAGS += -DDHD_FW_COREDUMP
         # Enable PKTID AUDIT
@@ -97,11 +99,11 @@ endif
        # DHD_LB_RXP - Perform RX Packet processing in parallel
        # DHD_LB_STATS - To display the Load Blancing statistics
        DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_TXP -DDHD_LB_STATS
-       # Enable wakelock for legacy scan
-       DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
        # Extended HANG event with reason codes
        DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON
        DHDCFLAGS += -DDHD_RECOVER_TIMEOUT
+       # HEAP ASLR
+       DHDCFLAGS += -DBCM_ASLR_HEAP
 
 ifneq ($(CONFIG_SOC_EXYNOS8895),)
        # Default Tx LB Enable
@@ -129,6 +131,8 @@ endif
 # Debug
 DHDCFLAGS += -DSIMPLE_MAC_PRINT
 DHDCFLAGS += -DDEBUGFS_CFG80211
+# Enable wakelock for legacy scan
+DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
 # Enable wakelock debug function
 DHDCFLAGS += -DDHD_TRACE_WAKE_LOCK
 # Print out kernel panic point of file and line info when assertion happened
@@ -162,7 +166,7 @@ DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-80
 DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-85
 
 # Roaming
-DHDCFLAGS += -DROAM_AP_ENV_DETECTION
+DHDCFLAGS += -DROAM_AP_ENV_DETECTION -DKEEP_CUSTOM_ROAM_TRIGGER
 DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API
 DHDCFLAGS += -DENABLE_FW_ROAM_SUSPEND
 DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
@@ -194,7 +198,7 @@ DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
 DHDCFLAGS += -DDHD_USE_ATOMIC_PKTGET
 DHDCFLAGS += -DTDLS_MSG_ONLY_WFD
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=30000
-DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=20
+DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=30
 DHDCFLAGS += -DENABLE_TDLS_AUTO_MODE
 DHDCFLAGS += -DP2P_SKIP_DFS
 DHDCFLAGS += -DKEEP_WIFION_OPTION
@@ -203,6 +207,7 @@ DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
 DHDCFLAGS += -DSKIP_WLFC_ON_CONCURRENT
 DHDCFLAGS += -DP2P_LISTEN_OFFLOADING
 DHDCFLAGS += -DUNSET_FW_ROAM_WIPHY_FLAG
+DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 
 # For special PNO Event keep wake lock for 10sec
 DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -253,7 +258,8 @@ DHDCFLAGS += -DCONFIG_HAS_WAKELOCK
 # Used short dwell time during initial scan
 DHDCFLAGS += -DUSE_INITIAL_SHORT_DWELL_TIME
 
-# Japan ccode revision will be fixed by nvram's value
+# Korea and Japan ccode revision will be fixed by nvram's value
+DHDCFLAGS += -DKEEP_KR_REGREV
 DHDCFLAGS += -DKEEP_JP_REGREV
 
 # NAN feature
@@ -282,21 +288,39 @@ DHDCFLAGS += -DSUPPORT_TRIGGER_HANG_EVENT
 # Enable Checking Blob existence
 DHDCFLAGS += -DDHD_BLOB_EXISTENCE_CHECK
 
+# Random mac scan
+DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+# WLC_E_SET_SSID fail
+DHDCFLAGS += -DSET_SSID_FAIL_CUSTOM_RC=100
+
+# Enable to block Band A(5G), Only support Band B(2G)
+ifeq ($(CONFIG_WLAN_5GDISABLE),y)
+DHDCFLAGS += -DDHD_2G_ONLY_SUPPORT
+endif
+# Disable VHT(5G HT80) mode
+ifeq ($(CONFIG_WLAN_VHTDISABLE),y)
+DHDCFLAGS += -DDHD_DISABLE_VHTMODE
+endif
+
 # Android Version Check from Platform source
-CANDIDATE_VERSION_PATH := ./../../build/core ../../../../../../build/core out
-FOUND_VERSION_PATH := $(foreach dir,$(CANDIDATE_VERSION_PATH), $(wildcard $(dir)/version_defaults.mk))
-FOUND_VERSION_PATH := $(word 1, $(FOUND_VERSION_PATH))
-ifeq ($(FOUND_VERSION_PATH),)
-$(warning Not found Android version file. Set None)
-else
-# Extract version string and get major number
-ANDROID_PLATFORM_VERSION := $(shell grep "PLATFORM_VERSION := " $(FOUND_VERSION_PATH) | cut -d "=" -f 2 | cut -d "." -f 1 | sed 's/ //g')
-$(warning Android Platform Version : $(ANDROID_PLATFORM_VERSION))
-# If Android version lower than 7(Nougat) => Use Legacy File path
-ifeq ($(shell expr $(ANDROID_PLATFORM_VERSION) \< 7),1)
-DHDCFLAGS += -DDHD_LEGACY_FILE_PATH
-$(warning Will be use Legacy file path)
+ifneq ($(PLATFORM_VERSION),)
+MAJOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -d "." -f 1)
+DHDCFLAGS += -DANDROID_PLATFORM_VERSION=$(MAJOR_VERSION)
 endif
+
+ifneq ($(PLATFORM_VERSION),)
+# Android O-OS (version 8) support
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+DHDCFLAGS += -DCUSTOM_ASSOC_TIMEOUT=20
+endif
+endif
+
+# Use Legacy dump path
+ifneq ($(USE_LEGACY_DUMP_PATH),)
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/media/wifi/log/\""
+else
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/log/wifi/\""
 endif
 
 ##############################
@@ -333,7 +357,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
  DHDCFLAGS += -DDHD_SSSR_DUMP
- DHDCFLAGS += -DDISABLE_SETBAND
 # tput enhancement for common
  DHDCFLAGS += -DUSE_WL_TXBF
  DHDCFLAGS += -DUSE_WL_FRAMEBURST
@@ -345,7 +368,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE
 # Customer ocl disabe
  DHDCFLAGS += -DCUSTOM_SET_OCLOFF
-
 # tput enhancement for PCIE
 ifeq ($(BUS_IFACE_PCIE),y)
   DHDCFLAGS += -DCUSTOM_TCPACK_SUPP_RATIO=15
@@ -366,13 +388,14 @@ endif
   DHDCFLAGS += -DWLFBT
   DHDCFLAGS += -DDHD_ENABLE_LPC
   DHDCFLAGS += -DWLAIBSS -DWLAIBSS_PS
-  DHDCFLAGS += -DWLADPS
-  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS
+#  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS_SEAK_AP_WAR
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
   DHDCFLAGS += -DWL_RELMCAST
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT -DSUPPORT_5G_1024QAM_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
 # disable pruned scan
@@ -389,11 +412,10 @@ endif
 # LOGTRACE_EVENT
   DHDCFLAGS += -DSHOW_LOGTRACE
   DHDCFLAGS += -DLOGTRACE_FROM_FILE
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
 ifeq ($(CONFIG_ARCH_MSM8998),y)
 # Use SMMU for IOMEM
   DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
 endif
 # Expand TCP tx queue to 10 times of default size
   DHDCFLAGS += -DTSQ_MULTIPLIER=10
@@ -402,20 +424,70 @@ endif
 ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895) $(CONFIG_ARCH_TEGRA)),y)
 # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
-# Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
 # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
 # Enable LQCM
   DHDCFLAGS += -DSUPPORT_LQCM
 endif
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895)), y)
+# DHD_LB_IRQSET - CPU migration by IRQ Affinity Set
+  DHDCFLAGS += -DDHD_LB_IRQSET
+endif
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+
+ifneq ($(PLATFORM_VERSION),)
+# DREAM Android N OS should not use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \< 8.0),1)
+ifneq ($(filter y,$(CONFIG_WLAN_GREAT) $(CONFIG_SEC_GREATQLTE_PROJECT)),y)
+ DREAM_NOS_DISCARD_FEATURES := y
+endif
+endif
+
+# Feature Set used for GREAT N OS and Android O OS
+ifneq ($(DREAM_NOS_DISCARD_FEATURES),y)
+# Debugaility
+  DHDCFLAGS += -DDEBUGABILITY
+  DHDCFLAGS += -DDHD_PKT_LOGGING
+# Debug Wakeup pkt reason
+  DHDCFLAGS += -DDHD_WAKE_STATUS -DDHD_WAKE_RX_STATUS -DDHD_WAKE_EVENT_STATUS
+  DHDCFLAGS += -DDHD_WAKEPKT_DUMP
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+# LAST ROAM EVENT LOG
+  DHDCFLAGS += -DWL_LASTEVT
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+#STAT REPORT
+#stat report shall be defined only if LINK STAT is defined
+  DHDCFLAGS += -DSTAT_REPORT
+#define temp static only when SDK doesn't support static memory for STAT REPORT
+#  DHDCFLAGS += -DSTAT_REPORT_TEMP_STATIC
+# Enable DHD_DUMP_MNGR
+  DHDCFLAGS += -DDHD_DUMP_MNGR
+endif
+
+# RSSI_SUM_REPORT is used over Android O OS only
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# RSSI Logging
+  DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
+# Enable NDO_CONFIG_SUPPORT in HAL
+  DHDCFLAGS += -DNDO_CONFIG_SUPPORT
+endif
+endif
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4361),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -424,7 +496,7 @@ ifneq ($(CONFIG_BCM4359),)
   DHDCFLAGS += -DMIMO_ANT_SETTING
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=4
+  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
   DHDCFLAGS += -DSOFTAP_UAPSD_OFF
 # tput enhancement for common
   DHDCFLAGS += -DUSE_WL_TXBF
@@ -461,9 +533,13 @@ endif
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
+  DHDCFLAGS += -DWL11ULB
  #DHDCFLAGS += -DSUPPORT_SENSORHUB
  # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
+ # virtual interface support for BCM4359 only
+  DHDCFLAGS += -DDHD_USE_CHECK_DONGLE_IDLE
+  DHDCFLAGS += -DDHD_ABORT_SCAN_CREATE_INTERFACE
  # disable pruned scan
   DHDCFLAGS += -DDISABLE_PRUNED_SCAN
  # Remove common feature for BCM4359
@@ -475,26 +551,68 @@ endif
  # Use restricted channels on STA/SoftAP concurrent mode
   DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
   DHDCFLAGS += -DDHD_LOG_DUMP
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
-ifneq ($(CONFIG_WLAN_GRACE),)
-  DHDCFLAGS += -DWBTEXT
-endif
-ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_SOC_EXYNOS8890)),y)
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+  DHDCFLAGS += -DSUPPORT_CUSTOM_SET_CAC
+# To support Enable EVENT SDB Transition log.
+  DHDCFLAGS += -DSUPPORT_EVT_SDB_LOG
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_ARCH_TEGRA)),y)
  # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
- # Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
+ # IRQ affinity setting for RX Load Balance
+ # DHDCFLAGS += -DDHD_LB_IRQSET
  # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
+ # CLM
+  DHDCFLAGS += -DDHD_SUPPORT_GB_999
+ # Configure MU-MIMO capability
+ifeq ($(CONFIG_SOC_EXYNOS8890),y)
+  DHDCFLAGS += -DDYNAMIC_MUMIMO_CONTROL
+endif
+ifeq ($(CONFIG_ARCH_MSM8998),y)
+# Use SMMU for IOMEM
+  DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
+endif
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO) $(CONFIG_SEC_HEROQLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_949
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO2) $(CONFIG_SEC_HERO2QLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_945
 endif
+# HANG simulation
+  DHDCFLAGS += -DDHD_HANG_SEND_UP_TEST
+
+ifeq ($(filter y,$(CONFIG_WLAN_GRACE) $(CONFIG_SEC_GRACEQLTE_PROJECT)),y)
+  # WBTEXT (11kv) feature
+  DHDCFLAGS += -DWBTEXT
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+endif
+
+ # RSDB mode from file config
+  DHDCFLAGS += -DRSDB_MODE_FROM_FILE
+ # LOGTRACE_EVENT
+  DHDCFLAGS += -DSHOW_LOGTRACE
+  DHDCFLAGS += -DLOGTRACE_FROM_FILE
+
+# Enable concate blob path
+    DHDCFLAGS += -DCONCATE_BLOB
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4359),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -567,9 +685,6 @@ ifeq ($(CONFIG_BCM4358),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 ifneq ($(CONFIG_BCM4354),)
@@ -586,6 +701,7 @@ ifneq ($(CONFIG_BCM4354),)
 # tput enhancement for SDIO
 ifeq ($(BUS_IFACE_SDIO),y)
   DHDCFLAGS += -DHW_OOB
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
   DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
   DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
@@ -628,9 +744,6 @@ ifeq ($(CONFIG_BCM4354),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 # Chipsets supported SDIO only
@@ -648,6 +761,7 @@ ifneq ($(CONFIG_BCM4339),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -677,11 +791,22 @@ ifeq ($(CONFIG_BCM4339),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
 endif
 
+ifneq ($(CONFIG_BCM43456),)
+  DHDCFLAGS += -DBCM43456_CHIP
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
+endif
 ifneq ($(CONFIG_BCM43455),)
-  DHDCFLAGS += -DBCM43455_CHIP -DHW_OOB
+  DHDCFLAGS += -DBCM43455_CHIP
+endif
+ifneq ($(CONFIG_BCM43454),)
+  DHDCFLAGS += -DBCM43454_CHIP
+endif
+
+# BCM43454/43455/43456 common difine.
+ifneq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)))
+  DHDCFLAGS += -DHW_OOB
   DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
@@ -694,6 +819,7 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -712,12 +838,11 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
   DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43455),y)
+ifeq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
   DHDCFLAGS += -DDHD_LOG_DUMP
 
   # FCC power limit control on ch12/13.
@@ -729,64 +854,38 @@ endif
   DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
   DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
+
+ifneq ($(filter y,$(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43455) $(CONFIG_BCM43456)))
 # Enable Firmware Coredump
-  DHDCFLAGS += -DDHD_FW_COREDUMP
+    DHDCFLAGS += -DDHD_FW_COREDUMP
 ifeq ($(CONFIG_BCMDHD_PREALLOC_MEMDUMP),y)
-  DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+    DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
 endif
 
 # Enable concate blob path
-  DHDCFLAGS += -DCONCATE_BLOB
-endif
-
-ifneq ($(CONFIG_BCM43454),)
-  DHDCFLAGS += -DBCM43454_CHIP -DHW_OOB
-  DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
-  DHDCFLAGS += -DUSE_CID_CHECK
-  DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DUSE_SDIOFIFO_IOVAR
+    DHDCFLAGS += -DCONCATE_BLOB
+# Generate .softap.info
+    DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
 
-  # tput enhancement
-  DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
-  DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
-  DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
-  DHDCFLAGS += -DDHDTCPACK_SUPPRESS
-  DHDCFLAGS += -DUSE_WL_TXBF
-  DHDCFLAGS += -DUSE_WL_FRAMEBURST
-  DHDCFLAGS += -DRXFRAME_THREAD
-  DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
-  DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
-  DHDCFLAGS += -DPROP_TXSTATUS_VSDB
-
-  # New Features
-  DHDCFLAGS += -DWL11U -DMFP
-  DHDCFLAGS += -DBCMCCX
-  DHDCFLAGS += -DWES_SUPPORT
-  DHDCFLAGS += -DOKC_SUPPORT
-  DHDCFLAGS += -DWLTDLS -DWLTDLS_AUTO_ENABLE
-  DHDCFLAGS += -DWLFBT
-  DHDCFLAGS += -DDHD_ENABLE_LPC
-  DHDCFLAGS += -DWLAIBSS
-  DHDCFLAGS += -DSUPPORT_LTECX
-  DHDCFLAGS += -DSUPPORT_2G_VHT
-  DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43454),y)
-  DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
-  DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
-  DRIVER_TYPE = y
+ifneq ($(CONFIG_BCM43456),)
+# STA/SoftAP Concurrent Mode Support for legacy chip
+  DHDCFLAGS += -DWL_VIRTUAL_APSTA
+  DHDCFLAGS += -DWL_RESTRICTED_APSTA_SCC
+  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
+  DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
+# Use restricted channels on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
+# Block ARP during DHCP on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_BLOCK_ARP_DURING_DHCP
+endif
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-  DHDCFLAGS += -DDHD_LOG_DUMP
-
-  # FCC power limit control on ch12/13.
-  #   DHDCFLAGS += -DFCC_PWR_LIMIT_2G
-  #
-  # Enable Roam time thresh
-  DHDCFLAGS += -DENABLE_MAX_DTIM_IN_SUSPEND
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT_IN_SUSPEND=10
-  DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
-  DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 endif
 
 ifneq ($(CONFIG_BCM4335),)
@@ -803,6 +902,7 @@ ifneq ($(CONFIG_BCM4335),)
 # DHDCFLAGS += -DDHD_SET_FW_HIGHSPEED
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DREPEAT_READFRAME
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64
@@ -920,6 +1020,15 @@ endif
   # Remove common feature for BCM4343
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DSUPPORT_P2P_GO_PS,$(DHDCFLAGS))
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
 endif
 
 ifneq ($(CONFIG_BCM43012),)
@@ -955,6 +1064,8 @@ ifeq ($(CONFIG_SOLIS),y)
   DHDCFLAGS += -DPLATFORM_SLP
   DHDCFLAGS += -UCONFIG_HAS_WAKELOCK
   DHDCFLAGS += -UDHD_TRACE_WAKE_LOCK
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+  DHDCFLAGS += -DDISCARD_UDPNETBIOS
 endif
   # Remove common feature for 43012
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
@@ -975,6 +1086,7 @@ endif
   DHDCFLAGS :=$(filter-out -DSUPPORT_AMPDU_MPDU_CMD,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DVSDB,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DPROP_TXSTATUS,$(DHDCFLAGS))
+  DHDCFLAGS :=$(filter-out -DLIMIT_BORROW,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDHD_USE_IDLECOUNT,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
@@ -1064,6 +1176,7 @@ endif
 ifneq ($(CONFIG_MACH_EXSOM7420),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
+DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 obj-$(CONFIG_MACH_EXSOM7420) += dhd_custom_exynos.o dhd_custom_memprealloc.o
 endif
 ifneq ($(CONFIG_SOC_EXYNOS8890),)
@@ -1074,10 +1187,10 @@ DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5430),)
-obj-$(CONFIG_MACH_UNIVERSAL5430) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5422),)
-obj-$(CONFIG_MACH_UNIVERSAL5422) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_ARCH_MSM8994),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
@@ -1100,6 +1213,10 @@ ifneq ($(CONFIG_SOC_EXYNOS7870),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -Wno-date-time
 endif
+ifneq ($(CONFIG_SOC_EXYNOS7885),)
+DHDCFLAGS += -DDHD_OF_SUPPORT
+DHDCFLAGS += -Wno-date-time
+endif
 ifneq ($(CONFIG_SOC_EXYNOS7570),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
@@ -1123,6 +1240,7 @@ DHDCFLAGS := $(filter-out -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL,$(DHDCFLAGS)
 DHDCFLAGS := $(filter-out -DWL_VENDOR_EXT_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DGSCAN_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DRTT_SUPPORT,$(DHDCFLAGS))
+DHDCFLAGS := $(filter-out -DDHD_LB_IRQSET,$(DHDCFLAGS))
 DHD_ANDROID_OFILES := $(filter-out wl_cfgvendor.o,$(DHD_ANDROID_OFILES))
 DHD_ANDROID_OFILES := $(filter-out dhd_rtt.o,$(DHD_ANDROID_OFILES))
 endif
@@ -1150,8 +1268,8 @@ DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o dhd_custom_sec.o
        bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \
        wl_android.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o \
        wl_linux_mon.o wl_roam.o dhd_linux_platdev.o dhd_linux_wq.o wl_cfg_btcoex.o \
-       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o
-
+       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o \
+       dhd_pktlog.o
 
 ifeq ($(BUS_IFACE_SDIO),y)
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o
@@ -1180,6 +1298,10 @@ ifeq ($(CONFIG_WL_NAN),y)
 # DHDOFILES += wl_cfgnan.o bcmxtlv.o
 endif
 
+ifneq ($(filter -DSTAT_REPORT,$(DHDCFLAGS)),)
+DHDOFILES += wl_statreport.o
+endif
+
 dhd-y := $(DHDOFILES)
 obj-$(DRIVER_TYPE)   += dhd.o
 
index 3a6716c4484bf653080b6b86d0d576a3d01f4737..cad83a8a85f8fb2c88743c8687330c8e8657a7a8 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2018, Broadcom Corporation
 # 
 #      Unless you and Broadcom execute a separate written software license
 # agreement governing use of this software, this software is licensed to you
@@ -60,7 +60,7 @@ endif
        # SKB TAILPAD to avoid out of boundary memory access
        DHDCFLAGS += -DDHDENABLE_TAILPAD
        # Enable PROP_TXSTATUS
-       DHDCFLAGS += -DPROP_TXSTATUS
+       DHDCFLAGS += -DPROP_TXSTATUS -DLIMIT_BORROW
        DHDCFLAGS += -DSUPPORT_P2P_GO_PS
        # Debug for DPC Thread watchdog bark
        DHDCFLAGS += -DDEBUG_DPC_THREAD_WATCHDOG
@@ -89,6 +89,8 @@ endif
        DHDCFLAGS += -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL
        # Enable Link down recovery
        DHDCFLAGS += -DSUPPORT_LINKDOWN_RECOVERY
+       # Enable Dongle Isolation
+       DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
        # Enable Firmware Coredump
        DHDCFLAGS += -DDHD_FW_COREDUMP
         # Enable PKTID AUDIT
@@ -97,11 +99,11 @@ endif
        # DHD_LB_RXP - Perform RX Packet processing in parallel
        # DHD_LB_STATS - To display the Load Blancing statistics
        DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_TXP -DDHD_LB_STATS
-       # Enable wakelock for legacy scan
-       DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
        # Extended HANG event with reason codes
        DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON
        DHDCFLAGS += -DDHD_RECOVER_TIMEOUT
+       # HEAP ASLR
+       DHDCFLAGS += -DBCM_ASLR_HEAP
 
 ifneq ($(CONFIG_SOC_EXYNOS8895),)
        # Default Tx LB Enable
@@ -129,6 +131,8 @@ endif
 # Debug
 DHDCFLAGS += -DSIMPLE_MAC_PRINT
 DHDCFLAGS += -DDEBUGFS_CFG80211
+# Enable wakelock for legacy scan
+DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
 # Enable wakelock debug function
 DHDCFLAGS += -DDHD_TRACE_WAKE_LOCK
 # Print out kernel panic point of file and line info when assertion happened
@@ -162,7 +166,7 @@ DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-80
 DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-85
 
 # Roaming
-DHDCFLAGS += -DROAM_AP_ENV_DETECTION
+DHDCFLAGS += -DROAM_AP_ENV_DETECTION -DKEEP_CUSTOM_ROAM_TRIGGER
 DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API
 DHDCFLAGS += -DENABLE_FW_ROAM_SUSPEND
 DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
@@ -194,7 +198,7 @@ DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
 DHDCFLAGS += -DDHD_USE_ATOMIC_PKTGET
 DHDCFLAGS += -DTDLS_MSG_ONLY_WFD
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=30000
-DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=20
+DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=30
 DHDCFLAGS += -DENABLE_TDLS_AUTO_MODE
 DHDCFLAGS += -DP2P_SKIP_DFS
 DHDCFLAGS += -DKEEP_WIFION_OPTION
@@ -203,6 +207,7 @@ DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
 DHDCFLAGS += -DSKIP_WLFC_ON_CONCURRENT
 DHDCFLAGS += -DP2P_LISTEN_OFFLOADING
 DHDCFLAGS += -DUNSET_FW_ROAM_WIPHY_FLAG
+DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 
 # For special PNO Event keep wake lock for 10sec
 DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -253,7 +258,8 @@ DHDCFLAGS += -DCONFIG_HAS_WAKELOCK
 # Used short dwell time during initial scan
 DHDCFLAGS += -DUSE_INITIAL_SHORT_DWELL_TIME
 
-# Japan ccode revision will be fixed by nvram's value
+# Korea and Japan ccode revision will be fixed by nvram's value
+DHDCFLAGS += -DKEEP_KR_REGREV
 DHDCFLAGS += -DKEEP_JP_REGREV
 
 # NAN feature
@@ -282,21 +288,39 @@ DHDCFLAGS += -DSUPPORT_TRIGGER_HANG_EVENT
 # Enable Checking Blob existence
 DHDCFLAGS += -DDHD_BLOB_EXISTENCE_CHECK
 
+# Random mac scan
+DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+# WLC_E_SET_SSID fail
+DHDCFLAGS += -DSET_SSID_FAIL_CUSTOM_RC=100
+
+# Enable to block Band A(5G), Only support Band B(2G)
+ifeq ($(CONFIG_WLAN_5GDISABLE),y)
+DHDCFLAGS += -DDHD_2G_ONLY_SUPPORT
+endif
+# Disable VHT(5G HT80) mode
+ifeq ($(CONFIG_WLAN_VHTDISABLE),y)
+DHDCFLAGS += -DDHD_DISABLE_VHTMODE
+endif
+
 # Android Version Check from Platform source
-CANDIDATE_VERSION_PATH := ./../../build/core ../../../../../../build/core out
-FOUND_VERSION_PATH := $(foreach dir,$(CANDIDATE_VERSION_PATH), $(wildcard $(dir)/version_defaults.mk))
-FOUND_VERSION_PATH := $(word 1, $(FOUND_VERSION_PATH))
-ifeq ($(FOUND_VERSION_PATH),)
-$(warning Not found Android version file. Set None)
-else
-# Extract version string and get major number
-ANDROID_PLATFORM_VERSION := $(shell grep "PLATFORM_VERSION := " $(FOUND_VERSION_PATH) | cut -d "=" -f 2 | cut -d "." -f 1 | sed 's/ //g')
-$(warning Android Platform Version : $(ANDROID_PLATFORM_VERSION))
-# If Android version lower than 7(Nougat) => Use Legacy File path
-ifeq ($(shell expr $(ANDROID_PLATFORM_VERSION) \< 7),1)
-DHDCFLAGS += -DDHD_LEGACY_FILE_PATH
-$(warning Will be use Legacy file path)
+ifneq ($(PLATFORM_VERSION),)
+MAJOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -d "." -f 1)
+DHDCFLAGS += -DANDROID_PLATFORM_VERSION=$(MAJOR_VERSION)
 endif
+
+ifneq ($(PLATFORM_VERSION),)
+# Android O-OS (version 8) support
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+DHDCFLAGS += -DCUSTOM_ASSOC_TIMEOUT=20
+endif
+endif
+
+# Use Legacy dump path
+ifneq ($(USE_LEGACY_DUMP_PATH),)
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/media/wifi/log/\""
+else
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/log/wifi/\""
 endif
 
 ##############################
@@ -338,7 +362,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
  DHDCFLAGS += -DDHD_SSSR_DUMP
- DHDCFLAGS += -DDISABLE_SETBAND
 # tput enhancement for common
  DHDCFLAGS += -DUSE_WL_TXBF
  DHDCFLAGS += -DUSE_WL_FRAMEBURST
@@ -350,7 +373,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE
 # Customer ocl disabe
  DHDCFLAGS += -DCUSTOM_SET_OCLOFF
-
 # tput enhancement for PCIE
 ifeq ($(BUS_IFACE_PCIE),y)
   DHDCFLAGS += -DCUSTOM_TCPACK_SUPP_RATIO=15
@@ -371,13 +393,14 @@ endif
   DHDCFLAGS += -DWLFBT
   DHDCFLAGS += -DDHD_ENABLE_LPC
   DHDCFLAGS += -DWLAIBSS -DWLAIBSS_PS
-  DHDCFLAGS += -DWLADPS
-  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS
+#  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS_SEAK_AP_WAR
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
   DHDCFLAGS += -DWL_RELMCAST
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT -DSUPPORT_5G_1024QAM_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
 # disable pruned scan
@@ -394,11 +417,10 @@ endif
 # LOGTRACE_EVENT
   DHDCFLAGS += -DSHOW_LOGTRACE
   DHDCFLAGS += -DLOGTRACE_FROM_FILE
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
 ifeq ($(CONFIG_ARCH_MSM8998),y)
 # Use SMMU for IOMEM
   DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
 endif
 # Expand TCP tx queue to 10 times of default size
   DHDCFLAGS += -DTSQ_MULTIPLIER=10
@@ -407,20 +429,70 @@ endif
 ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895) $(CONFIG_ARCH_TEGRA)),y)
 # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
-# Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
 # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
 # Enable LQCM
   DHDCFLAGS += -DSUPPORT_LQCM
 endif
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895)), y)
+# DHD_LB_IRQSET - CPU migration by IRQ Affinity Set
+  DHDCFLAGS += -DDHD_LB_IRQSET
+endif
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+
+ifneq ($(PLATFORM_VERSION),)
+# DREAM Android N OS should not use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \< 8.0),1)
+ifneq ($(filter y,$(CONFIG_WLAN_GREAT) $(CONFIG_SEC_GREATQLTE_PROJECT)),y)
+ DREAM_NOS_DISCARD_FEATURES := y
+endif
+endif
+
+# Feature Set used for GREAT N OS and Android O OS
+ifneq ($(DREAM_NOS_DISCARD_FEATURES),y)
+# Debugaility
+  DHDCFLAGS += -DDEBUGABILITY
+  DHDCFLAGS += -DDHD_PKT_LOGGING
+# Debug Wakeup pkt reason
+  DHDCFLAGS += -DDHD_WAKE_STATUS -DDHD_WAKE_RX_STATUS -DDHD_WAKE_EVENT_STATUS
+  DHDCFLAGS += -DDHD_WAKEPKT_DUMP
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+# LAST ROAM EVENT LOG
+  DHDCFLAGS += -DWL_LASTEVT
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+#STAT REPORT
+#stat report shall be defined only if LINK STAT is defined
+  DHDCFLAGS += -DSTAT_REPORT
+#define temp static only when SDK doesn't support static memory for STAT REPORT
+#  DHDCFLAGS += -DSTAT_REPORT_TEMP_STATIC
+# Enable DHD_DUMP_MNGR
+  DHDCFLAGS += -DDHD_DUMP_MNGR
+endif
+
+# RSSI_SUM_REPORT is used over Android O OS only
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# RSSI Logging
+  DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
+# Enable NDO_CONFIG_SUPPORT in HAL
+  DHDCFLAGS += -DNDO_CONFIG_SUPPORT
+endif
+endif
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4361),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -429,7 +501,7 @@ ifneq ($(CONFIG_BCM4359),)
   DHDCFLAGS += -DMIMO_ANT_SETTING
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=4
+  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
   DHDCFLAGS += -DSOFTAP_UAPSD_OFF
 # tput enhancement for common
   DHDCFLAGS += -DUSE_WL_TXBF
@@ -466,9 +538,13 @@ endif
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
+  DHDCFLAGS += -DWL11ULB
  #DHDCFLAGS += -DSUPPORT_SENSORHUB
  # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
+ # virtual interface support for BCM4359 only
+  DHDCFLAGS += -DDHD_USE_CHECK_DONGLE_IDLE
+  DHDCFLAGS += -DDHD_ABORT_SCAN_CREATE_INTERFACE
  # disable pruned scan
   DHDCFLAGS += -DDISABLE_PRUNED_SCAN
  # Remove common feature for BCM4359
@@ -480,26 +556,68 @@ endif
  # Use restricted channels on STA/SoftAP concurrent mode
   DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
   DHDCFLAGS += -DDHD_LOG_DUMP
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
-ifneq ($(CONFIG_WLAN_GRACE),)
-  DHDCFLAGS += -DWBTEXT
-endif
-ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_SOC_EXYNOS8890)),y)
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+  DHDCFLAGS += -DSUPPORT_CUSTOM_SET_CAC
+# To support Enable EVENT SDB Transition log.
+  DHDCFLAGS += -DSUPPORT_EVT_SDB_LOG
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_ARCH_TEGRA)),y)
  # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
- # Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
+ # IRQ affinity setting for RX Load Balance
+ # DHDCFLAGS += -DDHD_LB_IRQSET
  # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
+ # CLM
+  DHDCFLAGS += -DDHD_SUPPORT_GB_999
+ # Configure MU-MIMO capability
+ifeq ($(CONFIG_SOC_EXYNOS8890),y)
+  DHDCFLAGS += -DDYNAMIC_MUMIMO_CONTROL
+endif
+ifeq ($(CONFIG_ARCH_MSM8998),y)
+# Use SMMU for IOMEM
+  DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
+endif
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO) $(CONFIG_SEC_HEROQLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_949
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO2) $(CONFIG_SEC_HERO2QLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_945
 endif
+# HANG simulation
+  DHDCFLAGS += -DDHD_HANG_SEND_UP_TEST
+
+ifeq ($(filter y,$(CONFIG_WLAN_GRACE) $(CONFIG_SEC_GRACEQLTE_PROJECT)),y)
+  # WBTEXT (11kv) feature
+  DHDCFLAGS += -DWBTEXT
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+endif
+
+ # RSDB mode from file config
+  DHDCFLAGS += -DRSDB_MODE_FROM_FILE
+ # LOGTRACE_EVENT
+  DHDCFLAGS += -DSHOW_LOGTRACE
+  DHDCFLAGS += -DLOGTRACE_FROM_FILE
+
+# Enable concate blob path
+    DHDCFLAGS += -DCONCATE_BLOB
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4359),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -572,9 +690,6 @@ ifeq ($(CONFIG_BCM4358),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 ifneq ($(CONFIG_BCM4354),)
@@ -591,6 +706,7 @@ ifneq ($(CONFIG_BCM4354),)
 # tput enhancement for SDIO
 ifeq ($(BUS_IFACE_SDIO),y)
   DHDCFLAGS += -DHW_OOB
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
   DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
   DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
@@ -633,9 +749,6 @@ ifeq ($(CONFIG_BCM4354),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 # Chipsets supported SDIO only
@@ -653,6 +766,7 @@ ifneq ($(CONFIG_BCM4339),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -682,11 +796,22 @@ ifeq ($(CONFIG_BCM4339),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
 endif
 
+ifneq ($(CONFIG_BCM43456),)
+  DHDCFLAGS += -DBCM43456_CHIP
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
+endif
 ifneq ($(CONFIG_BCM43455),)
-  DHDCFLAGS += -DBCM43455_CHIP -DHW_OOB
+  DHDCFLAGS += -DBCM43455_CHIP
+endif
+ifneq ($(CONFIG_BCM43454),)
+  DHDCFLAGS += -DBCM43454_CHIP
+endif
+
+# BCM43454/43455/43456 common difine.
+ifneq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)))
+  DHDCFLAGS += -DHW_OOB
   DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
@@ -699,6 +824,7 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -717,12 +843,11 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
   DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43455),y)
+ifeq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
   DHDCFLAGS += -DDHD_LOG_DUMP
 
   # FCC power limit control on ch12/13.
@@ -734,64 +859,38 @@ endif
   DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
   DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
+
+ifneq ($(filter y,$(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43455) $(CONFIG_BCM43456)))
 # Enable Firmware Coredump
-  DHDCFLAGS += -DDHD_FW_COREDUMP
+    DHDCFLAGS += -DDHD_FW_COREDUMP
 ifeq ($(CONFIG_BCMDHD_PREALLOC_MEMDUMP),y)
-  DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+    DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
 endif
 
 # Enable concate blob path
-  DHDCFLAGS += -DCONCATE_BLOB
-endif
-
-ifneq ($(CONFIG_BCM43454),)
-  DHDCFLAGS += -DBCM43454_CHIP -DHW_OOB
-  DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
-  DHDCFLAGS += -DUSE_CID_CHECK
-  DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DUSE_SDIOFIFO_IOVAR
+    DHDCFLAGS += -DCONCATE_BLOB
+# Generate .softap.info
+    DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
 
-  # tput enhancement
-  DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
-  DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
-  DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
-  DHDCFLAGS += -DDHDTCPACK_SUPPRESS
-  DHDCFLAGS += -DUSE_WL_TXBF
-  DHDCFLAGS += -DUSE_WL_FRAMEBURST
-  DHDCFLAGS += -DRXFRAME_THREAD
-  DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
-  DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
-  DHDCFLAGS += -DPROP_TXSTATUS_VSDB
-
-  # New Features
-  DHDCFLAGS += -DWL11U -DMFP
-  DHDCFLAGS += -DBCMCCX
-  DHDCFLAGS += -DWES_SUPPORT
-  DHDCFLAGS += -DOKC_SUPPORT
-  DHDCFLAGS += -DWLTDLS -DWLTDLS_AUTO_ENABLE
-  DHDCFLAGS += -DWLFBT
-  DHDCFLAGS += -DDHD_ENABLE_LPC
-  DHDCFLAGS += -DWLAIBSS
-  DHDCFLAGS += -DSUPPORT_LTECX
-  DHDCFLAGS += -DSUPPORT_2G_VHT
-  DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43454),y)
-  DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
-  DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
-  DRIVER_TYPE = y
+ifneq ($(CONFIG_BCM43456),)
+# STA/SoftAP Concurrent Mode Support for legacy chip
+  DHDCFLAGS += -DWL_VIRTUAL_APSTA
+  DHDCFLAGS += -DWL_RESTRICTED_APSTA_SCC
+  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
+  DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
+# Use restricted channels on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
+# Block ARP during DHCP on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_BLOCK_ARP_DURING_DHCP
+endif
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-  DHDCFLAGS += -DDHD_LOG_DUMP
-
-  # FCC power limit control on ch12/13.
-  #   DHDCFLAGS += -DFCC_PWR_LIMIT_2G
-  #
-  # Enable Roam time thresh
-  DHDCFLAGS += -DENABLE_MAX_DTIM_IN_SUSPEND
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT_IN_SUSPEND=10
-  DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
-  DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 endif
 
 ifneq ($(CONFIG_BCM4335),)
@@ -808,6 +907,7 @@ ifneq ($(CONFIG_BCM4335),)
 # DHDCFLAGS += -DDHD_SET_FW_HIGHSPEED
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DREPEAT_READFRAME
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64
@@ -925,6 +1025,15 @@ endif
   # Remove common feature for BCM4343
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DSUPPORT_P2P_GO_PS,$(DHDCFLAGS))
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
 endif
 
 ifneq ($(CONFIG_BCM43012),)
@@ -960,6 +1069,8 @@ ifeq ($(CONFIG_SOLIS),y)
   DHDCFLAGS += -DPLATFORM_SLP
   DHDCFLAGS += -UCONFIG_HAS_WAKELOCK
   DHDCFLAGS += -UDHD_TRACE_WAKE_LOCK
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+  DHDCFLAGS += -DDISCARD_UDPNETBIOS
 endif
   # Remove common feature for 43012
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
@@ -980,6 +1091,7 @@ endif
   DHDCFLAGS :=$(filter-out -DSUPPORT_AMPDU_MPDU_CMD,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DVSDB,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DPROP_TXSTATUS,$(DHDCFLAGS))
+  DHDCFLAGS :=$(filter-out -DLIMIT_BORROW,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDHD_USE_IDLECOUNT,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
@@ -1069,6 +1181,7 @@ endif
 ifneq ($(CONFIG_MACH_EXSOM7420),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
+DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 obj-$(CONFIG_MACH_EXSOM7420) += dhd_custom_exynos.o dhd_custom_memprealloc.o
 endif
 ifneq ($(CONFIG_SOC_EXYNOS8890),)
@@ -1079,10 +1192,10 @@ DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5430),)
-obj-$(CONFIG_MACH_UNIVERSAL5430) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5422),)
-obj-$(CONFIG_MACH_UNIVERSAL5422) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_ARCH_MSM8994),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
@@ -1105,6 +1218,10 @@ ifneq ($(CONFIG_SOC_EXYNOS7870),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -Wno-date-time
 endif
+ifneq ($(CONFIG_SOC_EXYNOS7885),)
+DHDCFLAGS += -DDHD_OF_SUPPORT
+DHDCFLAGS += -Wno-date-time
+endif
 ifneq ($(CONFIG_SOC_EXYNOS7570),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
@@ -1128,6 +1245,7 @@ DHDCFLAGS := $(filter-out -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL,$(DHDCFLAGS)
 DHDCFLAGS := $(filter-out -DWL_VENDOR_EXT_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DGSCAN_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DRTT_SUPPORT,$(DHDCFLAGS))
+DHDCFLAGS := $(filter-out -DDHD_LB_IRQSET,$(DHDCFLAGS))
 DHD_ANDROID_OFILES := $(filter-out wl_cfgvendor.o,$(DHD_ANDROID_OFILES))
 DHD_ANDROID_OFILES := $(filter-out dhd_rtt.o,$(DHD_ANDROID_OFILES))
 endif
@@ -1155,8 +1273,8 @@ DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o dhd_custom_sec.o
        bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \
        wl_android.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o \
        wl_linux_mon.o wl_roam.o dhd_linux_platdev.o dhd_linux_wq.o wl_cfg_btcoex.o \
-       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o
-
+       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o \
+       dhd_pktlog.o
 
 ifeq ($(BUS_IFACE_SDIO),y)
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o
@@ -1185,6 +1303,10 @@ ifeq ($(CONFIG_WL_NAN),y)
 # DHDOFILES += wl_cfgnan.o bcmxtlv.o
 endif
 
+ifneq ($(filter -DSTAT_REPORT,$(DHDCFLAGS)),)
+DHDOFILES += wl_statreport.o
+endif
+
 dhd-y := $(DHDOFILES)
 obj-$(DRIVER_TYPE)   += dhd.o
 
index 06b86644f30431d7e18819ffdc03af1674c36111..be6ddcbc309d871a224debffd5ac4472edbd2586 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2018, Broadcom Corporation
 # 
 #      Unless you and Broadcom execute a separate written software license
 # agreement governing use of this software, this software is licensed to you
@@ -60,7 +60,7 @@ endif
        # SKB TAILPAD to avoid out of boundary memory access
        DHDCFLAGS += -DDHDENABLE_TAILPAD
        # Enable PROP_TXSTATUS
-       DHDCFLAGS += -DPROP_TXSTATUS
+       DHDCFLAGS += -DPROP_TXSTATUS -DLIMIT_BORROW
        DHDCFLAGS += -DSUPPORT_P2P_GO_PS
        # Debug for DPC Thread watchdog bark
        DHDCFLAGS += -DDEBUG_DPC_THREAD_WATCHDOG
@@ -89,6 +89,8 @@ endif
        DHDCFLAGS += -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL
        # Enable Link down recovery
        DHDCFLAGS += -DSUPPORT_LINKDOWN_RECOVERY
+       # Enable Dongle Isolation
+       DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
        # Enable Firmware Coredump
        DHDCFLAGS += -DDHD_FW_COREDUMP
         # Enable PKTID AUDIT
@@ -97,11 +99,11 @@ endif
        # DHD_LB_RXP - Perform RX Packet processing in parallel
        # DHD_LB_STATS - To display the Load Blancing statistics
        DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_TXP -DDHD_LB_STATS
-       # Enable wakelock for legacy scan
-       DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
        # Extended HANG event with reason codes
        DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON
        DHDCFLAGS += -DDHD_RECOVER_TIMEOUT
+       # HEAP ASLR
+       DHDCFLAGS += -DBCM_ASLR_HEAP
 
 ifneq ($(CONFIG_SOC_EXYNOS8895),)
        # Default Tx LB Enable
@@ -129,6 +131,8 @@ endif
 # Debug
 DHDCFLAGS += -DSIMPLE_MAC_PRINT
 DHDCFLAGS += -DDEBUGFS_CFG80211
+# Enable wakelock for legacy scan
+DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
 # Enable wakelock debug function
 DHDCFLAGS += -DDHD_TRACE_WAKE_LOCK
 # Print out kernel panic point of file and line info when assertion happened
@@ -162,7 +166,7 @@ DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-80
 DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-85
 
 # Roaming
-DHDCFLAGS += -DROAM_AP_ENV_DETECTION
+DHDCFLAGS += -DROAM_AP_ENV_DETECTION -DKEEP_CUSTOM_ROAM_TRIGGER
 DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API
 DHDCFLAGS += -DENABLE_FW_ROAM_SUSPEND
 DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
@@ -194,7 +198,7 @@ DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
 DHDCFLAGS += -DDHD_USE_ATOMIC_PKTGET
 DHDCFLAGS += -DTDLS_MSG_ONLY_WFD
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=30000
-DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=20
+DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=30
 DHDCFLAGS += -DENABLE_TDLS_AUTO_MODE
 DHDCFLAGS += -DP2P_SKIP_DFS
 DHDCFLAGS += -DKEEP_WIFION_OPTION
@@ -203,6 +207,7 @@ DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
 DHDCFLAGS += -DSKIP_WLFC_ON_CONCURRENT
 DHDCFLAGS += -DP2P_LISTEN_OFFLOADING
 DHDCFLAGS += -DUNSET_FW_ROAM_WIPHY_FLAG
+DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 
 # For special PNO Event keep wake lock for 10sec
 DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -253,7 +258,8 @@ DHDCFLAGS += -DCONFIG_HAS_WAKELOCK
 # Used short dwell time during initial scan
 DHDCFLAGS += -DUSE_INITIAL_SHORT_DWELL_TIME
 
-# Japan ccode revision will be fixed by nvram's value
+# Korea and Japan ccode revision will be fixed by nvram's value
+DHDCFLAGS += -DKEEP_KR_REGREV
 DHDCFLAGS += -DKEEP_JP_REGREV
 
 # NAN feature
@@ -282,21 +288,39 @@ DHDCFLAGS += -DSUPPORT_TRIGGER_HANG_EVENT
 # Enable Checking Blob existence
 DHDCFLAGS += -DDHD_BLOB_EXISTENCE_CHECK
 
+# Random mac scan
+DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+# WLC_E_SET_SSID fail
+DHDCFLAGS += -DSET_SSID_FAIL_CUSTOM_RC=100
+
+# Enable to block Band A(5G), Only support Band B(2G)
+ifeq ($(CONFIG_WLAN_5GDISABLE),y)
+DHDCFLAGS += -DDHD_2G_ONLY_SUPPORT
+endif
+# Disable VHT(5G HT80) mode
+ifeq ($(CONFIG_WLAN_VHTDISABLE),y)
+DHDCFLAGS += -DDHD_DISABLE_VHTMODE
+endif
+
 # Android Version Check from Platform source
-CANDIDATE_VERSION_PATH := ./../../build/core ../../../../../../build/core out
-FOUND_VERSION_PATH := $(foreach dir,$(CANDIDATE_VERSION_PATH), $(wildcard $(dir)/version_defaults.mk))
-FOUND_VERSION_PATH := $(word 1, $(FOUND_VERSION_PATH))
-ifeq ($(FOUND_VERSION_PATH),)
-$(warning Not found Android version file. Set None)
-else
-# Extract version string and get major number
-ANDROID_PLATFORM_VERSION := $(shell grep "PLATFORM_VERSION := " $(FOUND_VERSION_PATH) | cut -d "=" -f 2 | cut -d "." -f 1 | sed 's/ //g')
-$(warning Android Platform Version : $(ANDROID_PLATFORM_VERSION))
-# If Android version lower than 7(Nougat) => Use Legacy File path
-ifeq ($(shell expr $(ANDROID_PLATFORM_VERSION) \< 7),1)
-DHDCFLAGS += -DDHD_LEGACY_FILE_PATH
-$(warning Will be use Legacy file path)
+ifneq ($(PLATFORM_VERSION),)
+MAJOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -d "." -f 1)
+DHDCFLAGS += -DANDROID_PLATFORM_VERSION=$(MAJOR_VERSION)
 endif
+
+ifneq ($(PLATFORM_VERSION),)
+# Android O-OS (version 8) support
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+DHDCFLAGS += -DCUSTOM_ASSOC_TIMEOUT=20
+endif
+endif
+
+# Use Legacy dump path
+ifneq ($(USE_LEGACY_DUMP_PATH),)
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/media/wifi/log/\""
+else
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/log/wifi/\""
 endif
 
 ##############################
@@ -338,7 +362,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
  DHDCFLAGS += -DDHD_SSSR_DUMP
- DHDCFLAGS += -DDISABLE_SETBAND
 # tput enhancement for common
  DHDCFLAGS += -DUSE_WL_TXBF
  DHDCFLAGS += -DUSE_WL_FRAMEBURST
@@ -350,7 +373,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE
 # Customer ocl disabe
  DHDCFLAGS += -DCUSTOM_SET_OCLOFF
-
 # tput enhancement for PCIE
 ifeq ($(BUS_IFACE_PCIE),y)
   DHDCFLAGS += -DCUSTOM_TCPACK_SUPP_RATIO=15
@@ -371,13 +393,14 @@ endif
   DHDCFLAGS += -DWLFBT
   DHDCFLAGS += -DDHD_ENABLE_LPC
   DHDCFLAGS += -DWLAIBSS -DWLAIBSS_PS
-  DHDCFLAGS += -DWLADPS
-  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS
+#  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS_SEAK_AP_WAR
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
   DHDCFLAGS += -DWL_RELMCAST
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT -DSUPPORT_5G_1024QAM_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
 # disable pruned scan
@@ -394,11 +417,10 @@ endif
 # LOGTRACE_EVENT
   DHDCFLAGS += -DSHOW_LOGTRACE
   DHDCFLAGS += -DLOGTRACE_FROM_FILE
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
 ifeq ($(CONFIG_ARCH_MSM8998),y)
 # Use SMMU for IOMEM
   DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
 endif
 # Expand TCP tx queue to 10 times of default size
   DHDCFLAGS += -DTSQ_MULTIPLIER=10
@@ -407,20 +429,70 @@ endif
 ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895) $(CONFIG_ARCH_TEGRA)),y)
 # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
-# Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
 # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
 # Enable LQCM
   DHDCFLAGS += -DSUPPORT_LQCM
 endif
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895)), y)
+# DHD_LB_IRQSET - CPU migration by IRQ Affinity Set
+  DHDCFLAGS += -DDHD_LB_IRQSET
+endif
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+
+ifneq ($(PLATFORM_VERSION),)
+# DREAM Android N OS should not use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \< 8.0),1)
+ifneq ($(filter y,$(CONFIG_WLAN_GREAT) $(CONFIG_SEC_GREATQLTE_PROJECT)),y)
+ DREAM_NOS_DISCARD_FEATURES := y
+endif
+endif
+
+# Feature Set used for GREAT N OS and Android O OS
+ifneq ($(DREAM_NOS_DISCARD_FEATURES),y)
+# Debugaility
+  DHDCFLAGS += -DDEBUGABILITY
+  DHDCFLAGS += -DDHD_PKT_LOGGING
+# Debug Wakeup pkt reason
+  DHDCFLAGS += -DDHD_WAKE_STATUS -DDHD_WAKE_RX_STATUS -DDHD_WAKE_EVENT_STATUS
+  DHDCFLAGS += -DDHD_WAKEPKT_DUMP
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+# LAST ROAM EVENT LOG
+  DHDCFLAGS += -DWL_LASTEVT
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+#STAT REPORT
+#stat report shall be defined only if LINK STAT is defined
+  DHDCFLAGS += -DSTAT_REPORT
+#define temp static only when SDK doesn't support static memory for STAT REPORT
+#  DHDCFLAGS += -DSTAT_REPORT_TEMP_STATIC
+# Enable DHD_DUMP_MNGR
+  DHDCFLAGS += -DDHD_DUMP_MNGR
+endif
+
+# RSSI_SUM_REPORT is used over Android O OS only
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# RSSI Logging
+  DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
+# Enable NDO_CONFIG_SUPPORT in HAL
+  DHDCFLAGS += -DNDO_CONFIG_SUPPORT
+endif
+endif
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4361),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -429,7 +501,7 @@ ifneq ($(CONFIG_BCM4359),)
   DHDCFLAGS += -DMIMO_ANT_SETTING
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=4
+  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
   DHDCFLAGS += -DSOFTAP_UAPSD_OFF
 # tput enhancement for common
   DHDCFLAGS += -DUSE_WL_TXBF
@@ -466,9 +538,13 @@ endif
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
+  DHDCFLAGS += -DWL11ULB
  #DHDCFLAGS += -DSUPPORT_SENSORHUB
  # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
+ # virtual interface support for BCM4359 only
+  DHDCFLAGS += -DDHD_USE_CHECK_DONGLE_IDLE
+  DHDCFLAGS += -DDHD_ABORT_SCAN_CREATE_INTERFACE
  # disable pruned scan
   DHDCFLAGS += -DDISABLE_PRUNED_SCAN
  # Remove common feature for BCM4359
@@ -480,26 +556,68 @@ endif
  # Use restricted channels on STA/SoftAP concurrent mode
   DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
   DHDCFLAGS += -DDHD_LOG_DUMP
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
-ifneq ($(CONFIG_WLAN_GRACE),)
-  DHDCFLAGS += -DWBTEXT
-endif
-ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_SOC_EXYNOS8890)),y)
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+  DHDCFLAGS += -DSUPPORT_CUSTOM_SET_CAC
+# To support Enable EVENT SDB Transition log.
+  DHDCFLAGS += -DSUPPORT_EVT_SDB_LOG
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_ARCH_TEGRA)),y)
  # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
- # Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
+ # IRQ affinity setting for RX Load Balance
+ # DHDCFLAGS += -DDHD_LB_IRQSET
  # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
+ # CLM
+  DHDCFLAGS += -DDHD_SUPPORT_GB_999
+ # Configure MU-MIMO capability
+ifeq ($(CONFIG_SOC_EXYNOS8890),y)
+  DHDCFLAGS += -DDYNAMIC_MUMIMO_CONTROL
+endif
+ifeq ($(CONFIG_ARCH_MSM8998),y)
+# Use SMMU for IOMEM
+  DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
+endif
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO) $(CONFIG_SEC_HEROQLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_949
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO2) $(CONFIG_SEC_HERO2QLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_945
 endif
+# HANG simulation
+  DHDCFLAGS += -DDHD_HANG_SEND_UP_TEST
+
+ifeq ($(filter y,$(CONFIG_WLAN_GRACE) $(CONFIG_SEC_GRACEQLTE_PROJECT)),y)
+  # WBTEXT (11kv) feature
+  DHDCFLAGS += -DWBTEXT
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+endif
+
+ # RSDB mode from file config
+  DHDCFLAGS += -DRSDB_MODE_FROM_FILE
+ # LOGTRACE_EVENT
+  DHDCFLAGS += -DSHOW_LOGTRACE
+  DHDCFLAGS += -DLOGTRACE_FROM_FILE
+
+# Enable concate blob path
+    DHDCFLAGS += -DCONCATE_BLOB
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4359),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -572,9 +690,6 @@ ifeq ($(CONFIG_BCM4358),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 ifneq ($(CONFIG_BCM4354),)
@@ -591,6 +706,7 @@ ifneq ($(CONFIG_BCM4354),)
 # tput enhancement for SDIO
 ifeq ($(BUS_IFACE_SDIO),y)
   DHDCFLAGS += -DHW_OOB
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
   DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
   DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
@@ -633,9 +749,6 @@ ifeq ($(CONFIG_BCM4354),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 # Chipsets supported SDIO only
@@ -653,6 +766,7 @@ ifneq ($(CONFIG_BCM4339),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -682,11 +796,22 @@ ifeq ($(CONFIG_BCM4339),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
 endif
 
+ifneq ($(CONFIG_BCM43456),)
+  DHDCFLAGS += -DBCM43456_CHIP
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
+endif
 ifneq ($(CONFIG_BCM43455),)
-  DHDCFLAGS += -DBCM43455_CHIP -DHW_OOB
+  DHDCFLAGS += -DBCM43455_CHIP
+endif
+ifneq ($(CONFIG_BCM43454),)
+  DHDCFLAGS += -DBCM43454_CHIP
+endif
+
+# BCM43454/43455/43456 common difine.
+ifneq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)))
+  DHDCFLAGS += -DHW_OOB
   DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
@@ -699,6 +824,7 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -717,12 +843,11 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
   DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43455),y)
+ifeq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
   DHDCFLAGS += -DDHD_LOG_DUMP
 
   # FCC power limit control on ch12/13.
@@ -734,64 +859,38 @@ endif
   DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
   DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
+
+ifneq ($(filter y,$(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43455) $(CONFIG_BCM43456)))
 # Enable Firmware Coredump
-  DHDCFLAGS += -DDHD_FW_COREDUMP
+    DHDCFLAGS += -DDHD_FW_COREDUMP
 ifeq ($(CONFIG_BCMDHD_PREALLOC_MEMDUMP),y)
-  DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+    DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
 endif
 
 # Enable concate blob path
-  DHDCFLAGS += -DCONCATE_BLOB
-endif
-
-ifneq ($(CONFIG_BCM43454),)
-  DHDCFLAGS += -DBCM43454_CHIP -DHW_OOB
-  DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
-  DHDCFLAGS += -DUSE_CID_CHECK
-  DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DUSE_SDIOFIFO_IOVAR
+    DHDCFLAGS += -DCONCATE_BLOB
+# Generate .softap.info
+    DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
 
-  # tput enhancement
-  DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
-  DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
-  DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
-  DHDCFLAGS += -DDHDTCPACK_SUPPRESS
-  DHDCFLAGS += -DUSE_WL_TXBF
-  DHDCFLAGS += -DUSE_WL_FRAMEBURST
-  DHDCFLAGS += -DRXFRAME_THREAD
-  DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
-  DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
-  DHDCFLAGS += -DPROP_TXSTATUS_VSDB
-
-  # New Features
-  DHDCFLAGS += -DWL11U -DMFP
-  DHDCFLAGS += -DBCMCCX
-  DHDCFLAGS += -DWES_SUPPORT
-  DHDCFLAGS += -DOKC_SUPPORT
-  DHDCFLAGS += -DWLTDLS -DWLTDLS_AUTO_ENABLE
-  DHDCFLAGS += -DWLFBT
-  DHDCFLAGS += -DDHD_ENABLE_LPC
-  DHDCFLAGS += -DWLAIBSS
-  DHDCFLAGS += -DSUPPORT_LTECX
-  DHDCFLAGS += -DSUPPORT_2G_VHT
-  DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43454),y)
-  DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
-  DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
-  DRIVER_TYPE = y
+ifneq ($(CONFIG_BCM43456),)
+# STA/SoftAP Concurrent Mode Support for legacy chip
+  DHDCFLAGS += -DWL_VIRTUAL_APSTA
+  DHDCFLAGS += -DWL_RESTRICTED_APSTA_SCC
+  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
+  DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
+# Use restricted channels on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
+# Block ARP during DHCP on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_BLOCK_ARP_DURING_DHCP
+endif
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-  DHDCFLAGS += -DDHD_LOG_DUMP
-
-  # FCC power limit control on ch12/13.
-  #   DHDCFLAGS += -DFCC_PWR_LIMIT_2G
-  #
-  # Enable Roam time thresh
-  DHDCFLAGS += -DENABLE_MAX_DTIM_IN_SUSPEND
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT_IN_SUSPEND=10
-  DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
-  DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 endif
 
 ifneq ($(CONFIG_BCM4335),)
@@ -808,6 +907,7 @@ ifneq ($(CONFIG_BCM4335),)
 # DHDCFLAGS += -DDHD_SET_FW_HIGHSPEED
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DREPEAT_READFRAME
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64
@@ -925,6 +1025,15 @@ endif
   # Remove common feature for BCM4343
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DSUPPORT_P2P_GO_PS,$(DHDCFLAGS))
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
 endif
 
 ifneq ($(CONFIG_BCM43012),)
@@ -960,6 +1069,8 @@ ifeq ($(CONFIG_SOLIS),y)
   DHDCFLAGS += -DPLATFORM_SLP
   DHDCFLAGS += -UCONFIG_HAS_WAKELOCK
   DHDCFLAGS += -UDHD_TRACE_WAKE_LOCK
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+  DHDCFLAGS += -DDISCARD_UDPNETBIOS
 endif
   # Remove common feature for 43012
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
@@ -980,6 +1091,7 @@ endif
   DHDCFLAGS :=$(filter-out -DSUPPORT_AMPDU_MPDU_CMD,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DVSDB,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DPROP_TXSTATUS,$(DHDCFLAGS))
+  DHDCFLAGS :=$(filter-out -DLIMIT_BORROW,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDHD_USE_IDLECOUNT,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
@@ -1069,6 +1181,7 @@ endif
 ifneq ($(CONFIG_MACH_EXSOM7420),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
+DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 obj-$(CONFIG_MACH_EXSOM7420) += dhd_custom_exynos.o dhd_custom_memprealloc.o
 endif
 ifneq ($(CONFIG_SOC_EXYNOS8890),)
@@ -1079,10 +1192,10 @@ DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5430),)
-obj-$(CONFIG_MACH_UNIVERSAL5430) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5422),)
-obj-$(CONFIG_MACH_UNIVERSAL5422) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_ARCH_MSM8994),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
@@ -1105,6 +1218,10 @@ ifneq ($(CONFIG_SOC_EXYNOS7870),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -Wno-date-time
 endif
+ifneq ($(CONFIG_SOC_EXYNOS7885),)
+DHDCFLAGS += -DDHD_OF_SUPPORT
+DHDCFLAGS += -Wno-date-time
+endif
 ifneq ($(CONFIG_SOC_EXYNOS7570),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
@@ -1128,6 +1245,7 @@ DHDCFLAGS := $(filter-out -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL,$(DHDCFLAGS)
 DHDCFLAGS := $(filter-out -DWL_VENDOR_EXT_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DGSCAN_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DRTT_SUPPORT,$(DHDCFLAGS))
+DHDCFLAGS := $(filter-out -DDHD_LB_IRQSET,$(DHDCFLAGS))
 DHD_ANDROID_OFILES := $(filter-out wl_cfgvendor.o,$(DHD_ANDROID_OFILES))
 DHD_ANDROID_OFILES := $(filter-out dhd_rtt.o,$(DHD_ANDROID_OFILES))
 endif
@@ -1155,8 +1273,8 @@ DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o dhd_custom_sec.o
        bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \
        wl_android.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o \
        wl_linux_mon.o wl_roam.o dhd_linux_platdev.o dhd_linux_wq.o wl_cfg_btcoex.o \
-       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o
-
+       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o \
+       dhd_pktlog.o
 
 ifeq ($(BUS_IFACE_SDIO),y)
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o
@@ -1185,6 +1303,10 @@ ifeq ($(CONFIG_WL_NAN),y)
 # DHDOFILES += wl_cfgnan.o bcmxtlv.o
 endif
 
+ifneq ($(filter -DSTAT_REPORT,$(DHDCFLAGS)),)
+DHDOFILES += wl_statreport.o
+endif
+
 dhd-y := $(DHDOFILES)
 obj-$(DRIVER_TYPE)   += dhd.o
 
index 8a9902c7063312e80a2cae72ea89e189052cd307..fbf3ebf27dac6c07bd476272136ded6628dc532d 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 1999-2017, Broadcom Corporation
+# Copyright (C) 1999-2018, Broadcom Corporation
 # 
 #      Unless you and Broadcom execute a separate written software license
 # agreement governing use of this software, this software is licensed to you
@@ -60,7 +60,7 @@ endif
        # SKB TAILPAD to avoid out of boundary memory access
        DHDCFLAGS += -DDHDENABLE_TAILPAD
        # Enable PROP_TXSTATUS
-       DHDCFLAGS += -DPROP_TXSTATUS
+       DHDCFLAGS += -DPROP_TXSTATUS -DLIMIT_BORROW
        DHDCFLAGS += -DSUPPORT_P2P_GO_PS
        # Debug for DPC Thread watchdog bark
        DHDCFLAGS += -DDEBUG_DPC_THREAD_WATCHDOG
@@ -89,6 +89,8 @@ endif
        DHDCFLAGS += -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL
        # Enable Link down recovery
        DHDCFLAGS += -DSUPPORT_LINKDOWN_RECOVERY
+       # Enable Dongle Isolation
+       DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
        # Enable Firmware Coredump
        DHDCFLAGS += -DDHD_FW_COREDUMP
         # Enable PKTID AUDIT
@@ -97,11 +99,11 @@ endif
        # DHD_LB_RXP - Perform RX Packet processing in parallel
        # DHD_LB_STATS - To display the Load Blancing statistics
        DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_TXP -DDHD_LB_STATS
-       # Enable wakelock for legacy scan
-       DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
        # Extended HANG event with reason codes
        DHDCFLAGS += -DDHD_USE_EXTENDED_HANG_REASON
        DHDCFLAGS += -DDHD_RECOVER_TIMEOUT
+       # HEAP ASLR
+       DHDCFLAGS += -DBCM_ASLR_HEAP
 
 ifneq ($(CONFIG_SOC_EXYNOS8895),)
        # Default Tx LB Enable
@@ -129,6 +131,8 @@ endif
 # Debug
 DHDCFLAGS += -DSIMPLE_MAC_PRINT
 DHDCFLAGS += -DDEBUGFS_CFG80211
+# Enable wakelock for legacy scan
+DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK
 # Enable wakelock debug function
 DHDCFLAGS += -DDHD_TRACE_WAKE_LOCK
 # Print out kernel panic point of file and line info when assertion happened
@@ -162,7 +166,7 @@ DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_HIGH=-80
 DHDCFLAGS += -DCUSTOM_TDLS_RSSI_THRESHOLD_LOW=-85
 
 # Roaming
-DHDCFLAGS += -DROAM_AP_ENV_DETECTION
+DHDCFLAGS += -DROAM_AP_ENV_DETECTION -DKEEP_CUSTOM_ROAM_TRIGGER
 DHDCFLAGS += -DROAM_ENABLE -DROAM_CHANNEL_CACHE -DROAM_API
 DHDCFLAGS += -DENABLE_FW_ROAM_SUSPEND
 DHDCFLAGS += -DDHD_LOSSLESS_ROAMING
@@ -194,7 +198,7 @@ DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
 DHDCFLAGS += -DDHD_USE_ATOMIC_PKTGET
 DHDCFLAGS += -DTDLS_MSG_ONLY_WFD
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=30000
-DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=20
+DHDCFLAGS += -DCUSTOM_EVENT_PM_WAKE=30
 DHDCFLAGS += -DENABLE_TDLS_AUTO_MODE
 DHDCFLAGS += -DP2P_SKIP_DFS
 DHDCFLAGS += -DKEEP_WIFION_OPTION
@@ -203,6 +207,7 @@ DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
 DHDCFLAGS += -DSKIP_WLFC_ON_CONCURRENT
 DHDCFLAGS += -DP2P_LISTEN_OFFLOADING
 DHDCFLAGS += -DUNSET_FW_ROAM_WIPHY_FLAG
+DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 
 # For special PNO Event keep wake lock for 10sec
 DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
@@ -253,7 +258,8 @@ DHDCFLAGS += -DCONFIG_HAS_WAKELOCK
 # Used short dwell time during initial scan
 DHDCFLAGS += -DUSE_INITIAL_SHORT_DWELL_TIME
 
-# Japan ccode revision will be fixed by nvram's value
+# Korea and Japan ccode revision will be fixed by nvram's value
+DHDCFLAGS += -DKEEP_KR_REGREV
 DHDCFLAGS += -DKEEP_JP_REGREV
 
 # NAN feature
@@ -282,21 +288,39 @@ DHDCFLAGS += -DSUPPORT_TRIGGER_HANG_EVENT
 # Enable Checking Blob existence
 DHDCFLAGS += -DDHD_BLOB_EXISTENCE_CHECK
 
+# Random mac scan
+DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
+
+# WLC_E_SET_SSID fail
+DHDCFLAGS += -DSET_SSID_FAIL_CUSTOM_RC=100
+
+# Enable to block Band A(5G), Only support Band B(2G)
+ifeq ($(CONFIG_WLAN_5GDISABLE),y)
+DHDCFLAGS += -DDHD_2G_ONLY_SUPPORT
+endif
+# Disable VHT(5G HT80) mode
+ifeq ($(CONFIG_WLAN_VHTDISABLE),y)
+DHDCFLAGS += -DDHD_DISABLE_VHTMODE
+endif
+
 # Android Version Check from Platform source
-CANDIDATE_VERSION_PATH := ./../../build/core ../../../../../../build/core out
-FOUND_VERSION_PATH := $(foreach dir,$(CANDIDATE_VERSION_PATH), $(wildcard $(dir)/version_defaults.mk))
-FOUND_VERSION_PATH := $(word 1, $(FOUND_VERSION_PATH))
-ifeq ($(FOUND_VERSION_PATH),)
-$(warning Not found Android version file. Set None)
-else
-# Extract version string and get major number
-ANDROID_PLATFORM_VERSION := $(shell grep "PLATFORM_VERSION := " $(FOUND_VERSION_PATH) | cut -d "=" -f 2 | cut -d "." -f 1 | sed 's/ //g')
-$(warning Android Platform Version : $(ANDROID_PLATFORM_VERSION))
-# If Android version lower than 7(Nougat) => Use Legacy File path
-ifeq ($(shell expr $(ANDROID_PLATFORM_VERSION) \< 7),1)
-DHDCFLAGS += -DDHD_LEGACY_FILE_PATH
-$(warning Will be use Legacy file path)
+ifneq ($(PLATFORM_VERSION),)
+MAJOR_VERSION := $(shell echo $(PLATFORM_VERSION) | cut -d "." -f 1)
+DHDCFLAGS += -DANDROID_PLATFORM_VERSION=$(MAJOR_VERSION)
 endif
+
+ifneq ($(PLATFORM_VERSION),)
+# Android O-OS (version 8) support
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+DHDCFLAGS += -DCUSTOM_ASSOC_TIMEOUT=20
+endif
+endif
+
+# Use Legacy dump path
+ifneq ($(USE_LEGACY_DUMP_PATH),)
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/media/wifi/log/\""
+else
+  DHDCFLAGS += -DDHD_COMMON_DUMP_PATH="\"/data/log/wifi/\""
 endif
 
 ##############################
@@ -361,7 +385,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
  DHDCFLAGS += -DDHD_SSSR_DUMP
- DHDCFLAGS += -DDISABLE_SETBAND
 # tput enhancement for common
  DHDCFLAGS += -DUSE_WL_TXBF
  DHDCFLAGS += -DUSE_WL_FRAMEBURST
@@ -373,7 +396,6 @@ ifneq ($(CONFIG_BCM4361),)
  DHDCFLAGS += -DCUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE
 # Customer ocl disabe
  DHDCFLAGS += -DCUSTOM_SET_OCLOFF
-
 # tput enhancement for PCIE
 ifeq ($(BUS_IFACE_PCIE),y)
   DHDCFLAGS += -DCUSTOM_TCPACK_SUPP_RATIO=15
@@ -394,13 +416,14 @@ endif
   DHDCFLAGS += -DWLFBT
   DHDCFLAGS += -DDHD_ENABLE_LPC
   DHDCFLAGS += -DWLAIBSS -DWLAIBSS_PS
-  DHDCFLAGS += -DWLADPS
-  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS
+#  DHDCFLAGS += -DADPS_MODE_FROM_FILE
+#  DHDCFLAGS += -DWLADPS_SEAK_AP_WAR
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
   DHDCFLAGS += -DWL_RELMCAST
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT -DSUPPORT_5G_1024QAM_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DENABLE_IPMCAST_FILTER
 # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
 # disable pruned scan
@@ -417,11 +440,10 @@ endif
 # LOGTRACE_EVENT
   DHDCFLAGS += -DSHOW_LOGTRACE
   DHDCFLAGS += -DLOGTRACE_FROM_FILE
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
 ifeq ($(CONFIG_ARCH_MSM8998),y)
 # Use SMMU for IOMEM
   DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
 endif
 # Expand TCP tx queue to 10 times of default size
   DHDCFLAGS += -DTSQ_MULTIPLIER=10
@@ -430,20 +452,70 @@ endif
 ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895) $(CONFIG_ARCH_TEGRA)),y)
 # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
-# Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
 # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
 # Enable LQCM
   DHDCFLAGS += -DSUPPORT_LQCM
 endif
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_SOC_EXYNOS8895)), y)
+# DHD_LB_IRQSET - CPU migration by IRQ Affinity Set
+  DHDCFLAGS += -DDHD_LB_IRQSET
+endif
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+
+ifneq ($(PLATFORM_VERSION),)
+# DREAM Android N OS should not use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \< 8.0),1)
+ifneq ($(filter y,$(CONFIG_WLAN_GREAT) $(CONFIG_SEC_GREATQLTE_PROJECT)),y)
+ DREAM_NOS_DISCARD_FEATURES := y
+endif
+endif
+
+# Feature Set used for GREAT N OS and Android O OS
+ifneq ($(DREAM_NOS_DISCARD_FEATURES),y)
+# Debugaility
+  DHDCFLAGS += -DDEBUGABILITY
+  DHDCFLAGS += -DDHD_PKT_LOGGING
+# Debug Wakeup pkt reason
+  DHDCFLAGS += -DDHD_WAKE_STATUS -DDHD_WAKE_RX_STATUS -DDHD_WAKE_EVENT_STATUS
+  DHDCFLAGS += -DDHD_WAKEPKT_DUMP
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+# LAST ROAM EVENT LOG
+  DHDCFLAGS += -DWL_LASTEVT
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+#STAT REPORT
+#stat report shall be defined only if LINK STAT is defined
+  DHDCFLAGS += -DSTAT_REPORT
+#define temp static only when SDK doesn't support static memory for STAT REPORT
+#  DHDCFLAGS += -DSTAT_REPORT_TEMP_STATIC
+# Enable DHD_DUMP_MNGR
+  DHDCFLAGS += -DDHD_DUMP_MNGR
+endif
+
+# RSSI_SUM_REPORT is used over Android O OS only
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# RSSI Logging
+  DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
+# Enable NDO_CONFIG_SUPPORT in HAL
+  DHDCFLAGS += -DNDO_CONFIG_SUPPORT
+endif
+endif
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4361),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -452,7 +524,7 @@ ifneq ($(CONFIG_BCM4359),)
   DHDCFLAGS += -DMIMO_ANT_SETTING
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=4
+  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT=6
   DHDCFLAGS += -DSOFTAP_UAPSD_OFF
 # tput enhancement for common
   DHDCFLAGS += -DUSE_WL_TXBF
@@ -489,9 +561,13 @@ endif
   DHDCFLAGS += -DSUPPORT_LTECX
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
+  DHDCFLAGS += -DWL11ULB
  #DHDCFLAGS += -DSUPPORT_SENSORHUB
  # virtual interface for RSDB
   DHDCFLAGS += -DWL_VIRTUAL_APSTA
+ # virtual interface support for BCM4359 only
+  DHDCFLAGS += -DDHD_USE_CHECK_DONGLE_IDLE
+  DHDCFLAGS += -DDHD_ABORT_SCAN_CREATE_INTERFACE
  # disable pruned scan
   DHDCFLAGS += -DDISABLE_PRUNED_SCAN
  # Remove common feature for BCM4359
@@ -503,26 +579,68 @@ endif
  # Use restricted channels on STA/SoftAP concurrent mode
   DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
   DHDCFLAGS += -DDHD_LOG_DUMP
-# Random mac scan
-  DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN
-ifneq ($(CONFIG_WLAN_GRACE),)
-  DHDCFLAGS += -DWBTEXT
-endif
-ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_SOC_EXYNOS8890)),y)
+# To support CAC
+  DHDCFLAGS += -DSUPPORT_SET_CAC
+  DHDCFLAGS += -DSUPPORT_CUSTOM_SET_CAC
+# To support Enable EVENT SDB Transition log.
+  DHDCFLAGS += -DSUPPORT_EVT_SDB_LOG
+ifeq ($(filter y,$(CONFIG_ARCH_MSM8996) $(CONFIG_ARCH_MSM8998) $(CONFIG_SOC_EXYNOS8890) $(CONFIG_ARCH_TEGRA)),y)
  # Runtime PM
   DHDCFLAGS += -DDHD_PCIE_RUNTIMEPM -DMAX_IDLE_COUNT=11 -DCUSTOM_DHD_RUNTIME_MS=100
- # Enable Dongle Isolation
-  DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
+ # IRQ affinity setting for RX Load Balance
+ # DHDCFLAGS += -DDHD_LB_IRQSET
  # Disable SOFTAP_SEND_HANGEVT
   DHDCFLAGS := $(filter-out -DSOFTAP_SEND_HANGEVT,$(DHDCFLAGS))
+ # CLM
+  DHDCFLAGS += -DDHD_SUPPORT_GB_999
+ # Configure MU-MIMO capability
+ifeq ($(CONFIG_SOC_EXYNOS8890),y)
+  DHDCFLAGS += -DDYNAMIC_MUMIMO_CONTROL
+endif
+ifeq ($(CONFIG_ARCH_MSM8998),y)
+# Use SMMU for IOMEM
+  DHDCFLAGS += -DUSE_SMMU_ARCH_MSM
+  DHDCFLAGS += -DSET_DMA_MASK_64BIT
+endif
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO) $(CONFIG_SEC_HEROQLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_949
+endif
+
+ifeq ($(filter y,$(CONFIG_WLAN_HERO2) $(CONFIG_SEC_HERO2QLTE_PROJECT)),y)
+  DHDCFLAGS += -DDHD_SUPPORT_US_945
 endif
+# HANG simulation
+  DHDCFLAGS += -DDHD_HANG_SEND_UP_TEST
+
+ifeq ($(filter y,$(CONFIG_WLAN_GRACE) $(CONFIG_SEC_GRACEQLTE_PROJECT)),y)
+  # WBTEXT (11kv) feature
+  DHDCFLAGS += -DWBTEXT
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+endif
+
+ # RSDB mode from file config
+  DHDCFLAGS += -DRSDB_MODE_FROM_FILE
+ # LOGTRACE_EVENT
+  DHDCFLAGS += -DSHOW_LOGTRACE
+  DHDCFLAGS += -DLOGTRACE_FROM_FILE
+
+# Enable concate blob path
+    DHDCFLAGS += -DCONCATE_BLOB
+
+# For Samsung factory mode only
+ifeq ($(CONFIG_SEC_FACTORY),y)
+# Detect NON DMA M2M corruption
+  DHDCFLAGS += -DDHD_NON_DMA_M2M_CORRUPTION
+# Detect FW Memory Corruption
+  DHDCFLAGS += -DDHD_FW_MEM_CORRUPTION
+endif # CONFIG_SEC_FACTORY
 
 ifeq ($(CONFIG_BCM4359),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
-else
-  DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 endif
 endif
 
@@ -595,9 +713,6 @@ ifeq ($(CONFIG_BCM4358),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 ifneq ($(CONFIG_BCM4354),)
@@ -614,6 +729,7 @@ ifneq ($(CONFIG_BCM4354),)
 # tput enhancement for SDIO
 ifeq ($(BUS_IFACE_SDIO),y)
   DHDCFLAGS += -DHW_OOB
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
   DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
   DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
@@ -656,9 +772,6 @@ ifeq ($(CONFIG_BCM4354),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-ifeq ($(BUS_IFACE_SDIO),y)
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
 endif
 
 # Chipsets supported SDIO only
@@ -676,6 +789,7 @@ ifneq ($(CONFIG_BCM4339),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -705,11 +819,22 @@ ifeq ($(CONFIG_BCM4339),y)
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
 endif
 
+ifneq ($(CONFIG_BCM43456),)
+  DHDCFLAGS += -DBCM43456_CHIP
+  DHDCFLAGS += -DWLADPS_PRIVATE_CMD
+endif
 ifneq ($(CONFIG_BCM43455),)
-  DHDCFLAGS += -DBCM43455_CHIP -DHW_OOB
+  DHDCFLAGS += -DBCM43455_CHIP
+endif
+ifneq ($(CONFIG_BCM43454),)
+  DHDCFLAGS += -DBCM43454_CHIP
+endif
+
+# BCM43454/43455/43456 common difine.
+ifneq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)))
+  DHDCFLAGS += -DHW_OOB
   DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
   DHDCFLAGS += -DUSE_CID_CHECK
   DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
@@ -722,6 +847,7 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DDHDTCPACK_SUPPRESS
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
   DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
@@ -740,12 +866,11 @@ ifneq ($(CONFIG_BCM43455),)
   DHDCFLAGS += -DSUPPORT_2G_VHT
   DHDCFLAGS += -DSUPPORT_WL_TXPOWER
   DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43455),y)
+ifeq ($(filter y,$(CONFIG_BCM43454) $(CONFIG_BCM43455) $(CONFIG_BCM43456)),y)
   DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
   DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
   DRIVER_TYPE = y
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
   DHDCFLAGS += -DDHD_LOG_DUMP
 
   # FCC power limit control on ch12/13.
@@ -757,64 +882,38 @@ endif
   DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
   DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
+
+ifneq ($(filter y,$(CONFIG_BCM43455) $(CONFIG_BCM43456)),$(filter m,$(CONFIG_BCM43455) $(CONFIG_BCM43456)))
 # Enable Firmware Coredump
-  DHDCFLAGS += -DDHD_FW_COREDUMP
+    DHDCFLAGS += -DDHD_FW_COREDUMP
 ifeq ($(CONFIG_BCMDHD_PREALLOC_MEMDUMP),y)
-  DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+    DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
 endif
 
 # Enable concate blob path
-  DHDCFLAGS += -DCONCATE_BLOB
-endif
-
-ifneq ($(CONFIG_BCM43454),)
-  DHDCFLAGS += -DBCM43454_CHIP -DHW_OOB
-  DHDCFLAGS += -DSUPPORT_MULTIPLE_REVISION
-  DHDCFLAGS += -DUSE_CID_CHECK
-  DHDCFLAGS += -DENABLE_BCN_LI_BCN_WAKEUP
-  DHDCFLAGS += -DUSE_SDIOFIFO_IOVAR
+    DHDCFLAGS += -DCONCATE_BLOB
+# Generate .softap.info
+    DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
 
-  # tput enhancement
-  DHDCFLAGS += -DCUSTOM_GLOM_SETTING=8 -DCUSTOM_RXCHAIN=1
-  DHDCFLAGS += -DUSE_DYNAMIC_F2_BLKSIZE -DDYNAMIC_F2_BLKSIZE_FOR_NONLEGACY=128
-  DHDCFLAGS += -DBCMSDIOH_TXGLOM -DCUSTOM_TXGLOM=1 -DBCMSDIOH_TXGLOM_HIGHSPEED
-  DHDCFLAGS += -DDHDTCPACK_SUPPRESS
-  DHDCFLAGS += -DUSE_WL_TXBF
-  DHDCFLAGS += -DUSE_WL_FRAMEBURST
-  DHDCFLAGS += -DRXFRAME_THREAD
-  DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64 -DCUSTOM_IBSS_AMPDU_BA_WSIZE=16
-  DHDCFLAGS += -DCUSTOM_DPC_CPUCORE=0
-  DHDCFLAGS += -DPROP_TXSTATUS_VSDB
-
-  # New Features
-  DHDCFLAGS += -DWL11U -DMFP
-  DHDCFLAGS += -DBCMCCX
-  DHDCFLAGS += -DWES_SUPPORT
-  DHDCFLAGS += -DOKC_SUPPORT
-  DHDCFLAGS += -DWLTDLS -DWLTDLS_AUTO_ENABLE
-  DHDCFLAGS += -DWLFBT
-  DHDCFLAGS += -DDHD_ENABLE_LPC
-  DHDCFLAGS += -DWLAIBSS
-  DHDCFLAGS += -DSUPPORT_LTECX
-  DHDCFLAGS += -DSUPPORT_2G_VHT
-  DHDCFLAGS += -DSUPPORT_WL_TXPOWER
-  DHDCFLAGS += -DBCMCCX_S69
-ifeq ($(CONFIG_BCM43454),y)
-  DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
-  DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
-  DRIVER_TYPE = y
+ifneq ($(CONFIG_BCM43456),)
+# STA/SoftAP Concurrent Mode Support for legacy chip
+  DHDCFLAGS += -DWL_VIRTUAL_APSTA
+  DHDCFLAGS += -DWL_RESTRICTED_APSTA_SCC
+  DHDCFLAGS += -DSOFTAP_UAPSD_OFF
+  DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
+# Use restricted channels on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_RESTRICTED_CHANNEL
+# Block ARP during DHCP on STA/SoftAP concurrent mode
+  DHDCFLAGS += -DAPSTA_BLOCK_ARP_DURING_DHCP
+endif
 endif
-  DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-  DHDCFLAGS += -DDHD_LOG_DUMP
-
-  # FCC power limit control on ch12/13.
-  #   DHDCFLAGS += -DFCC_PWR_LIMIT_2G
-  #
-  # Enable Roam time thresh
-  DHDCFLAGS += -DENABLE_MAX_DTIM_IN_SUSPEND
-  DHDCFLAGS += -DCUSTOM_BCN_TIMEOUT_IN_SUSPEND=10
-  DHDCFLAGS += -DCUSTOM_ROAM_TIME_THRESH_IN_SUSPEND=6000
-  DHDCFLAGS += -DMAX_DTIM_ALLOWED_INTERVAL=925
 endif
 
 ifneq ($(CONFIG_BCM4335),)
@@ -831,6 +930,7 @@ ifneq ($(CONFIG_BCM4335),)
 # DHDCFLAGS += -DDHD_SET_FW_HIGHSPEED
   DHDCFLAGS += -DUSE_WL_TXBF
   DHDCFLAGS += -DUSE_WL_FRAMEBURST
+  DHDCFLAGS += -DCUSTOM_FRAMEBURST_SET=1
   DHDCFLAGS += -DRXFRAME_THREAD
   DHDCFLAGS += -DREPEAT_READFRAME
   DHDCFLAGS += -DCUSTOM_AMPDU_BA_WSIZE=64
@@ -948,6 +1048,15 @@ endif
   # Remove common feature for BCM4343
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DSUPPORT_P2P_GO_PS,$(DHDCFLAGS))
+# Generate .softap.info
+  DHDCFLAGS += -DGEN_SOFTAP_INFO_FILE
+ifneq ($(PLATFORM_VERSION),)
+# Android O OS use below features
+ifeq ($(shell expr $(PLATFORM_VERSION) \>= 8.0),1)
+# Use single nvram file
+  DHDCFLAGS += -DDHD_USE_SINGLE_NVRAM_FILE
+endif
+endif
 endif
 
 ifneq ($(CONFIG_BCM43012),)
@@ -983,6 +1092,8 @@ ifeq ($(CONFIG_SOLIS),y)
   DHDCFLAGS += -DPLATFORM_SLP
   DHDCFLAGS += -UCONFIG_HAS_WAKELOCK
   DHDCFLAGS += -UDHD_TRACE_WAKE_LOCK
+  DHDCFLAGS += -DDHD_USE_CLMINFO_PARSER
+  DHDCFLAGS += -DDISCARD_UDPNETBIOS
 endif
   # Remove common feature for 43012
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
@@ -1003,6 +1114,7 @@ endif
   DHDCFLAGS :=$(filter-out -DSUPPORT_AMPDU_MPDU_CMD,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DVSDB,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DPROP_TXSTATUS,$(DHDCFLAGS))
+  DHDCFLAGS :=$(filter-out -DLIMIT_BORROW,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DROAM_AP_ENV_DETECTION,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDHD_USE_IDLECOUNT,$(DHDCFLAGS))
   DHDCFLAGS :=$(filter-out -DDISABLE_11H_SOFTAP,$(DHDCFLAGS))
@@ -1092,6 +1204,7 @@ endif
 ifneq ($(CONFIG_MACH_EXSOM7420),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
+DHDCFLAGS += -DEXYNOS_PCIE_MODULE_PATCH
 obj-$(CONFIG_MACH_EXSOM7420) += dhd_custom_exynos.o dhd_custom_memprealloc.o
 endif
 ifneq ($(CONFIG_SOC_EXYNOS8890),)
@@ -1102,10 +1215,10 @@ DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -DBCMPCIE_OOB_HOST_WAKE
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5430),)
-obj-$(CONFIG_MACH_UNIVERSAL5430) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_MACH_UNIVERSAL5422),)
-obj-$(CONFIG_MACH_UNIVERSAL5422) += dhd_custom_exynos.o
+DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
 ifneq ($(CONFIG_ARCH_MSM8994),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
@@ -1128,6 +1241,10 @@ ifneq ($(CONFIG_SOC_EXYNOS7870),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 DHDCFLAGS += -Wno-date-time
 endif
+ifneq ($(CONFIG_SOC_EXYNOS7885),)
+DHDCFLAGS += -DDHD_OF_SUPPORT
+DHDCFLAGS += -Wno-date-time
+endif
 ifneq ($(CONFIG_SOC_EXYNOS7570),)
 DHDCFLAGS += -DDHD_OF_SUPPORT
 endif
@@ -1151,6 +1268,7 @@ DHDCFLAGS := $(filter-out -DDHD_ALLOC_COHERENT_MEM_FROM_ATOMIC_POOL,$(DHDCFLAGS)
 DHDCFLAGS := $(filter-out -DWL_VENDOR_EXT_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DGSCAN_SUPPORT,$(DHDCFLAGS))
 DHDCFLAGS := $(filter-out -DRTT_SUPPORT,$(DHDCFLAGS))
+DHDCFLAGS := $(filter-out -DDHD_LB_IRQSET,$(DHDCFLAGS))
 DHD_ANDROID_OFILES := $(filter-out wl_cfgvendor.o,$(DHD_ANDROID_OFILES))
 DHD_ANDROID_OFILES := $(filter-out dhd_rtt.o,$(DHD_ANDROID_OFILES))
 endif
@@ -1178,8 +1296,8 @@ DHDOFILES := dhd_pno.o dhd_common.o dhd_ip.o dhd_custom_gpio.o dhd_custom_sec.o
        bcmutils.o bcmwifi_channels.o hndpmu.o linux_osl.o sbutils.o siutils.o \
        wl_android.o wl_cfg80211.o wl_cfgp2p.o wl_cfg_btcoex.o wldev_common.o \
        wl_linux_mon.o wl_roam.o dhd_linux_platdev.o dhd_linux_wq.o wl_cfg_btcoex.o \
-       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o
-
+       hnd_pktq.o hnd_pktpool.o dhd_debug.o dhd_debug_linux.o dhd_custom_cis.o dhd_mschdbg.o \
+       dhd_pktlog.o
 
 ifeq ($(BUS_IFACE_SDIO),y)
 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o
@@ -1208,6 +1326,10 @@ ifeq ($(CONFIG_WL_NAN),y)
 # DHDOFILES += wl_cfgnan.o bcmxtlv.o
 endif
 
+ifneq ($(filter -DSTAT_REPORT,$(DHDCFLAGS)),)
+DHDOFILES += wl_statreport.o
+endif
+
 dhd-y := $(DHDOFILES)
 obj-$(DRIVER_TYPE)   += dhd.o
 
index f4df6da37b59ce20d1ac9b3ff1843b0956a4e51f..2259156c53b8318d8c25e32ffbd2aaaddf19f5e1 100644 (file)
@@ -2,7 +2,7 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index a5a7a5b23d3df54a0b5ff7c62c745a6efd847fa6..921582e9533e68d89ee993a792ed6bcc71ff171e 100644 (file)
@@ -3,7 +3,7 @@
  * Contents are wifi-specific, used by any kernel or app-level
  * software that might want wifi things as it grows.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 46f3554343366534f52a6349c478171e0157f840..92d409bb21ce4e2b6d9ea0f50c72a59045093f64 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bcmevent read-only data shared by kernel or app layers
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmevent.c 676811 2016-12-24 20:48:46Z $
+ * $Id: bcmevent.c 707287 2017-06-27 06:44:29Z $
  */
 
 #include <typedefs.h>
@@ -165,7 +165,6 @@ static const bcmevent_name_str_t bcmevent_names[] = {
 #endif /* WLAIBSS */
 #ifdef GSCAN_SUPPORT
        BCMEVENT_NAME(WLC_E_PFN_GSCAN_FULL_RESULT),
-       BCMEVENT_NAME(WLC_E_PFN_SWC),
        BCMEVENT_NAME(WLC_E_PFN_SSID_EXT),
 #endif /* GSCAN_SUPPORT */
 #ifdef WLBSSLOAD_REPORT
@@ -259,12 +258,14 @@ int
 is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
        bcm_event_msg_u_t *out_event)
 {
-       uint16 len;
+       uint16 evlen = 0;       /* length in bcmeth_hdr */
        uint16 subtype;
        uint16 usr_subtype;
        bcm_event_t *bcm_event;
        uint8 *pktend;
+       uint8 *evend;
        int err = BCME_OK;
+       uint32 data_len = 0; /* data length in bcm_event */
 
        pktend = (uint8 *)pktdata + pktlen;
        bcm_event = (bcm_event_t *)pktdata;
@@ -285,7 +286,17 @@ is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
        }
 
        /* check length in bcmeth_hdr */
-       len = ntoh16_ua((void *)&bcm_event->bcm_hdr.length);
+
+       /* temporary - header length not always set properly. When the below
+        * !BCMDONGLEHOST is in all branches that use trunk DHD, the code
+        * under BCMDONGLEHOST can be removed.
+        */
+       evlen = (uint16)(pktend - (uint8 *)&bcm_event->bcm_hdr.version);
+       evend = (uint8 *)&bcm_event->bcm_hdr.version + evlen;
+       if (evend != pktend) {
+               err = BCME_BADLEN;
+               goto done;
+       }
 
        /* match on subtype, oui and usr subtype for BRCM events */
        subtype = ntoh16_ua((void *)&bcm_event->bcm_hdr.subtype);
@@ -303,14 +314,17 @@ is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
        usr_subtype = ntoh16_ua((void *)&bcm_event->bcm_hdr.usr_subtype);
        switch (usr_subtype) {
        case BCMILCP_BCM_SUBTYPE_EVENT:
-               if (pktlen < sizeof(bcm_event_t)) {
+               /* check that header length and pkt length are sufficient */
+               if ((pktlen < sizeof(bcm_event_t)) ||
+                       (evend < ((uint8 *)bcm_event + sizeof(bcm_event_t)))) {
                        err = BCME_BADLEN;
                        goto done;
                }
 
-               len = (uint16)sizeof(bcm_event_t) +
-                       (uint16)ntoh32_ua((void *)&bcm_event->event.datalen);
-               if ((uint8 *)pktdata + len > pktend) {
+               /* ensure data length in event is not beyond the packet. */
+               data_len = ntoh32_ua((void *)&bcm_event->event.datalen);
+               if ((sizeof(bcm_event_t) + data_len +
+                       BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD) != pktlen) {
                        err = BCME_BADLEN;
                        goto done;
                }
@@ -329,14 +343,16 @@ is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
 
        case BCMILCP_BCM_SUBTYPE_DNGLEVENT:
 #if defined(DNGL_EVENT_SUPPORT)
-               if (pktlen < sizeof(bcm_dngl_event_t)) {
+               if ((pktlen < sizeof(bcm_dngl_event_t)) ||
+                       (evend < ((uint8 *)bcm_event + sizeof(bcm_dngl_event_t)))) {
                        err = BCME_BADLEN;
                        goto done;
                }
 
-               len = sizeof(bcm_dngl_event_t) +
-                       ntoh16_ua((void *)&((bcm_dngl_event_t *)pktdata)->dngl_event.datalen);
-               if ((uint8 *)pktdata + len > pktend) {
+               /* ensure data length in event is not beyond the packet. */
+               data_len = ntoh16_ua((void *)&((bcm_dngl_event_t *)pktdata)->dngl_event.datalen);
+               if ((sizeof(bcm_dngl_event_t) + data_len +
+                       BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD) != pktlen) {
                        err = BCME_BADLEN;
                        goto done;
                }
@@ -363,6 +379,7 @@ is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
                goto done;
        }
 
+       BCM_REFERENCE(data_len);
 done:
        return err;
 }
index eae09abf79b8a36baf675734711ea528e955ec08..e9a36fc8fab2f68922b7a8f1403a1dcd7cb263eb 100644 (file)
@@ -2,7 +2,7 @@
  *  BCMSDH interface glue
  *  implement bcmsdh API for SDIOH driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ce05e4475f7616b440c827609731a77d9cce5c72..6ab0bfa4a2515a8d997c850b9e8af57bbdb111bf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SDIO access interface for drivers - linux specific (pci only)
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 5670e4f2c45111b993ede5513e9b333a86096201..746fb08c4fcb85745111aa258d4430efe6e3aa4b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Proprietary,Open:>>
  *
- * $Id: bcmsdh_sdmmc.c 670926 2016-11-18 05:53:11Z $
+ * $Id: bcmsdh_sdmmc.c 731653 2017-11-14 03:29:19Z $
  */
 #include <typedefs.h>
 
@@ -58,6 +58,27 @@ mmc_host_clk_release(struct mmc_host *host)
 #else
 #include <linux/mmc/host.h>
 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 0, 0)) */
+
+#ifdef CONFIG_SOC_EXYNOS7885
+void
+mmc_host_clk_hold(struct mmc_host *host)
+{
+       BCM_REFERENCE(host);
+       return;
+}
+void
+mmc_host_clk_release(struct mmc_host *host)
+{
+       BCM_REFERENCE(host);
+       return;
+}
+unsigned int
+mmc_host_clk_rate(struct mmc_host *host)
+{
+       return host->ios.clock;
+}
+#endif /* CONFIG_SOC_EXYNOS7885 */
+
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
@@ -465,8 +486,6 @@ const bcm_iovar_t sdioh_iovars[] = {
        {"sd_ints",     IOV_USEINTS,    0, 0,   IOVT_BOOL,      0 },
        {"sd_numints",  IOV_NUMINTS,    0, 0,   IOVT_UINT32,    0 },
        {"sd_numlocalints", IOV_NUMLOCALINTS, 0, 0, IOVT_UINT32,        0 },
-       {"sd_hostreg",  IOV_HOSTREG,    0, 0,   IOVT_BUFFER,    sizeof(sdreg_t) },
-       {"sd_devreg",   IOV_DEVREG,     0, 0,   IOVT_BUFFER,    sizeof(sdreg_t) },
        {"sd_divisor",  IOV_DIVISOR,    0, 0,   IOVT_UINT32,    0 },
        {"sd_power",    IOV_POWER,      0, 0,   IOVT_UINT32,    0 },
        {"sd_clock",    IOV_CLOCK,      0, 0,   IOVT_UINT32,    0 },
@@ -686,74 +705,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name,
                int_val = (int32)0;
                bcopy(&int_val, arg, val_size);
                break;
-
-       case IOV_GVAL(IOV_HOSTREG):
-       {
-               sdreg_t *sd_ptr = (sdreg_t *)params;
-
-               if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
-                       sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
-                       bcmerror = BCME_BADARG;
-                       break;
-               }
-
-               sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__,
-                                 (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
-                                 sd_ptr->offset));
-               if (sd_ptr->offset & 1)
-                       int_val = 8; /* sdioh_sdmmc_rreg8(si, sd_ptr->offset); */
-               else if (sd_ptr->offset & 2)
-                       int_val = 16; /* sdioh_sdmmc_rreg16(si, sd_ptr->offset); */
-               else
-                       int_val = 32; /* sdioh_sdmmc_rreg(si, sd_ptr->offset); */
-
-               bcopy(&int_val, arg, sizeof(int_val));
-               break;
-       }
-
-       case IOV_SVAL(IOV_HOSTREG):
-       {
-               sdreg_t *sd_ptr = (sdreg_t *)params;
-
-               if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
-                       sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
-                       bcmerror = BCME_BADARG;
-                       break;
-               }
-
-               sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value,
-                                 (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
-                                 sd_ptr->offset));
-               break;
-       }
-
-       case IOV_GVAL(IOV_DEVREG):
-       {
-               sdreg_t *sd_ptr = (sdreg_t *)params;
-               uint8 data = 0;
-
-               if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
-                       bcmerror = BCME_SDIO_ERROR;
-                       break;
-               }
-
-               int_val = (int)data;
-               bcopy(&int_val, arg, sizeof(int_val));
-               break;
-       }
-
-       case IOV_SVAL(IOV_DEVREG):
-       {
-               sdreg_t *sd_ptr = (sdreg_t *)params;
-               uint8 data = (uint8)sd_ptr->value;
-
-               if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
-                       bcmerror = BCME_SDIO_ERROR;
-                       break;
-               }
-               break;
-       }
-
        default:
                bcmerror = BCME_UNSUPPORTED;
                break;
index 0563c47a93fc70274e711cd72229e066db98ee92..261bdf63eafb30b92fa0ac9ff2deae3597a561e2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 2353e025e8ad2fb9017b47a80bab0cf2da3e58cc..4bdafa7c2ef3817299bda6f9d91ee004b5866ba6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver O/S-independent utility routines
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmutils.c 676811 2016-12-24 20:48:46Z $
+ * $Id: bcmutils.c 699163 2017-05-12 05:18:23Z $
  */
 
 #include <bcm_cfg.h>
@@ -2320,7 +2320,7 @@ bcm_mkiovar(const char *name, const char *data, uint datalen, char *buf, uint bu
        strncpy(buf, name, buflen);
 
        /* append data onto the end of the name string */
-       if (data) {
+       if (data && datalen != 0) {
                memcpy(&buf[len], data, datalen);
                len += datalen;
        }
index 40fc3f7578fb4a7ce967620d3ba93208f8cb7e24..1aa375b26ff98bfa83867d3dd91513d140f1aed7 100644 (file)
@@ -3,7 +3,7 @@
  * Contents are wifi-specific, used by any kernel or app-level
  * software that might want wifi things as it grows.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 28c6e2739303cfa8f41416e954d00cf543540873..fa6a62169e09217c818dde13ff1e9dbdb731717d 100644 (file)
@@ -3,7 +3,7 @@
  * This header file housing the define and function prototype use by
  * both the wl driver, tools & Apps.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index fef0cc413c12efe24b90bd00fd07e4c0255fd654..c968ad63759203db320bb5ae9c44a4c14282870b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Indices for 802.11 a/b/g/n/ac 1-3 chain symmetric transmit rates
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index d6bef6fa2c37fe54503248e9684f9a2dad127a3e..097c62e21ff9e41d69786a1f9850777de264fd9f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver O/S-independent utility routines
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index d810a8799075c20de60eb6786d9a48633b51a1be..ca9a9d5c5850ea2fe8fbe7517c4af15f6cd0d75f 100644 (file)
@@ -4,7 +4,7 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd.h 685046 2017-02-15 08:10:34Z $
+ * $Id: dhd.h 752171 2018-03-15 02:55:35Z $
  */
 
 /****************
@@ -126,6 +126,7 @@ enum dhd_bus_state {
 #define DHD_BUS_BUSY_RPM_ALL                 (DHD_BUS_BUSY_RPM_SUSPEND_DONE | \
                DHD_BUS_BUSY_RPM_SUSPEND_IN_PROGRESS | \
                DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS)
+#define DHD_BUS_BUSY_IN_CHECKDIED            0x800
 
 #define DHD_BUS_BUSY_SET_IN_TX(dhdp) \
        (dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_TX
@@ -149,6 +150,8 @@ enum dhd_bus_state {
        (dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_RPM_SUSPEND_DONE
 #define DHD_BUS_BUSY_SET_RPM_RESUME_IN_PROGRESS(dhdp) \
        (dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS
+#define DHD_BUS_BUSY_SET_IN_CHECKDIED(dhdp) \
+       (dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_CHECKDIED
 
 #define DHD_BUS_BUSY_CLEAR_IN_TX(dhdp) \
        (dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_TX
@@ -172,6 +175,8 @@ enum dhd_bus_state {
        (dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_RPM_SUSPEND_DONE
 #define DHD_BUS_BUSY_CLEAR_RPM_RESUME_IN_PROGRESS(dhdp) \
        (dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS
+#define DHD_BUS_BUSY_CLEAR_IN_CHECKDIED(dhdp) \
+       (dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_CHECKDIED
 
 #define DHD_BUS_BUSY_CHECK_IN_TX(dhdp) \
        ((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_TX)
@@ -197,6 +202,8 @@ enum dhd_bus_state {
        ((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS)
 #define DHD_BUS_BUSY_CHECK_RPM_ALL(dhdp) \
        ((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RPM_ALL)
+#define DHD_BUS_BUSY_CHECK_IN_CHECKDIED(dhdp) \
+       ((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_CHECKDIED)
 #define DHD_BUS_BUSY_CHECK_IDLE(dhdp) \
                ((dhdp)->dhd_bus_busy_state == 0)
 
@@ -211,24 +218,15 @@ enum dhd_bus_state {
 #define DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp) \
                ((dhdp)->busstate == DHD_BUS_DOWN || (dhdp)->busstate == DHD_BUS_DOWN_IN_PROGRESS)
 
-/* Macro to print Ethernet Address as String
- * expects both arguements as (char *)
- */
-#define DHD_MAC_TO_STR(mac, str) (snprintf(str, ETHER_ADDR_STR_LEN, \
-                                       "%02x:%02x:%02x:%02x:%02x:%02x\n", \
-                                       (uchar)mac[0]&0xff, \
-                                       (uchar)mac[1]&0xff, \
-                                       (uchar)mac[2]&0xff, \
-                                       (uchar)mac[3]&0xff, \
-                                       (uchar)mac[4]&0xff, \
-                                       (uchar)mac[5]&0xff))
-
-
 /* Download Types */
 typedef enum download_type {
        FW,
        NVRAM,
-       CLM_BLOB
+       CLM_BLOB,
+#if defined(DHD_USE_CLMINFO_PARSER)
+       CLMINFO,
+#endif /* DHD_USE_CLMINFO_PARSER */
+       DOWNLOAD_TYPE_LAST
 } download_type_t;
 
 
@@ -260,6 +258,9 @@ enum dhd_op_flags {
 
 #define DHD_OPMODE_SUPPORTED(dhd, opmode_flag) \
        (dhd ? ((((dhd_pub_t *)dhd)->op_mode)  &  opmode_flag) : -1)
+#define DHD_OPMODE_STA_SOFTAP_CONCURR(dhd) \
+       (dhd ? (((((dhd_pub_t *)dhd)->op_mode) & DHD_FLAG_CONCURR_STA_HOSTAP_MODE) == \
+       DHD_FLAG_CONCURR_STA_HOSTAP_MODE) : 0)
 
 /* Max sequential TX/RX Control timeouts to set HANG event */
 #ifndef MAX_CNTL_TX_TIMEOUT
@@ -288,6 +289,7 @@ enum dhd_op_flags {
  */
 #define MAX_NVRAMBUF_SIZE      (16 * 1024) /* max nvram buf size */
 #define MAX_CLM_BUF_SIZE       (48 * 1024) /* max clm blob size */
+#define MAX_CLMINFO_BUF_SIZE    (4 * 1024) /* max clminfo buf size */
 #ifdef DHD_DEBUG
 #define DHD_JOIN_MAX_TIME_DEFAULT 10000 /* ms: Max time out for joining AP */
 #define DHD_SCAN_DEF_TIMEOUT 10000 /* ms: Max time out for scan in progress */
@@ -297,7 +299,7 @@ enum dhd_op_flags {
 #if defined(CUSTOMER_HW4) && defined(PLATFORM_SLP)
 #define CONFIG_BCMDHD_CLM_PATH "/lib/firmware/bcmdhd_clm.blob"
 #else
-#define CONFIG_BCMDHD_CLM_PATH "/system/etc/wifi/bcmdhd_clm.blob"
+#define CONFIG_BCMDHD_CLM_PATH "/etc/wifi/bcmdhd_clm.blob"
 #endif /* CUSTOMER_HW4 && PLATFORM_SLP */
 #endif /* CONFIG_BCMDHD_CLM_PATH */
 #define WL_CCODE_NULL_COUNTRY  "#n"
@@ -358,7 +360,9 @@ enum dhd_prealloc_index {
        DHD_PREALLOC_PKTID_MAP = 13,
        DHD_PREALLOC_PKTID_MAP_IOCTL = 14,
        DHD_PREALLOC_DHD_LOG_DUMP_BUF = 15,
-       DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX = 16
+       DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX = 16,
+       DHD_PREALLOC_DHD_PKTLOG_DUMP_BUF = 17,
+       DHD_PREALLOC_STAT_REPORT_BUF = 18
 };
 
 enum dhd_dongledump_mode {
@@ -391,6 +395,9 @@ enum dhd_dongledump_type {
        DUMP_TYPE_RESUMED_UNKNOWN,
        DUMP_TYPE_TRANS_ID_MISMATCH,
        DUMP_TYPE_HANG_ON_IFACE_OP_FAIL,
+#ifdef DEBUG_DNGL_INIT_FAIL
+       DUMP_TYPE_DONGLE_INIT_FAILURE,
+#endif /* DEBUG_DNGL_INIT_FAIL */
 #ifdef SUPPORT_LINKDOWN_RECOVERY
        DUMP_TYPE_READ_SHM_FAIL
 #endif /* SUPPORT_LINKDOWN_RECOVERY */
@@ -409,9 +416,12 @@ enum dhd_hang_reason {
        HANG_REASON_PCIE_PKTID_ERROR = 0x800A,
        HANG_REASON_PCIE_LINK_DOWN = 0x8805,
        HANG_REASON_INVALID_EVENT_OR_DATA = 0x8806,
-       HANG_REASON_MAX = 0x8807
+       HANG_REASON_UNKNOWN = 0x8807,
+       HANG_REASON_MAX = 0x8808
 };
 
+#define WLC_E_DEAUTH_MAX_REASON 0x0FFF
+
 enum dhd_rsdb_scan_features {
        /* Downgraded scan feature for AP active */
        RSDB_SCAN_DOWNGRADED_AP_SCAN = 0x01,
@@ -423,6 +433,13 @@ enum dhd_rsdb_scan_features {
        RSDB_SCAN_DOWNGRADED_CH_PRUNE_ALL  = 0x20
 };
 
+enum dhd_eapol_message_type {
+       EAPOL_4WAY_M1 = 1,
+       EAPOL_4WAY_M2,
+       EAPOL_4WAY_M3,
+       EAPOL_4WAY_M4
+};
+
 /* Packet alignment for most efficient SDIO (can change based on platform) */
 #ifndef DHD_SDALIGN
 #define DHD_SDALIGN    32
@@ -470,6 +487,23 @@ enum {
        TCPACK_SUP_HOLD,
        TCPACK_SUP_LAST_MODE
 };
+
+#ifdef ARGOS_CPU_SCHEDULER
+#define TCPACK_SUP_DEFAULT     TCPACK_SUP_OFF
+#ifdef BCMSDIO
+#define TCPACK_SUP_ON          TCPACK_SUP_DELAYTX
+#elif defined(BCMPCIE)
+#define TCPACK_SUP_ON          TCPACK_SUP_HOLD
+#else
+#define TCPACK_SUP_ON          TCPACK_SUP_OFF
+#endif /* BCMSDIO */
+#else
+#ifdef BCMSDIO
+#define TCPACK_SUP_DEFAULT     TCPACK_SUP_DELAYTX
+#elif defined(BCMPCIE)
+#define TCPACK_SUP_DEFAULT     TCPACK_SUP_OFF
+#endif /* BCMSDIO */
+#endif /* ARGOS_CPU_SCHEDULER */
 #endif /* DHDTCPACK_SUPPRESS */
 
 #if defined(TRAFFIC_MGMT_DWM)
@@ -575,8 +609,12 @@ extern void dhd_log_dump_write(int type, const char *fmt, ...);
 extern char *dhd_log_dump_get_timestamp(void);
 #endif /* DHD_LOG_DUMP */
 
+#define DHD_DEBUG_DUMP_TYPE    "debug_dump_USER"
+
 #if defined(CUSTOMER_HW4)
+#ifndef DHD_COMMON_DUMP_PATH
 #define DHD_COMMON_DUMP_PATH   "/data/media/wifi/log/"
+#endif /* !DHD_COMMON_DUMP_PATH */
 #else
 #define DHD_COMMON_DUMP_PATH   "/installmedia/"
 #endif /* CUSTOMER_HW4 */
@@ -619,6 +657,24 @@ struct module_metadata {
        u64 data_addr;  /* address of module data in host */
 };
 #endif
+
+#ifdef DMAMAP_STATS
+typedef struct dmamap_stats {
+       uint64 txdata;
+       uint64 txdata_sz;
+       uint64 rxdata;
+       uint64 rxdata_sz;
+       uint64 ioctl_rx;
+       uint64 ioctl_rx_sz;
+       uint64 event_rx;
+       uint64 event_rx_sz;
+       uint64 info_rx;
+       uint64 info_rx_sz;
+       uint64 tsbuf_rx;
+       uint64 tsbuf_rx_sz;
+} dma_stats_t;
+#endif /* DMAMAP_STATS */
+
 /* Common structure for module and instance linkage */
 typedef struct dhd_pub {
        /* Linkage ponters */
@@ -674,6 +730,11 @@ typedef struct dhd_pub {
        ulong tx_realloc;       /* Number of tx packets we had to realloc for headroom */
        ulong fc_packets;       /* Number of flow control pkts recvd */
 
+#ifdef DMAMAP_STATS
+       /* DMA Mapping statistics */
+       dma_stats_t dma_stats;
+#endif /* DMAMAP_STATS */
+
        /* Last error return */
        int bcmerror;
        uint tickcnt;
@@ -791,6 +852,9 @@ typedef struct dhd_pub {
 #if defined(DHD_HANG_SEND_UP_TEST)
        uint req_hang_type;
 #endif /* DHD_HANG_SEND_UP_TEST */
+#if defined(CONFIG_BCM_DETECT_CONSECUTIVE_HANG)
+       uint hang_counts;
+#endif /* CONFIG_BCM_DETECT_CONSECUTIVE_HANG */
 #ifdef WLTDLS
        bool tdls_enable;
 #endif
@@ -898,10 +962,10 @@ typedef struct dhd_pub {
        char    *cached_clm;
        int     cached_clm_length;
 #endif
-#ifdef KEEP_JP_REGREV
+#if defined(KEEP_KR_REGREV) || defined(KEEP_JP_REGREV)
        char vars_ccode[WLC_CNTRY_BUF_SZ];
        uint vars_regrev;
-#endif /* KEEP_JP_REGREV */
+#endif /* KEEP_KR_REGREV || KEEP_JP_REGREV */
 #ifdef WLTDLS
        uint32 tdls_mode;
 #endif
@@ -932,9 +996,9 @@ typedef struct dhd_pub {
        /* timesync link */
        struct dhd_ts *ts;
        bool    d2h_hostrdy_supported;
-#ifdef DBG_PKT_MON
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
        bool d11_tx_status;
-#endif /* DBG_PKT_MON */
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
        uint16 ndo_version;             /* ND offload version supported */
 #ifdef NDO_CONFIG_SUPPORT
        bool ndo_enable;                /* ND offload feature enable */
@@ -980,6 +1044,22 @@ typedef struct dhd_pub {
 #endif /* WLADPS_SEAK_AP_WAR */
        bool ext_trap_data_supported;
        uint32 *extended_trap_data;
+#ifdef DHD_PKT_LOGGING
+       struct dhd_pktlog *pktlog;
+#endif /* DHD_PKT_LOGGING */
+#if defined(STAT_REPORT)
+       void *stat_report_info;
+#endif
+#ifdef DHD_DUMP_MNGR
+       struct _dhd_dump_file_manage *dump_file_manage;
+#endif /* DHD_DUMP_MNGR */
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       uint8 reassoc_mumimo_sw;
+       uint8 murx_block_eapol;
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+#ifdef DHD_USE_CLMINFO_PARSER
+       bool is_clm_mult_regrev;        /* Checking for CLM single/multiple regrev */
+#endif /* DHD_USE_CLMINFO_PARSER */
 } dhd_pub_t;
 
 typedef struct {
@@ -1329,7 +1409,8 @@ typedef enum dhd_attach_states
        DHD_ATTACH_STATE_EARLYSUSPEND_DONE = 0x100,
        DHD_ATTACH_TIMESYNC_ATTACH_DONE = 0x200,
        DHD_ATTACH_LOGTRACE_INIT = 0x400,
-       DHD_ATTACH_STATE_DONE = 0x800
+       DHD_ATTACH_STATE_LB_ATTACH_DONE = 0x800,
+       DHD_ATTACH_STATE_DONE = 0x1000
 } dhd_attach_states_t;
 
 /* Value -1 means we are unsuccessful in creating the kthread. */
@@ -1367,13 +1448,7 @@ extern void dhd_store_conn_status(uint32 event, uint32 status, uint32 reason);
 
 extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec);
 
-#ifdef DHD_WAKE_STATUS
-/* Receive frame for delivery to OS.  Callee disposes of rxp. */
-extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt, uint8 chan,
-       int pkt_wake, wake_counts_t *wcp);
-#else
 extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt, uint8 chan);
-#endif /* DHD_WAKE_STATUS */
 
 /* Return pointer to interface name */
 extern char *dhd_ifname(dhd_pub_t *dhdp, int idx);
@@ -1542,8 +1617,13 @@ void dhd_schedule_sssr_dump(dhd_pub_t *dhdp);
 #define DHD_ARP_FILTER_NUM             5
 #define DHD_BROADCAST_ARP_FILTER_NUM   6
 #define DHD_IP4BCAST_DROP_FILTER_NUM   7
+#define DHD_CISCO_STP_DROP_FILTER_NUM  8
+#define DHD_CISCO_XID_DROP_FILTER_NUM  9
+#define DHD_UDPNETBIOS_DROP_FILTER_NUM 10
 #define DISCARD_IPV4_MCAST     "102 1 6 IP4_H:16 0xf0 0xe0"
 #define DISCARD_IPV6_MCAST     "103 1 6 IP6_H:24 0xff 0xff"
+#define DISCARD_IPV4_BCAST     "107 1 6 IP4_H:16 0xffffffff 0xffffffff"
+#define DISCARD_UDPNETBIOS     "110 1 6 UDP_H:2 0xffff 0x0089"
 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 dhd_packet_filter_add_remove(dhd_pub_t *dhdp, int add_remove, int num);
@@ -1604,6 +1684,30 @@ typedef struct {
 } dhd_event_log_t;
 #endif /* SHOW_LOGTRACE */
 
+#if defined(DHD_NON_DMA_M2M_CORRUPTION)
+#define PCIE_DMAXFER_LPBK_LENGTH       4096
+typedef struct dhd_pcie_dmaxfer_lpbk {
+       union {
+               uint32  length;
+               uint32  status;
+       } u;
+       uint32  srcdelay;
+       uint32  destdelay;
+       uint32  lpbkmode;
+       uint32  wait;
+       uint32  core;
+} dhd_pcie_dmaxfer_lpbk_t;
+#endif /* DHD_NON_DMA_M2M_CORRUPTION */
+enum d11_lpbk_type {
+       M2M_DMA_LPBK = 0,
+       D11_LPBK = 1,
+       BMC_LPBK = 2,
+       M2M_NON_DMA_LPBK = 3,
+       D11_HOST_MEM_LPBK = 4,
+       BMC_HOST_MEM_LPBK = 5,
+       MAX_LPBK = 6
+};
+
 #ifdef KEEP_ALIVE
 extern int dhd_dev_start_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id, uint8 *ip_pkt,
        uint16 ip_pkt_len, uint8* src_mac_addr, uint8* dst_mac_addr, uint32 period_msec);
@@ -1693,6 +1797,7 @@ extern uint dhd_bus_chip_id(dhd_pub_t *dhdp);
 extern uint dhd_bus_chiprev_id(dhd_pub_t *dhdp);
 extern uint dhd_bus_chippkg_id(dhd_pub_t *dhdp);
 #endif /* defined(BCMSDIO) || defined(BCMPCIE) */
+int dhd_bus_get_fw_mode(dhd_pub_t *dhdp);
 
 #if defined(KEEP_ALIVE)
 extern int dhd_keep_alive_onoff(dhd_pub_t *dhd);
@@ -1723,6 +1828,8 @@ extern int dhd_os_busbusy_wait_condition(dhd_pub_t *pub, uint *var, uint conditi
 extern int dhd_os_busbusy_wait_negation(dhd_pub_t * pub, uint * condition);
 extern int dhd_os_d3ack_wait(dhd_pub_t * pub, uint * condition);
 extern int dhd_os_d3ack_wake(dhd_pub_t * pub);
+extern int dhd_os_dmaxfer_wait(dhd_pub_t *pub, uint *condition);
+extern int dhd_os_dmaxfer_wake(dhd_pub_t *pub);
 
 /*
  * Manage sta objects in an interface. Interface is identified by an ifindex and
@@ -1740,7 +1847,8 @@ extern int dhd_bssidx2idx(dhd_pub_t *dhdp, uint32 bssidx);
 extern struct net_device *dhd_linux_get_primary_netdev(dhd_pub_t *dhdp);
 
 extern bool dhd_is_concurrent_mode(dhd_pub_t *dhd);
-extern int dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set);
+int dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *param_buf, uint param_len,
+               char *res_buf, uint res_len, int set);
 extern int dhd_getiovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf,
                uint cmd_len, char **resptr, uint resp_len);
 
@@ -1908,6 +2016,15 @@ extern uint dhd_force_tx_queueing;
 #define CUSTOM_ASSOC_RETRY_MAX                 DEFAULT_ASSOC_RETRY_MAX
 #endif /* DEFAULT_ASSOC_RETRY_MAX */
 
+#if defined(BCMSDIO) || defined(DISABLE_FRAMEBURST)
+#define DEFAULT_FRAMEBURST_SET                 0
+#else
+#define DEFAULT_FRAMEBURST_SET                 1
+#endif /* BCMSDIO */
+
+#ifndef CUSTOM_FRAMEBURST_SET
+#define CUSTOM_FRAMEBURST_SET                  DEFAULT_FRAMEBURST_SET
+#endif /* CUSTOM_FRAMEBURST_SET */
 
 #ifdef WLTDLS
 #ifndef CUSTOM_TDLS_IDLE_MODE_SETTING
@@ -1960,6 +2077,19 @@ extern uint dhd_pktgen_len;
 extern char fw_path2[MOD_PARAM_PATHLEN];
 #endif
 
+#if defined(ANDROID_PLATFORM_VERSION)
+#if (ANDROID_PLATFORM_VERSION < 7)
+#define DHD_LEGACY_FILE_PATH
+#define VENDOR_PATH "/system"
+#elif (ANDROID_PLATFORM_VERSION == 7)
+#define VENDOR_PATH "/system"
+#elif (ANDROID_PLATFORM_VERSION >= 8)
+#define VENDOR_PATH "/vendor"
+#endif /* ANDROID_PLATFORM_VERSION < 7 */
+#else
+#define VENDOR_PATH ""
+#endif /* ANDROID_PLATFORM_VERSION */
+
 #ifdef DHD_LEGACY_FILE_PATH
 #define PLATFORM_PATH  "/data/"
 #elif defined(PLATFORM_SLP)
@@ -2008,6 +2138,7 @@ static INLINE int dhd_check_module_mac(dhd_pub_t *dhdp) { return 0; }
 int dhd_read_cis(dhd_pub_t *dhdp);
 void dhd_clear_cis(dhd_pub_t *dhdp);
 #if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK)
+bool dhd_check_module(char *module_name);
 extern int dhd_check_module_b85a(void);
 extern int dhd_check_module_b90(void);
 #define BCM4359_MODULE_TYPE_B90B 1
@@ -2184,6 +2315,12 @@ extern void dhd_os_general_spin_unlock(dhd_pub_t *pub, unsigned long flags);
 #define DHD_TDLS_UNLOCK(lock, flags)     dhd_os_spin_unlock((lock), (flags))
 #endif /* WLTDLS */
 
+#ifdef DBG_PKT_MON
+/* Enable DHD PKT MON spin lock/unlock */
+#define DHD_PKT_MON_LOCK(lock, flags)     (flags) = dhd_os_spin_lock(lock)
+#define DHD_PKT_MON_UNLOCK(lock, flags)   dhd_os_spin_unlock(lock, (flags))
+#endif /* DBG_PKT_MON */
+
 #define DHD_LINUX_GENERAL_LOCK(dhdp, flags)    DHD_GENERAL_LOCK(dhdp, flags)
 #define DHD_LINUX_GENERAL_UNLOCK(dhdp, flags)  DHD_GENERAL_UNLOCK(dhdp, flags)
 
@@ -2249,6 +2386,10 @@ int dhd_download_blob(dhd_pub_t *dhd, unsigned char *image,
                uint32 len, char *iovar);
 
 int dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path);
+#ifdef DHD_USE_CLMINFO_PARSER
+int dhd_get_clminfo(dhd_pub_t *dhd, char *clm_path);
+#define NUM_OF_COUNTRYS 150
+#endif /* DHD_USE_CLMINFO_PARSER */
 
 #ifdef SHOW_LOGTRACE
 int dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size,
@@ -2321,6 +2462,9 @@ extern void dhd_lb_stats_rxc_percpu_cnt_incr(dhd_pub_t *dhdp);
 #define DHD_LB_STATS_TXC_PERCPU_CNT_INCR(dhdp) DHD_LB_STATS_NOOP
 #define DHD_LB_STATS_RXC_PERCPU_CNT_INCR(dhdp) DHD_LB_STATS_NOOP
 #endif /* !DHD_LB_STATS */
+#ifdef DHD_LB_IRQSET
+extern void dhd_irq_set_affinity(dhd_pub_t *dhdp);
+#endif /* DHD_LB_IRQSET */
 
 #ifdef DHD_SSSR_DUMP
 #define DHD_SSSR_MEMPOOL_SIZE  (1024 * 1024) /* 1MB size */
@@ -2455,6 +2599,8 @@ int dhd_send_msg_to_daemon(struct sk_buff *skb, void *data, int size);
 void dhd_send_trap_to_fw_for_timeout(dhd_pub_t * pub, timeout_reasons_t reason);
 #endif
 
+extern void dhd_prhex(const char *msg, volatile uchar *buf, uint nbytes, uint8 dbg_level);
+
 #if defined(CONFIG_64BIT)
 #define DHD_SUPPORT_64BIT
 #elif defined(DHD_EFI)
@@ -2474,4 +2620,56 @@ extern void dhd_make_hang_with_reason(struct net_device *dev, const char *string
 extern void dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path);
 #endif /* DHD_BLOB_EXISTENCE_CHECK */
 
+#ifdef DHD_WAKE_STATUS
+wake_counts_t* dhd_get_wakecount(dhd_pub_t *dhdp);
+#endif /* DHD_WAKE_STATUS */
+
+#ifdef BCM_ASLR_HEAP
+extern uint32 dhd_get_random_number(void);
+#endif /* BCM_ASLR_HEAP */
+
+#define DHD_DUMP_TYPE_NAME_SIZE                32
+#define DHD_DUMP_FILE_PATH_SIZE                256
+#define DHD_DUMP_FILE_COUNT_MAX                5
+#define DHD_DUMP_TYPE_COUNT_MAX                10
+
+#ifdef DHD_DUMP_MNGR
+typedef struct _DFM_elem {
+       char type_name[DHD_DUMP_TYPE_NAME_SIZE];
+       char file_path[DHD_DUMP_FILE_COUNT_MAX][DHD_DUMP_FILE_PATH_SIZE];
+       int file_idx;
+} DFM_elem_t;
+
+typedef struct _dhd_dump_file_manage {
+       DFM_elem_t elems[DHD_DUMP_TYPE_COUNT_MAX];
+} dhd_dump_file_manage_t;
+
+extern void dhd_dump_file_manage_enqueue(dhd_pub_t *dhd, char *dump_path, char *fname);
+#endif /* DHD_DUMP_MNGR */
+
+int dhd_check_eapol_4way_message(char *dump_data);
+#ifdef DYNAMIC_MUMIMO_CONTROL
+#ifdef ARGOS_CPU_SCHEDULER
+void argos_config_mumimo_reset(void);
+#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+#if defined(BCMSDIO) || defined(BCMPCIE)
+extern uint dhd_get_chip_id(dhd_pub_t *dhdp);
+extern uint dhd_get_chiprev_id(dhd_pub_t *dhdp);
+#endif /* BCMSDIO || BCMPCIE */
+
+#if defined(DHD_BLOB_EXISTENCE_CHECK) && defined(DHD_USE_CLMINFO_PARSER)
+#define CHECK_IS_BLOB(dhdp)            (dhdp)->is_blob
+#define CHECK_IS_MULT_REGREV(dhdp)     (dhdp)->is_clm_mult_regrev
+#elif defined(DHD_BLOB_EXISTENCE_CHECK) && !defined(DHD_USE_CLMINFO_PARSER)
+#define CHECK_IS_BLOB(dhdp)            (dhdp)->is_blob
+#define CHECK_IS_MULT_REGREV(dhdp)     FALSE
+#elif !defined(DHD_BLOB_EXISTENCE_CHECK) && defined(DHD_USE_CLMINFO_PARSER)
+#define CHECK_IS_BLOB(dhdp)            TRUE
+#define CHECK_IS_MULT_REGREV(dhdp)     (dhdp)->is_clm_mult_regrev
+#else /* !DHD_BLOB_EXISTENCE_CHECK && !DHD_USE_CLMINFO_PARSER */
+#define CHECK_IS_BLOB(dhdp)            FALSE
+#define CHECK_IS_MULT_REGREV(dhdp)     TRUE
+#endif /* DHD_BLOB_EXISTENCE_CHECK && DHD_USE_CLMINFO_PARSER */
+
 #endif /* _dhd_h_ */
index 4d6551d89e97219566282d64adf26016c23eabae..5266c305fdf8ef826b027e55084721a6932e6bc6 100644 (file)
@@ -4,7 +4,7 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_bus.h 683604 2017-02-08 11:19:43Z $
+ * $Id: dhd_bus.h 698895 2017-05-11 02:55:17Z $
  */
 
 #ifndef _dhd_bus_h_
@@ -197,14 +197,7 @@ extern void dhd_bus_ringbell(struct dhd_bus *bus, uint32 value);
 extern void dhd_bus_ringbell_2(struct dhd_bus *bus, uint32 value, bool devwake);
 extern void dhd_bus_cmn_readshared(struct dhd_bus *bus, void* data, uint8 type, uint16 ringid);
 extern uint32 dhd_bus_get_sharedflags(struct dhd_bus *bus);
-
-#ifdef DHD_WAKE_STATUS
-extern void dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count,
-       int pkt_wake);
-#else
 extern void dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count);
-#endif /* DHD_WAKE_STATUS */
-
 extern void dhd_bus_start_queue(struct dhd_bus *bus);
 extern void dhd_bus_stop_queue(struct dhd_bus *bus);
 extern dhd_mb_ring_t dhd_bus_get_mbintr_fn(struct dhd_bus *bus);
@@ -290,4 +283,8 @@ extern uint16 dhd_get_chipid(dhd_pub_t *dhd);
 
 extern int dhd_get_idletime(dhd_pub_t *dhd);
 
+#ifdef DHD_WAKE_STATUS
+extern wake_counts_t* dhd_bus_get_wakecount(dhd_pub_t *dhd);
+extern int dhd_bus_get_bus_wake(dhd_pub_t * dhd);
+#endif /* DHD_WAKE_STATUS */
 #endif /* _dhd_bus_h_ */
index 34b7a58b87e4e6c807e6ea4b42392ba491076666..d48c4630d06dcbc077b401d2d3f1248ae6695983 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DHD Protocol Module for CDC and BDC.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_cdc.c 671577 2016-11-22 10:31:40Z $
+ * $Id: dhd_cdc.c 699163 2017-05-12 05:18:23Z $
  *
  * BDC is like CDC, except it includes a header for data packets to convey
  * packet priority over the bus, and flags (e.g. to indicate checksum status
index e564545a0a875e3ac323e52db560abbe8d166b83..f9a2f742a95886aa1cdbbd191012a611640fceea 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver - Dongle Host Driver (DHD) related
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_cfg80211.c 676977 2016-12-27 17:27:09Z $
+ * $Id: dhd_cfg80211.c 699163 2017-05-12 05:18:23Z $
  */
 
 #include <linux/vmalloc.h>
@@ -171,7 +171,7 @@ wl_dongle_up(struct net_device *ndev)
        s32 err = 0;
        u32 local_up = 0;
 
-       err = wldev_ioctl(ndev, WLC_UP, &local_up, sizeof(local_up), true);
+       err = wldev_ioctl_set(ndev, WLC_UP, &local_up, sizeof(local_up));
        if (unlikely(err)) {
                WL_ERR(("WLC_UP error (%d)\n", err));
        }
@@ -184,7 +184,7 @@ wl_dongle_down(struct net_device *ndev)
        s32 err = 0;
        u32 local_down = 0;
 
-       err = wldev_ioctl(ndev, WLC_DOWN, &local_down, sizeof(local_down), true);
+       err = wldev_ioctl_set(ndev, WLC_DOWN, &local_down, sizeof(local_down));
        if (unlikely(err)) {
                WL_ERR(("WLC_DOWN error (%d)\n", err));
        }
index 20923ce5fda823315afba6f1a0c8d2cab40810a8..7a0fac8fb8396c538022a3e9289a4051be28621f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver - Dongle Host Driver (DHD) related
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index daf648804f00cfe245ff616c8cca4bd1f1b21c95..5481657a5e0cda638d99e3ff304cbdc54bd79fca 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom Dongle Host Driver (DHD), common DHD core.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_common.c 684400 2017-02-13 07:55:10Z $
+ * $Id: dhd_common.c 751393 2018-03-12 07:48:00Z $
  */
 #include <typedefs.h>
 #include <osl.h>
@@ -110,7 +110,8 @@ extern int is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype
 
 #if defined(CUSTOMER_HW4)
 /* For CUSTOMER_HW4 do not enable DHD_EVENT_VAL and DHD_ERROR_MEM_VAL */
-int dhd_msg_level = DHD_ERROR_VAL | DHD_MSGTRACE_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL;
+int dhd_msg_level = DHD_ERROR_VAL | DHD_MSGTRACE_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL |
+       DHD_PKT_MON_VAL;
 #else
 /* By default all logs are enabled */
 int dhd_msg_level = DHD_ERROR_VAL | DHD_MSGTRACE_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL |
@@ -447,19 +448,22 @@ dhd_sssr_mempool_deinit(dhd_pub_t *dhd)
 int
 dhd_get_sssr_reg_info(dhd_pub_t *dhd)
 {
-       int ret;
+       int ret = BCME_ERROR;
+
+       DHD_ERROR(("%s: get sssr_reg_info\n", __FUNCTION__));
        /* get sssr_reg_info from firmware */
        memset((void *)&dhd->sssr_reg_info, 0, sizeof(dhd->sssr_reg_info));
-       bcm_mkiovar("sssr_reg_info", 0, 0, (char *)&dhd->sssr_reg_info,
-               sizeof(dhd->sssr_reg_info));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, &dhd->sssr_reg_info,
-               sizeof(dhd->sssr_reg_info), FALSE, 0)) < 0) {
-               DHD_ERROR(("%s: sssr_reg_info failed (error=%d)\n",
-                       __FUNCTION__, ret));
-               return BCME_ERROR;
+       if (bcm_mkiovar("sssr_reg_info", 0, 0, (char *)&dhd->sssr_reg_info,
+               sizeof(dhd->sssr_reg_info))) {
+               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, &dhd->sssr_reg_info,
+                       sizeof(dhd->sssr_reg_info), FALSE, 0)) < 0) {
+                       DHD_ERROR(("%s: dhd_wl_ioctl_cmd failed (error=%d)\n", __FUNCTION__, ret));
+               }
+       } else {
+                       DHD_ERROR(("%s: bcm_mkiovar failed\n", __FUNCTION__));
        }
 
-       return BCME_OK;
+       return ret;
 }
 
 uint32
@@ -633,8 +637,8 @@ dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
                    dhdp->up, dhdp->txoff, dhdp->busstate);
        bcm_bprintf(strbuf, "pub.hdrlen %u pub.maxctl %u pub.rxsz %u\n",
                    dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz);
-       bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %s\n",
-                   dhdp->iswl, dhdp->drv_version, bcm_ether_ntoa(&dhdp->mac, eabuf));
+       bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac "MACDBG"\n",
+                   dhdp->iswl, dhdp->drv_version, MAC2STRDBG(bcm_ether_ntoa(&dhdp->mac, eabuf)));
        bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %u\n", dhdp->bcmerror, dhdp->tickcnt);
 
        bcm_bprintf(strbuf, "dongle stats:\n");
@@ -661,6 +665,27 @@ dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
                    dhdp->tx_pktgetfail, dhdp->rx_pktgetfail);
        bcm_bprintf(strbuf, "\n");
 
+#ifdef DMAMAP_STATS
+       /* Add DMA MAP info */
+       bcm_bprintf(strbuf, "DMA MAP stats: \n");
+       bcm_bprintf(strbuf, "txdata: %lu size: %luK, rxdata: %lu size: %luK\n",
+                       dhdp->dma_stats.txdata, KB(dhdp->dma_stats.txdata_sz),
+                       dhdp->dma_stats.rxdata, KB(dhdp->dma_stats.rxdata_sz));
+#ifndef IOCTLRESP_USE_CONSTMEM
+       bcm_bprintf(strbuf, "IOCTL RX: %lu size: %luK ,",
+                       dhdp->dma_stats.ioctl_rx, KB(dhdp->dma_stats.ioctl_rx_sz));
+#endif /* !IOCTLRESP_USE_CONSTMEM */
+       bcm_bprintf(strbuf, "EVENT RX: %lu size: %luK, INFO RX: %lu size: %luK, "
+                       "TSBUF RX: %lu size %luK\n",
+                       dhdp->dma_stats.event_rx, KB(dhdp->dma_stats.event_rx_sz),
+                       dhdp->dma_stats.info_rx, KB(dhdp->dma_stats.info_rx_sz),
+                       dhdp->dma_stats.tsbuf_rx, KB(dhdp->dma_stats.tsbuf_rx_sz));
+       bcm_bprintf(strbuf, "Total : %luK \n",
+                       KB(dhdp->dma_stats.txdata_sz + dhdp->dma_stats.rxdata_sz +
+                       dhdp->dma_stats.ioctl_rx_sz + dhdp->dma_stats.event_rx_sz +
+                       dhdp->dma_stats.tsbuf_rx_sz));
+#endif /* DMAMAP_STATS */
+
        /* Add any prot info */
        dhd_prot_dump(dhdp, strbuf);
        bcm_bprintf(strbuf, "\n");
@@ -712,7 +737,7 @@ dhd_wl_ioctl_get_intiovar(dhd_pub_t *dhd_pub, char *name, uint *pval,
        char iovbuf[WLC_IOCTL_SMLEN];
        int ret = -1;
 
-       /* memset(iovbuf, 0, sizeof(iovbuf)); */
+       memset(iovbuf, 0, sizeof(iovbuf));
        if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
                ret = dhd_wl_ioctl_cmd(dhd_pub, cmd, iovbuf, sizeof(iovbuf), set, ifidx);
                if (!ret) {
@@ -733,13 +758,15 @@ int
 dhd_wl_ioctl_set_intiovar(dhd_pub_t *dhd_pub, char *name, uint val,
        int cmd, uint8 set, int ifidx)
 {
-       char iovbuf[WLC_IOCTL_SMLEN];
+       char iovbuf[WLC_IOCTL_SMLEN] = {0};
        int ret = -1;
        int lval = htol32(val);
+       uint len;
 
-       /* memset(iovbuf, 0, sizeof(iovbuf)); */
-       if (bcm_mkiovar(name, (char*)&lval, sizeof(lval), iovbuf, sizeof(iovbuf))) {
-               ret = dhd_wl_ioctl_cmd(dhd_pub, cmd, iovbuf, sizeof(iovbuf), set, ifidx);
+       len = bcm_mkiovar(name, (char*)&lval, sizeof(lval), iovbuf, sizeof(iovbuf));
+
+       if (len) {
+               ret = dhd_wl_ioctl_cmd(dhd_pub, cmd, iovbuf, len, set, ifidx);
                if (ret) {
                        DHD_ERROR(("%s: set int iovar %s failed, ERR %d\n",
                                __FUNCTION__, name, ret));
@@ -780,14 +807,15 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
        if (dhd_os_proto_block(dhd_pub))
        {
 #ifdef DHD_LOG_DUMP
-               int slen, i, val, rem, lval;
-               char *pval, *pos, *msg;
-               char tmp[64];
+               int slen, val, lval, min_len;
+               char *msg, tmp[64];
 
                /* WLC_GET_VAR */
                if (ioc->cmd == WLC_GET_VAR) {
+                       min_len = MIN(sizeof(tmp) - 1, strlen(buf));
                        memset(tmp, 0, sizeof(tmp));
-                       bcopy(ioc->buf, tmp, strlen(ioc->buf) + 1);
+                       bcopy(buf, tmp, min_len);
+                       tmp[min_len] = '\0';
                }
 #endif /* DHD_LOG_DUMP */
                DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
@@ -845,38 +873,31 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
 #ifdef DHD_LOG_DUMP
                if (ioc->cmd == WLC_GET_VAR || ioc->cmd == WLC_SET_VAR) {
                        lval = 0;
-                       slen = strlen(ioc->buf) + 1;
-                       msg = (char*)ioc->buf;
-                       if (ioc->cmd == WLC_GET_VAR) {
-                               msg = tmp;
-                               lval = *(int*)ioc->buf;
-                       } else {
-                               int min_len = MIN(ioc->len - slen, sizeof(int));
-                               bcopy((msg + slen), &lval, min_len);
+                       slen = strlen(buf) + 1;
+                       msg = (char*)buf;
+                       if (len >= slen + sizeof(lval)) {
+                               if (ioc->cmd == WLC_GET_VAR) {
+                                       msg = tmp;
+                                       lval = *(int*)buf;
+                               } else {
+                                       min_len = MIN(ioc->len - slen, sizeof(int));
+                                       bcopy((msg + slen), &lval, min_len);
+                               }
+                       }
+                       if (!strncmp(msg, "cur_etheraddr", strlen("cur_etheraddr"))) {
+                               lval = 0;
                        }
                        DHD_ERROR_MEM(("%s: cmd: %d, msg: %s, val: 0x%x, len: %d, set: %d\n",
                                ioc->cmd == WLC_GET_VAR ? "WLC_GET_VAR" : "WLC_SET_VAR",
                                ioc->cmd, msg, lval, ioc->len, ioc->set));
                } else {
                        slen = ioc->len;
-                       if (ioc->buf != NULL) {
-                               val = *(int*)ioc->buf;
-                               pval = (char*)ioc->buf;
-                               pos = tmp;
-                               rem = sizeof(tmp);
-                               memset(tmp, 0, sizeof(tmp));
-                               for (i = 0; i < slen; i++) {
-                                       pos += snprintf(pos, rem, "%02x ", pval[i]);
-                                       rem = sizeof(tmp) - (int)(pos - tmp);
-                                       if (rem <= 0) {
-                                               break;
-                                       }
-                               }
+                       if (buf != NULL) {
+                               val = *(int*)buf;
                                /* Do not dump for WLC_GET_MAGIC and WLC_GET_VERSION */
                                if (ioc->cmd != WLC_GET_MAGIC && ioc->cmd != WLC_GET_VERSION)
-                                       DHD_ERROR_MEM(("WLC_IOCTL: cmd: %d, val: %d(%s), "
-                                               "len: %d, set: %d\n",
-                                               ioc->cmd, val, tmp, ioc->len, ioc->set));
+                                       DHD_ERROR_MEM(("WLC_IOCTL: cmd: %d, val: %d, len: %d, "
+                                       "set: %d\n", ioc->cmd, val, ioc->len, ioc->set));
                        } else {
                                DHD_ERROR_MEM(("WLC_IOCTL: cmd: %d, buf is NULL\n", ioc->cmd));
                        }
@@ -907,14 +928,14 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
                                        DHD_ERROR(("%s: %s: %s, %s\n",
                                                __FUNCTION__, ioc->cmd == WLC_GET_VAR ?
                                                "WLC_GET_VAR" : "WLC_SET_VAR",
-                                               (char *)ioc->buf,
+                                               (char *)buf,
                                                ret == BCME_UNSUPPORTED ? "UNSUPPORTED"
                                                : "NOT ASSOCIATED"));
                                } else {
                                        DHD_ERROR(("%s: %s: %s, ret = %d\n",
                                                __FUNCTION__, ioc->cmd == WLC_GET_VAR ?
                                                "WLC_GET_VAR" : "WLC_SET_VAR",
-                                               (char *)ioc->buf, ret));
+                                               (char *)buf, ret));
                                }
                        } else {
                                if (ret == BCME_UNSUPPORTED || ret == BCME_NOTASSOCIATED) {
@@ -986,7 +1007,7 @@ int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen)
 {
        DHD_TRACE(("%s \n", __FUNCTION__));
 
-       return dhd_iovar(dhd, 0, "cons", msg, msglen, 1);
+       return dhd_iovar(dhd, 0, "cons", msg, msglen, NULL, 0, TRUE);
 
 }
 #endif /* DHD_DEBUG && BCMDHDUSB  */
@@ -1450,7 +1471,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
        case IOV_SVAL(IOV_PROXY_ARP): {
                uint32  bssidx;
                const char *val;
-               char iobuf[32];
 
                if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
                        DHD_ERROR(("%s: IOV_PROXY_ARP: bad parameter\n", __FUNCTION__));
@@ -1462,11 +1482,8 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
                /* Issue a iovar request to WL to update the proxy arp capability bit
                 * in the Extended Capability IE of beacons/probe responses.
                 */
-               bcm_mkiovar("proxy_arp_advertise", val, sizeof(int_val), iobuf,
-                       sizeof(iobuf));
-               bcmerror =  dhd_wl_ioctl_cmd(dhd_pub, WLC_SET_VAR, iobuf,
-                       sizeof(iobuf),  TRUE, bssidx);
-
+               bcmerror = dhd_iovar(dhd_pub, bssidx, "proxy_arp_advertise", val, sizeof(int_val),
+                               NULL, 0, TRUE);
                if (bcmerror == BCME_OK) {
                        dhd_set_parp_status(dhd_pub, bssidx, int_val ? 1 : 0);
                }
@@ -2011,7 +2028,7 @@ exit:
 }
 
 int
-dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void * buf, uint buflen)
+dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen)
 {
        int bcmerror = 0;
        unsigned long flags;
@@ -2181,6 +2198,58 @@ unlock_exit:
        return bcmerror;
 }
 
+#if defined(SHOW_EVENTS) && defined(SUPPORT_EVT_SDB_LOG)
+#define SDB_ENABLE_AP  0x01
+#define SDB_ENABLE_P2P 0x02
+#define SDB_IS_AP(i)   (i & SDB_ENABLE_AP)
+#define SDB_IS_P2P(i)  (i & SDB_ENABLE_P2P)
+
+#define WLC_RSDB_MODE_AUTO_MASK 0x80
+#define WLC_RSDB_EXTRACT_MODE(val) ((int8)((val) & (~(WLC_RSDB_MODE_AUTO_MASK))))
+
+static void
+wl_event_sdb_transition_print(void *event_data, const char *event_name)
+{
+       wl_event_sdb_trans_t *rdata;
+       wl_event_sdb_data_t *value;
+       char *sta_mode = "";
+       int i;
+       char chanbuf[CHANSPEC_STR_LEN];
+       rdata = (wl_event_sdb_trans_t *)event_data;
+
+       if (!rdata) {
+               DHD_ERROR(("%s: event_data is NULL\n", __FUNCTION__));
+               return;
+       }
+
+       if (rdata->version != WL_EVENT_SDB_TRANSITION_VER) {
+               DHD_ERROR(("%s: invalid Version(%d)\n",
+                       __FUNCTION__, rdata->version));
+               return;
+       }
+
+       if (rdata->rsdb_mode & WLC_RSDB_MODE_AUTO_MASK) {
+               DHD_ERROR((" RSDB Mode : Auto, "));
+       }
+       DHD_ERROR(("Current RSDB Mode : %d\n", WLC_RSDB_EXTRACT_MODE(rdata->rsdb_mode)));
+
+       for (i = 0; i < rdata->enable_bsscfg; i++) {
+               value = &rdata->values[i];
+
+               if (SDB_IS_P2P(value->is_iftype)) {
+                       sta_mode = SDB_IS_AP(value->is_iftype) ? "P2P_GO" : "P2P_GC";
+               } else {
+                       sta_mode = SDB_IS_AP(value->is_iftype) ? "SoftAP" : "Station";
+               }
+
+               wf_chspec_ntoa_ex(value->chanspec, chanbuf);
+               DHD_ERROR((" wlc%d <%s> \"%s\", %s(0x%04x)\n",
+                       value->wlunit, sta_mode,
+                       value->ssidbuf, chanbuf, value->chanspec));
+       }
+}
+#endif /* SHOW_EVENTS && SUPPORT_EVT_SDB_LOG */
+
 #ifdef SHOW_EVENTS
 static void
 wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data,
@@ -2204,13 +2273,7 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data,
        datalen = ntoh32(event->datalen);
 
        /* debug dump of event messages */
-       snprintf(eabuf, sizeof(eabuf), "%02x:%02x:%02x:%02x:%02x:%02x",
-               (uchar)event->addr.octet[0]&0xff,
-               (uchar)event->addr.octet[1]&0xff,
-               (uchar)event->addr.octet[2]&0xff,
-               (uchar)event->addr.octet[3]&0xff,
-               (uchar)event->addr.octet[4]&0xff,
-               (uchar)event->addr.octet[5]&0xff);
+       snprintf(eabuf, sizeof(eabuf), MACDBG, MAC2STRDBG(event->addr.octet));
 
        event_name = bcmevent_get_name(event_type);
        BCM_REFERENCE(event_name);
@@ -2357,7 +2420,6 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data,
        case WLC_E_PFN_SCAN_NONE:
        case WLC_E_PFN_SCAN_ALLGONE:
        case WLC_E_PFN_GSCAN_FULL_RESULT:
-       case WLC_E_PFN_SWC:
        case WLC_E_PFN_SSID_EXT:
                DHD_EVENT(("PNOEVENT: %s\n", event_name));
                break;
@@ -2449,6 +2511,14 @@ wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data,
        }
 #endif /* SHOW_LOGTRACE */
 
+#ifdef SUPPORT_EVT_SDB_LOG
+       case WLC_E_SDB_TRANSITION:
+               DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n",
+                       event_name, (int)status, (int)reason));
+               wl_event_sdb_transition_print(event_data, event_name);
+               break;
+#endif /* SUPPORT_EVT_SDB_LOG */
+
        default:
                DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n",
                       event_name, event_type, eabuf, (int)status, (int)reason,
@@ -2663,9 +2733,6 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen
        uint evlen;
        int ret;
        uint16 usr_subtype;
-       char macstr[ETHER_ADDR_STR_LEN];
-
-       BCM_REFERENCE(macstr);
 
        ret = wl_host_event_get_data(pktdata, pktlen, &evu);
        if (ret != BCME_OK) {
@@ -2765,12 +2832,11 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen
 #ifdef PROP_TXSTATUS
                {
                        uint8* ea = pvt_data->eth.ether_dhost;
-                       WLFC_DBGMESG(("WLC_E_IF: idx:%d, action:%s, iftype:%s, "
-                                                 "[%02x:%02x:%02x:%02x:%02x:%02x]\n",
-                                                 ifevent->ifidx,
-                                                 ((ifevent->opcode == WLC_E_IF_ADD) ? "ADD":"DEL"),
-                                                 ((ifevent->role == 0) ? "STA":"AP "),
-                                                 ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]));
+                       WLFC_DBGMESG(("WLC_E_IF: idx:%d, action:%s, iftype:%s, ["MACDBG"]\n",
+                               ifevent->ifidx,
+                               ((ifevent->opcode == WLC_E_IF_ADD) ? "ADD":"DEL"),
+                               ((ifevent->role == 0) ? "STA":"AP "),
+                               MAC2STRDBG(ea)));
                        (void)ea;
 
                        if (ifevent->opcode == WLC_E_IF_CHANGE)
@@ -2905,8 +2971,8 @@ wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen
                                __FUNCTION__, type, flags, status, role, del_sta));
 
                        if (del_sta) {
-                               DHD_MAC_TO_STR((event->addr.octet), macstr);
-                               DHD_EVENT(("%s: Deleting STA %s\n", __FUNCTION__, macstr));
+                               DHD_EVENT(("%s: Deleting STA " MACDBG "\n",
+                                       __FUNCTION__, MAC2STRDBG(event->addr.octet)));
 
                                dhd_del_sta(dhd_pub, dhd_ifname2idx(dhd_pub->info,
                                        event->ifname), &event->addr.octet);
@@ -2989,9 +3055,9 @@ dhd_print_buf(void *pbuf, int len, int bytes_per_line)
 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
 #endif
 
-#ifdef PKT_FILTER_SUPPORT
+#if defined(PKT_FILTER_SUPPORT) || defined(DHD_PKT_LOGGING)
 /* Convert user's input in hex pattern to byte-size mask */
-static int
+int
 wl_pattern_atoh(char *src, char *dst)
 {
        int i;
@@ -3014,7 +3080,9 @@ wl_pattern_atoh(char *src, char *dst)
        }
        return i;
 }
+#endif /* PKT_FILTER_SUPPORT || DHD_PKT_LOGGING */
 
+#ifdef PKT_FILTER_SUPPORT
 void
 dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode)
 {
@@ -3152,7 +3220,7 @@ dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
                DHD_ERROR(("%s: malloc failed\n", __FUNCTION__));
                goto fail;
        }
-
+       memset(buf, 0, BUF_SIZE);
        memcpy(arg_save, arg, strlen(arg) + 1);
 
        if (strlen(arg) > BUF_SIZE) {
@@ -3212,20 +3280,28 @@ dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
                }
 
                /* Parse pattern filter mask. */
-               mask_size =
-                       htod32(wl_pattern_atoh(argv[i],
-                       (char *) pkt_filterp->u.pattern.mask_and_pattern));
+               rc  = wl_pattern_atoh(argv[i],
+                       (char *) pkt_filterp->u.pattern.mask_and_pattern);
 
+               if (rc == -1) {
+                       DHD_ERROR(("Rejecting: %s\n", argv[i]));
+                       goto fail;
+               }
+               mask_size = htod32(rc);
                if (argv[++i] == NULL) {
                        DHD_ERROR(("Pattern not provided\n"));
                        goto fail;
                }
 
                /* Parse pattern filter pattern. */
-               pattern_size =
-                       htod32(wl_pattern_atoh(argv[i],
-                       (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
+               rc = wl_pattern_atoh(argv[i],
+                       (char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size]);
 
+               if (rc == -1) {
+                       DHD_ERROR(("Rejecting: %s\n", argv[i]));
+                       goto fail;
+               }
+               pattern_size = htod32(rc);
                if (mask_size != pattern_size) {
                        DHD_ERROR(("Mask and pattern not the same size\n"));
                        goto fail;
@@ -3450,20 +3526,13 @@ void
 dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx)
 {
        int ret = 0;
-       int iov_len = 0;
-       char iovbuf[DHD_IOVAR_BUF_SIZE];
 
        if (dhd == NULL) return;
        if (dhd->arp_version == 1)
                idx = 0;
 
-       iov_len = bcm_mkiovar("arp_table_clear", 0, 0, iovbuf, sizeof(iovbuf));
-       if (!iov_len) {
-               DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
-                       __FUNCTION__, sizeof(iovbuf)));
-               return;
-       }
-       if ((ret  = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx)) < 0)
+       ret = dhd_iovar(dhd, idx, "arp_table_clear", NULL, 0, NULL, 0, TRUE);
+       if (ret < 0)
                DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
 }
 
@@ -3471,46 +3540,29 @@ void
 dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx)
 {
        int ret = 0;
-       int iov_len = 0;
-       char iovbuf[DHD_IOVAR_BUF_SIZE];
 
        if (dhd == NULL) return;
        if (dhd->arp_version == 1)
                idx = 0;
 
-       iov_len = bcm_mkiovar("arp_hostip_clear", 0, 0, iovbuf, sizeof(iovbuf));
-       if (!iov_len) {
-               DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
-                       __FUNCTION__, sizeof(iovbuf)));
-               return;
-       }
-       if ((ret  = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx)) < 0)
+       ret = dhd_iovar(dhd, idx, "arp_hostip_clear", NULL, 0, NULL, 0, TRUE);
+       if (ret < 0)
                DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
 }
 
 void
 dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx)
 {
-       int iov_len = 0;
-       char iovbuf[DHD_IOVAR_BUF_SIZE];
-       int retcode;
-
+       int ret;
 
        if (dhd == NULL) return;
        if (dhd->arp_version == 1)
                idx = 0;
-       iov_len = bcm_mkiovar("arp_hostip", (char *)&ipaddr,
-               sizeof(ipaddr), iovbuf, sizeof(iovbuf));
-       if (!iov_len) {
-               DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
-                       __FUNCTION__, sizeof(iovbuf)));
-               return;
-       }
-       retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
 
-       if (retcode)
-               DHD_TRACE(("%s: ARP ip addr add failed, retcode = %d\n",
-               __FUNCTION__, retcode));
+       ret = dhd_iovar(dhd, idx, "arp_hostip", (char *)&ipaddr, sizeof(ipaddr),
+                       NULL, 0, TRUE);
+       if (ret)
+               DHD_TRACE(("%s: ARP ip addr add failed, ret = %d\n", __FUNCTION__, ret));
        else
                DHD_TRACE(("%s: sARP H ipaddr entry added \n",
                __FUNCTION__));
@@ -3519,8 +3571,7 @@ dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx)
 int
 dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx)
 {
-       int retcode, i;
-       int iov_len;
+       int ret, i;
        uint32 *ptr32 = buf;
        bool clr_bottom = FALSE;
 
@@ -3530,13 +3581,11 @@ dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx)
        if (dhd->arp_version == 1)
                idx = 0;
 
-       iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen);
-       BCM_REFERENCE(iov_len);
-       retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, idx);
-
-       if (retcode) {
+       ret = dhd_iovar(dhd, idx, "arp_hostip", NULL, 0, (char *)buf, buflen,
+                       FALSE);
+       if (ret) {
                DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n",
-               __FUNCTION__, retcode));
+               __FUNCTION__, ret));
 
                return -1;
        }
@@ -3568,6 +3617,12 @@ dhd_ndo_enable(dhd_pub_t * dhd, int ndo_enable)
        if (dhd == NULL)
                return -1;
 
+#ifdef WL_CFG80211
+       if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+               /* NDO disable on STA+SOFTAP mode */
+               ndo_enable = FALSE;
+       }
+#endif /* WL_CFG80211 */
        retcode = dhd_wl_ioctl_set_intiovar(dhd, "ndoe",
                ndo_enable, WLC_SET_VAR, TRUE, 0);
        if (retcode)
@@ -3588,7 +3643,7 @@ int
 dhd_ndo_add_ip(dhd_pub_t *dhd, char* ipv6addr, int idx)
 {
        int iov_len = 0;
-       char iovbuf[DHD_IOVAR_BUF_SIZE];
+       char iovbuf[DHD_IOVAR_BUF_SIZE] = {0};
        int retcode;
 
        if (dhd == NULL)
@@ -3620,7 +3675,7 @@ int
 dhd_ndo_remove_ip(dhd_pub_t *dhd, int idx)
 {
        int iov_len = 0;
-       char iovbuf[DHD_IOVAR_BUF_SIZE];
+       char iovbuf[DHD_IOVAR_BUF_SIZE] = {0};
        int retcode;
 
        if (dhd == NULL)
@@ -3659,6 +3714,7 @@ dhd_ndo_get_version(dhd_pub_t *dhdp)
                return BCME_ERROR;
        }
 
+       memset(&iovbuf, 0, sizeof(iovbuf));
        ndo_get_ver.version = htod16(WL_ND_HOSTIP_IOV_VER);
        ndo_get_ver.op_type = htod16(WL_ND_HOSTIP_OP_VER);
        ndo_get_ver.length = htod32(WL_ND_HOSTIP_FIXED_LEN + sizeof(uint16));
@@ -4269,6 +4325,84 @@ int dhd_keep_alive_onoff(dhd_pub_t *dhd)
        return res;
 }
 #endif /* defined(KEEP_ALIVE) */
+
+#define CSCAN_TLV_TYPE_SSID_IE 'S'
+/*
+ *  SSIDs list parsing from cscan tlv list
+ */
+int
+wl_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid, int max, int *bytes_left)
+{
+       char* str;
+       int idx = 0;
+       uint8 len;
+
+       if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
+               DHD_ERROR(("%s error paramters\n", __FUNCTION__));
+               return BCME_BADARG;
+       }
+       str = *list_str;
+       while (*bytes_left > 0) {
+               if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
+                       *list_str = str;
+                       DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]));
+                       return idx;
+               }
+
+               if (idx >= max) {
+                       DHD_ERROR(("%s number of SSIDs more than %d\n", __FUNCTION__, idx));
+                       return BCME_BADARG;
+               }
+
+               /* Get proper CSCAN_TLV_TYPE_SSID_IE */
+               *bytes_left -= 1;
+               if (*bytes_left == 0) {
+                       DHD_ERROR(("%s no length field.\n", __FUNCTION__));
+                       return BCME_BADARG;
+               }
+               str += 1;
+               ssid[idx].rssi_thresh = 0;
+               ssid[idx].flags = 0;
+               len = str[0];
+               if (len == 0) {
+                       /* Broadcast SSID */
+                       ssid[idx].SSID_len = 0;
+                       memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN);
+                       *bytes_left -= 1;
+                       str += 1;
+
+                       DHD_TRACE(("BROADCAST SCAN  left=%d\n", *bytes_left));
+               } else if (len <= DOT11_MAX_SSID_LEN) {
+                       /* Get proper SSID size */
+                       ssid[idx].SSID_len = len;
+                       *bytes_left -= 1;
+                       /* Get SSID */
+                       if (ssid[idx].SSID_len > *bytes_left) {
+                               DHD_ERROR(("%s out of memory range len=%d but left=%d\n",
+                               __FUNCTION__, ssid[idx].SSID_len, *bytes_left));
+                               return BCME_BADARG;
+                       }
+                       str += 1;
+                       memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len);
+
+                       *bytes_left -= ssid[idx].SSID_len;
+                       str += ssid[idx].SSID_len;
+                       ssid[idx].hidden = TRUE;
+
+                       DHD_TRACE(("%s :size=%d left=%d\n",
+                               (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left));
+               } else {
+                       DHD_ERROR(("### SSID size more than %d\n", str[0]));
+                       return BCME_BADARG;
+               }
+               idx++;
+       }
+
+       *list_str = str;
+       return idx;
+}
+
+#if defined(WL_WIRELESS_EXT)
 /* Android ComboSCAN support */
 
 /*
@@ -4369,79 +4503,6 @@ wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list,
        return idx;
 }
 
-/*
- *  SSIDs list parsing from cscan tlv list
- */
-int
-wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid, int max, int *bytes_left)
-{
-       char* str;
-       int idx = 0;
-
-       if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
-               DHD_ERROR(("%s error paramters\n", __FUNCTION__));
-               return -1;
-       }
-       str = *list_str;
-       while (*bytes_left > 0) {
-
-               if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
-                       *list_str = str;
-                       DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]));
-                       return idx;
-               }
-
-               /* Get proper CSCAN_TLV_TYPE_SSID_IE */
-               *bytes_left -= 1;
-               str += 1;
-               ssid[idx].rssi_thresh = 0;
-               ssid[idx].flags = 0;
-               if (str[0] == 0) {
-                       /* Broadcast SSID */
-                       ssid[idx].SSID_len = 0;
-                       memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN);
-                       *bytes_left -= 1;
-                       str += 1;
-
-                       DHD_TRACE(("BROADCAST SCAN  left=%d\n", *bytes_left));
-               }
-               else if (str[0] <= DOT11_MAX_SSID_LEN) {
-                       /* Get proper SSID size */
-                       ssid[idx].SSID_len = str[0];
-                       *bytes_left -= 1;
-                       str += 1;
-
-                       /* Get SSID */
-                       if (ssid[idx].SSID_len > *bytes_left) {
-                               DHD_ERROR(("%s out of memory range len=%d but left=%d\n",
-                               __FUNCTION__, ssid[idx].SSID_len, *bytes_left));
-                               return -1;
-                       }
-
-                       memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len);
-
-                       *bytes_left -= ssid[idx].SSID_len;
-                       str += ssid[idx].SSID_len;
-                       ssid[idx].hidden = TRUE;
-
-                       DHD_TRACE(("%s :size=%d left=%d\n",
-                               (char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left));
-               }
-               else {
-                       DHD_ERROR(("### SSID size more that %d\n", str[0]));
-                       return -1;
-               }
-
-               if (idx++ >  max) {
-                       DHD_ERROR(("%s number of SSIDs more that %d\n", __FUNCTION__, idx));
-                       return -1;
-               }
-       }
-
-       *list_str = str;
-       return idx;
-}
-
 /* Parse a comma-separated list from list_str into ssid array, starting
  * at index idx.  Max specifies size of the ssid array.  Parses ssids
  * and returns updated idx; if idx >= max not all fit, the excess have
@@ -4523,6 +4584,8 @@ wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
        return num;
 }
 
+#endif 
+
 #if defined(TRAFFIC_MGMT_DWM)
 static int traffic_mgmt_add_dwm_filter(dhd_pub_t *dhd,
        trf_mgmt_filter_list_t * trf_mgmt_filter_list, int len)
@@ -4764,7 +4827,7 @@ exit:
 int
 dhd_check_current_clm_data(dhd_pub_t *dhd)
 {
-       char iovbuf[WLC_IOCTL_SMLEN];
+       char iovbuf[WLC_IOCTL_SMLEN] = {0};
        wl_country_t *cspec;
        int err = BCME_OK;
 
@@ -4793,7 +4856,7 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
        int len;
        unsigned char *imgbuf = NULL;
        int err = BCME_OK;
-       char iovbuf[WLC_IOCTL_SMLEN];
+       char iovbuf[WLC_IOCTL_SMLEN] = {0};
        int status = FALSE;
 
        if (clm_path[0] != '\0') {
@@ -4804,7 +4867,7 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
                clm_blob_path = clm_path;
                DHD_TRACE(("clm path from module param:%s\n", clm_path));
        } else {
-               clm_blob_path = CONFIG_BCMDHD_CLM_PATH;
+               clm_blob_path = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH;
        }
 
        /* If CLM blob file is found on the filesystem, download the file.
@@ -4874,6 +4937,10 @@ dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
                }
        } else {
                DHD_INFO(("Skipping the clm download. len:%d memblk:%p \n", len, imgbuf));
+#ifdef DHD_USE_CLMINFO_PARSER
+               err = BCME_ERROR;
+               goto exit;
+#endif /* DHD_USE_CLMINFO_PARSER */
        }
 
        /* Verify country code */
@@ -4893,6 +4960,233 @@ exit:
        return err;
 }
 
+#ifdef DHD_USE_CLMINFO_PARSER
+#ifdef CUSTOMER_HW4
+#ifdef PLATFORM_SLP
+#define CLMINFO_PATH PLATFORM_PATH".clminfo"
+#else
+#define CLMINFO_PATH VENDOR_PATH"/etc/wifi/.clminfo"
+#endif /* PLATFORM_SLP */
+#else
+#define CLMINFO_PATH "/installmedia/.clminfo"
+#endif /* CUSTOMER_HW4 */
+
+extern struct cntry_locales_custom translate_custom_table[NUM_OF_COUNTRYS];
+
+unsigned int
+process_clarification_vars(char *varbuf, unsigned int varbuf_size)
+{
+       char *dp;
+       bool findNewline;
+       int column;
+       unsigned int buf_len, len;
+
+       dp = varbuf;
+
+       findNewline = FALSE;
+       column = 0;
+
+       for (len = 0; len < varbuf_size; len++) {
+               if ((varbuf[len] == '\r') || (varbuf[len] == ' ')) {
+                       continue;
+               }
+               if (findNewline && varbuf[len] != '\n') {
+                       continue;
+               }
+               findNewline = FALSE;
+               if (varbuf[len] == '#') {
+                       findNewline = TRUE;
+                       continue;
+               }
+               if (varbuf[len] == '\n') {
+                       if (column == 0) {
+                               continue;
+                       }
+                       column = 0;
+                       continue;
+               }
+               *dp++ = varbuf[len];
+               column++;
+       }
+       buf_len = (unsigned int)(dp - varbuf);
+
+       while (dp < varbuf + len) {
+               *dp++ = 0;
+       }
+
+       return buf_len;
+}
+
+int
+dhd_get_clminfo(dhd_pub_t *dhd, char *clm_path)
+{
+       int bcmerror = BCME_OK;
+       char *clminfo_path = CLMINFO_PATH;
+
+       char *memblock = NULL;
+       char *bufp;
+       uint len = MAX_CLMINFO_BUF_SIZE;
+       uint str_ln;
+       char *tokenp = NULL;
+       int cnt = 0;
+       char *temp_buf = NULL;
+       char tokdelim;
+       int parse_step = 0;
+
+       char *clm_blob_vendor_path = VENDOR_PATH;
+       char *clm_blob_path = NULL;
+       int clm_blob_path_len = 0;
+
+       /* Clears clm_path and translate_custom_table */
+       memset(clm_path, 0, MOD_PARAM_PATHLEN);
+       memset(translate_custom_table, 0, sizeof(translate_custom_table));
+
+       /*
+        * Read clm info from the .clminfo file
+        * 1st line : CLM blob file path
+        * 2nd ~ end of line: Country locales table
+        */
+       if (dhd_get_download_buffer(dhd, clminfo_path, CLMINFO, &memblock, &len) != 0) {
+               DHD_ERROR(("%s: Cannot open .clminfo file\n", __FUNCTION__));
+               bcmerror = BCME_ERROR;
+               dhd->is_clm_mult_regrev = FALSE;
+               goto out;
+       }
+
+       dhd->is_clm_mult_regrev = TRUE;
+
+       if ((len > 0) && (len < MAX_CLMINFO_BUF_SIZE) && memblock) {
+               /* Found clminfo file. Parsing the file */
+               DHD_INFO(("clminfo file parsing from %s \n", clminfo_path));
+
+               bufp = (char *) memblock;
+               bufp[len] = 0;
+
+               /* clean up the file */
+               len = process_clarification_vars(bufp, len);
+
+               tokenp = bcmstrtok(&bufp, "=", &tokdelim);
+               /* reduce the len of bufp by token byte(1) and ptr length */
+               len -= (strlen(tokenp) + 1);
+
+               if (strncmp(tokenp, "clm_path", 8) != 0) {
+                       DHD_ERROR(("%s: Cannot found clm_path\n", __FUNCTION__));
+                       bcmerror = BCME_ERROR;
+                       goto out;
+               }
+               temp_buf = bcmstrtok(&bufp, ";", &tokdelim);
+               str_ln = strlen(temp_buf);
+               /* read clm_path */
+               strncpy(clm_path, temp_buf, str_ln);
+               len -= (strlen(clm_path) + 1);
+
+               clm_blob_path_len = strlen(clm_path);
+               clm_blob_path = (char *)MALLOCZ(dhd->osh, clm_blob_path_len);
+               if (clm_blob_path == NULL) {
+                       bcmerror = BCME_NOMEM;
+                       DHD_ERROR(("%s: Failed to allocate memory!\n", __FUNCTION__));
+                       goto out;
+               }
+               memset(clm_blob_path, 0, clm_blob_path_len);
+               strncpy(clm_blob_path, clm_path, strlen(clm_path));
+
+               /* Concannate VENDOR_PATH + CLM_PATH */
+               memset(clm_path, 0, MOD_PARAM_PATHLEN);
+               snprintf(clm_path, (int)strlen(clm_blob_vendor_path) + clm_blob_path_len + 1,
+                       "%s%s", clm_blob_vendor_path, clm_blob_path);
+               clm_path[strlen(clm_path)] = '\0';
+
+               DHD_INFO(("%s: Found clm_path %s\n", __FUNCTION__, clm_path));
+
+               if (len <= 0) {
+                       DHD_ERROR(("%s: Length is invalid\n", __FUNCTION__));
+                       bcmerror = BCME_ERROR;
+                       goto out;
+               }
+
+               /* reserved relocale map[0] to XZ/11 */
+               memcpy(translate_custom_table[cnt].custom_locale, "XZ", strlen("XZ"));
+               translate_custom_table[cnt].custom_locale_rev = 11;
+               DHD_INFO(("%s: Relocale map - iso_aabrev %s custom locale %s "
+                       "custom locale rev %d\n",
+                       __FUNCTION__,
+                       translate_custom_table[cnt].iso_abbrev,
+                       translate_custom_table[cnt].custom_locale,
+                       translate_custom_table[cnt].custom_locale_rev));
+
+               cnt++;
+
+               /* start parsing relocale map */
+               do {
+
+                       if ((bufp[0] == 0) && (len > 0)) {
+                               DHD_ERROR(("%s: First byte is NULL character\n", __FUNCTION__));
+                               bcmerror = BCME_ERROR;
+                               goto out;
+                       }
+                       if ((bufp[0] == '=') || (bufp[0] == '/') || (bufp[0] == ';')) {
+                               DHD_ERROR(("%s: Data is invalid\n", __FUNCTION__));
+                               bcmerror = BCME_ERROR;
+                               goto out;
+                       }
+
+                       /* parsing relocale data */
+                       tokenp = bcmstrtok(&bufp, "=/;", &tokdelim);
+                       len -= (strlen(tokenp) + 1);
+
+                       if ((parse_step == 0) && (tokdelim == '=')) {
+                               memcpy(translate_custom_table[cnt].iso_abbrev,
+                                               tokenp, strlen(tokenp));
+                               parse_step++;
+                       } else if ((parse_step == 1) && (tokdelim == '/')) {
+                               memcpy(translate_custom_table[cnt].custom_locale,
+                                               tokenp, strlen(tokenp));
+                               parse_step++;
+                       } else if ((parse_step == 2) && (tokdelim == ';')) {
+                               char *str, *endptr = NULL;
+                               int locale_rev;
+
+                               str = tokenp;
+                               locale_rev = (int)strtoul(str, &endptr, 0);
+                               if (*endptr != 0) {
+                                       bcmerror = BCME_ERROR;
+                                       goto out;
+                               }
+
+                               translate_custom_table[cnt].custom_locale_rev = locale_rev;
+
+                               DHD_INFO(("%s: Relocale map - iso_aabrev %s"
+                                       " custom locale %s custom locale rev %d\n",
+                                       __FUNCTION__,
+                                       translate_custom_table[cnt].iso_abbrev,
+                                       translate_custom_table[cnt].custom_locale,
+                                       translate_custom_table[cnt].custom_locale_rev));
+
+                               parse_step = 0;
+                               cnt++;
+                       } else {
+                               DHD_ERROR(("%s: CLM info data format is invalid\n", __FUNCTION__));
+                               bcmerror = BCME_ERROR;
+                               goto out;
+                       }
+
+               } while (len > 0);
+       }
+out:
+       if (clm_blob_path) {
+               MFREE(dhd->osh, clm_blob_path, clm_blob_path_len);
+       }
+       if (memblock) {
+               dhd_free_download_buffer(dhd, memblock, MAX_CLMINFO_BUF_SIZE);
+       }
+       if (bcmerror != BCME_OK) {
+               DHD_ERROR(("%s: .clminfo parsing fail!!\n", __FUNCTION__));
+       }
+
+       return bcmerror;
+}
+#endif /* DHD_USE_CLMINFO_PARSER */
+
 void dhd_free_download_buffer(dhd_pub_t        *dhd, void *buffer, int length)
 {
 #ifdef CACHE_FW_IMAGES
@@ -4901,6 +5195,39 @@ void dhd_free_download_buffer(dhd_pub_t  *dhd, void *buffer, int length)
        MFREE(dhd->osh, buffer, length);
 }
 
+/* Parse EAPOL 4 way handshake messages */
+int
+dhd_check_eapol_4way_message(char *dump_data)
+{
+       unsigned char type;
+       int pair, ack, mic, kerr, req, sec, install;
+       unsigned short us_tmp;
+       type = dump_data[18];
+       if (type == 2) {
+               us_tmp = (dump_data[19] << 8) | dump_data[20];
+               pair = 0 != (us_tmp & 0x08);
+               ack = 0  != (us_tmp & 0x80);
+               mic = 0  != (us_tmp & 0x100);
+               kerr = 0 != (us_tmp & 0x400);
+               req = 0  != (us_tmp & 0x800);
+               sec = 0  != (us_tmp & 0x200);
+               install = 0 != (us_tmp & 0x40);
+               if (!sec && !mic && ack && !install && pair && !kerr && !req) {
+                       return EAPOL_4WAY_M1;
+               } else if (pair && !install && !ack && mic && !sec && !kerr && !req) {
+                       return EAPOL_4WAY_M2;
+               } else if (pair && ack && mic && sec && !kerr && !req) {
+                       return EAPOL_4WAY_M3;
+               } else if (pair && !install && !ack && mic && sec && !req && !kerr) {
+                       return EAPOL_4WAY_M4;
+               } else {
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
 #if defined(DHD_8021X_DUMP)
 #define EAP_PRINT(str) \
        DHD_ERROR(("ETHER_TYPE_802_1X[%s] [%s]: " str "\n", \
@@ -4910,8 +5237,6 @@ void
 dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction)
 {
        unsigned char type;
-       int pair, ack, mic, kerr, req, sec, install;
-       unsigned short us_tmp;
 
        type = dump_data[15];
        if (type == 0) {
@@ -4949,24 +5274,20 @@ dhd_dump_eapol_4way_message(char *ifname, char *dump_data, bool direction)
                                dump_data[14], dump_data[15], dump_data[30]));
                }
        } else if (type == 3 && dump_data[18] == 2) {
-               us_tmp = (dump_data[19] << 8) | dump_data[20];
-               pair =  0 != (us_tmp & 0x08);
-               ack = 0  != (us_tmp & 0x80);
-               mic = 0  != (us_tmp & 0x100);
-               kerr =  0 != (us_tmp & 0x400);
-               req = 0  != (us_tmp & 0x800);
-               sec = 0  != (us_tmp & 0x200);
-               install  = 0 != (us_tmp & 0x40);
-
-               if (!sec && !mic && ack && !install && pair && !kerr && !req) {
+               switch (dhd_check_eapol_4way_message(dump_data)) {
+               case EAPOL_4WAY_M1:
                        EAP_PRINT("EAPOL Packet, 4-way handshake, M1");
-               } else if (pair && !install && !ack && mic && !sec && !kerr && !req) {
+                       break;
+               case EAPOL_4WAY_M2:
                        EAP_PRINT("EAPOL Packet, 4-way handshake, M2");
-               } else if (pair && ack && mic && sec && !kerr && !req) {
+                       break;
+               case EAPOL_4WAY_M3:
                        EAP_PRINT("EAPOL Packet, 4-way handshake, M3");
-               } else if (pair && !install && !ack && mic && sec && !req && !kerr) {
+                       break;
+               case EAPOL_4WAY_M4:
                        EAP_PRINT("EAPOL Packet, 4-way handshake, M4");
-               } else {
+                       break;
+               default:
                        DHD_ERROR(("ETHER_TYPE_802_1X[%s] [%s]: ver %d, type %d, replay %d\n",
                                ifname, direction ? "TX" : "RX",
                                dump_data[14], dump_data[15], dump_data[30]));
@@ -5582,7 +5903,7 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size,
        uint32 *lognums = NULL;
        char *logstrs = NULL;
        int ram_index = 0;
-       char **fmts;
+       char **fmts = NULL;
        int num_fmts = 0;
        int32 i = 0;
 
@@ -5599,6 +5920,11 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size,
                        hdr->rom_lognums_offset) / sizeof(uint32);
                lognums = (uint32 *) &raw_fmts[hdr->rom_lognums_offset];
                logstrs = (char *)       &raw_fmts[hdr->rom_logstrs_offset];
+
+               if (logstrs_size != hdr->logstrs_size) {
+                       DHD_ERROR(("%s: bad logstrs_size %d\n", __FUNCTION__, hdr->logstrs_size));
+                       return BCME_ERROR;
+               }
        } else {
                /*
                 * Legacy logstrs.bin format without header.
@@ -5646,6 +5972,11 @@ dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size,
                                logstrs = (char *)      &raw_fmts[num_fmts << 2];
                        }
        }
+
+       if (event_log->fmts != NULL) {
+               DHD_ERROR(("fmts was not released\n"));
+               return BCME_ERROR;
+       }
        fmts = MALLOC(osh, num_fmts  * sizeof(char *));
        if (fmts == NULL) {
                DHD_ERROR(("%s: Failed to allocate fmts memory\n", __FUNCTION__));
@@ -5861,6 +6192,63 @@ int dhd_free_tdls_peer_list(dhd_pub_t *dhd_pub)
 }
 #endif /* #if defined(WLTDLS) && defined(PCIE_FULL_DONGLE) */
 
+/* pretty hex print a contiguous buffer
+ * based on the debug level specified
+ */
+void
+dhd_prhex(const char *msg, volatile uchar *buf, uint nbytes, uint8 dbg_level)
+{
+       char line[128], *p;
+       int len = sizeof(line);
+       int nchar;
+       uint i;
+
+       if (msg && (msg[0] != '\0')) {
+               if (dbg_level == DHD_ERROR_VAL)
+                       DHD_ERROR(("%s:\n", msg));
+               else if (dbg_level == DHD_INFO_VAL)
+                       DHD_INFO(("%s:\n", msg));
+               else if (dbg_level == DHD_TRACE_VAL)
+                       DHD_TRACE(("%s:\n", msg));
+       }
+
+       p = line;
+       for (i = 0; i < nbytes; i++) {
+               if (i % 16 == 0) {
+                       nchar = snprintf(p, len, "  %04x: ", i);        /* line prefix */
+                       p += nchar;
+                       len -= nchar;
+               }
+               if (len > 0) {
+                       nchar = snprintf(p, len, "%02x ", buf[i]);
+                       p += nchar;
+                       len -= nchar;
+               }
+
+               if (i % 16 == 15) {
+                       /* flush line */
+                       if (dbg_level == DHD_ERROR_VAL)
+                               DHD_ERROR(("%s:\n", line));
+                       else if (dbg_level == DHD_INFO_VAL)
+                               DHD_INFO(("%s:\n", line));
+                       else if (dbg_level == DHD_TRACE_VAL)
+                               DHD_TRACE(("%s:\n", line));
+                       p = line;
+                       len = sizeof(line);
+               }
+       }
+
+       /* flush last partial line */
+       if (p != line) {
+               if (dbg_level == DHD_ERROR_VAL)
+                       DHD_ERROR(("%s:\n", line));
+               else if (dbg_level == DHD_INFO_VAL)
+                       DHD_INFO(("%s:\n", line));
+               else if (dbg_level == DHD_TRACE_VAL)
+                       DHD_TRACE(("%s:\n", line));
+       }
+}
+
 #ifdef DUMP_IOCTL_IOV_LIST
 void
 dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node)
index 75754e114687d0690f82d426e0e48345c8276ee1..7c8cfe8256cc405d97328cf78d25276cac5febab 100644 (file)
@@ -2,7 +2,7 @@
  * Process CIS information from OTP for customer platform
  * (Handle the MAC address and module information)
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -25,7 +25,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_custom_cis.c 685046 2017-02-15 08:10:34Z $
+ * $Id: dhd_custom_cis.c 747655 2018-02-19 08:09:31Z $
  */
 
 #include <typedefs.h>
@@ -368,6 +368,7 @@ dhd_set_default_macaddr(dhd_pub_t *dhdp)
 {
        char iovbuf[WLC_IOCTL_SMLEN];
        struct ether_addr *mac;
+       int ret;
 
        if (!dhdp) {
                DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
@@ -377,10 +378,9 @@ dhd_set_default_macaddr(dhd_pub_t *dhdp)
        mac = &dhdp->mac;
 
        /* Read the default MAC address */
-       memset(iovbuf, 0, sizeof(iovbuf));
-       bcm_mkiovar("cur_etheraddr", 0, 0, iovbuf, sizeof(iovbuf));
-       if (dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, iovbuf,
-               sizeof(iovbuf), FALSE, 0) < 0) {
+       ret = dhd_iovar(dhdp, 0, "cur_etheraddr", NULL, 0, iovbuf, sizeof(iovbuf),
+                       FALSE);
+       if (ret < 0) {
                DHD_ERROR(("%s: Can't get the default MAC address\n", __FUNCTION__));
                return BCME_NOTUP;
        }
@@ -974,7 +974,7 @@ write_cid:
 }
 
 #ifdef SUPPORT_MULTIPLE_MODULE_CIS
-static bool
+bool
 dhd_check_module(char *module_name)
 {
        char vname[MAX_VNAME_LEN];
index 591a5d54f5d9ae0c3df63b87f3b9e6f3f022c651..0f56525791d788a64a71867fc8fbf3798b5d4371 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Platform Dependent file for Samsung Exynos
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -23,7 +23,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_custom_exynos.c 690177 2017-03-15 03:19:27Z $
+ * $Id: dhd_custom_exynos.c 742942 2018-01-24 07:12:25Z $
  */
 #include <linux/device.h>
 #include <linux/gpio.h>
 #endif /* !CONFIG_ARCH_SWA100 && !CONFIG_MACH_UNIVERSAL7580 */
 #endif /* CONFIG_64BIT */
 
-#if !defined(CONFIG_ARCH_SWA100) && !defined(CONFIG_SOC_EXYNOS7870)
+#if defined(CONFIG_MACH_UNIVERSAL7580) || defined(CONFIG_MACH_UNIVERSAL5430) || \
+       defined(CONFIG_MACH_UNIVERSAL5422)
 #include <mach/irqs.h>
-#endif /* !CONFIG_ARCH_SWA100 && !CONFIG_MACH_UNIVERSAL7580 */
+#endif /* CONFIG_MACH_UNIVERSAL7580 || CONFIG_MACH_UNIVERSAL5430 || CONFIG_MACH_UNIVERSAL5422 */
 
 #include <linux/sec_sysfs.h>
 
@@ -101,18 +102,21 @@ extern struct device *mmc_dev_for_wlan;
 #define SAMSUNG_PCIE_CH_NUM 0
 #endif
 #ifdef CONFIG_MACH_UNIVERSAL5433
-extern void exynos_pcie_poweron(void);
-extern void exynos_pcie_poweroff(void);
+extern void exynos_pcie_pm_resume(void);
+extern void exynos_pcie_pm_suspend(void);
 #else
-extern void exynos_pcie_poweron(int);
-extern void exynos_pcie_poweroff(int);
+extern void exynos_pcie_pm_resume(int);
+extern void exynos_pcie_pm_suspend(int);
 #endif /* CONFIG_MACH_UNIVERSAL5433 */
 #endif /* EXYNOS_PCIE_RC_ONOFF */
 
-#if (defined(CONFIG_MACH_UNIVERSAL3475) || defined(CONFIG_SOC_EXYNOS7870))
+#if (defined(CONFIG_MACH_UNIVERSAL3475) || defined(CONFIG_SOC_EXYNOS7870) || \
+       defined(CONFIG_MACH_UNIVERSAL7580) || defined(CONFIG_SOC_EXYNOS7885))
 extern struct mmc_host *wlan_mmc;
 extern void mmc_ctrl_power(struct mmc_host *host, bool onoff);
-#endif /* CONFIG_MACH_UNIVERSAL3475 || CONFIG_SOC_EXYNOS7870 */
+#endif /* MACH_UNIVERSAL3475 || SOC_EXYNOS7870 ||
+       * MACH_UNIVERSAL7580 || SOC_EXYNOS7885
+       */
 
 static int
 dhd_wlan_power(int onoff)
@@ -127,7 +131,7 @@ dhd_wlan_power(int onoff)
 
 #ifdef EXYNOS_PCIE_RC_ONOFF
        if (!onoff) {
-               exynos_pcie_poweroff(SAMSUNG_PCIE_CH_NUM);
+               exynos_pcie_pm_suspend(SAMSUNG_PCIE_CH_NUM);
        }
 
        if (gpio_direction_output(wlan_pwr_on, onoff)) {
@@ -141,7 +145,7 @@ dhd_wlan_power(int onoff)
                printk(KERN_ERR "%s Disable L1ss EP side\n", __FUNCTION__);
                exynos_pcie_l1ss_ctrl(0, PCIE_L1SS_CTRL_WIFI);
 #endif /* CONFIG_SOC_EXYNOS8895 */
-               exynos_pcie_poweron(SAMSUNG_PCIE_CH_NUM);
+               exynos_pcie_pm_resume(SAMSUNG_PCIE_CH_NUM);
        }
 #else
 #ifdef CONFIG_MACH_A7LTE
@@ -166,10 +170,13 @@ dhd_wlan_power(int onoff)
                        printk(KERN_INFO "%s WLAN SDIO GPIO control error\n", __FUNCTION__);
        }
 #endif /* CONFIG_MACH_A7LTE */
-#if (defined(CONFIG_MACH_UNIVERSAL3475) || defined(CONFIG_SOC_EXYNOS7870))
+#if (defined(CONFIG_MACH_UNIVERSAL3475) || defined(CONFIG_SOC_EXYNOS7870) || \
+       defined(CONFIG_MACH_UNIVERSAL7580) || defined(CONFIG_SOC_EXYNOS7885))
        if (wlan_mmc)
                mmc_ctrl_power(wlan_mmc, onoff);
-#endif /* CONFIG_MACH_UNIVERSAL3475 || CONFIG_SOC_EXYNOS7870 */
+#endif /* MACH_UNIVERSAL3475 || SOC_EXYNOS7870 ||
+       * MACH_UNIVERSAL7580 || SOC_EXYNOS7885
+       */
 #endif /* EXYNOS_PCIE_RC_ONOFF */
        return 0;
 }
@@ -257,6 +264,7 @@ dhd_wlan_init_gpio(void)
        }
 #ifdef CONFIG_BCMDHD_PCIE
        gpio_direction_output(wlan_pwr_on, 1);
+       msleep(WIFI_TURNON_DELAY);
 #else
        gpio_direction_output(wlan_pwr_on, 0);
 #endif /* CONFIG_BCMDHD_PCIE */
@@ -264,9 +272,8 @@ dhd_wlan_init_gpio(void)
        if (wlan_dev)
                gpio_export_link(wlan_dev, "WLAN_REG_ON", wlan_pwr_on);
 
-       msleep(WIFI_TURNON_DELAY);
 #ifdef EXYNOS_PCIE_RC_ONOFF
-       exynos_pcie_poweron(SAMSUNG_PCIE_CH_NUM);
+       exynos_pcie_pm_resume(SAMSUNG_PCIE_CH_NUM);
 #endif /* EXYNOS_PCIE_RC_ONOFF */
 
 #ifdef CONFIG_BCMDHD_OOB_HOST_WAKE
index 87366842c96175403c3cc219224956a5d29652e9..8b8336d474eccd92c2f4ff6e630e48f8868ad273 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Customer code to add GPIO control during WLAN start/stop
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index c74233eb61db1a1e530c22e74a58569149afcae0..551cd59b2cc42d7c1171cf039122faaff9ebabcc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Platform Dependent file for usage of Preallocted Memory
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -23,7 +23,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_custom_memprealloc.c 669363 2016-11-09 06:59:02Z $
+ * $Id: dhd_custom_memprealloc.c 742436 2018-01-22 08:33:32Z $
  */
 
 #include <linux/device.h>
 #define WLAN_STATIC_DHD_PKTID_IOCTL_MAP        14
 #define WLAN_STATIC_DHD_LOG_DUMP_BUF   15
 #define WLAN_STATIC_DHD_LOG_DUMP_BUF_EX        16
+#define WLAN_STATIC_DHD_PKTLOG_DUMP_BUF        17
+#define WLAN_STATIC_STAT_REPORT_BUF            18
 
 #define WLAN_SCAN_BUF_SIZE             (64 * 1024)
 
-#if defined(CONFIG_64BIT)
 #define WLAN_DHD_INFO_BUF_SIZE         (32 * 1024)
 #define WLAN_DHD_WLFC_BUF_SIZE         (64 * 1024)
 #define WLAN_DHD_IF_FLOW_LKUP_SIZE     (64 * 1024)
-#else
-#define WLAN_DHD_INFO_BUF_SIZE         (32 * 1024)
-#define WLAN_DHD_WLFC_BUF_SIZE         (16 * 1024)
-#define WLAN_DHD_IF_FLOW_LKUP_SIZE     (20 * 1024)
-#endif /* CONFIG_64BIT */
 #define WLAN_DHD_MEMDUMP_SIZE          (1536 * 1024)
 
 #define PREALLOC_WLAN_SEC_NUM          4
 #define DHD_LOG_DUMP_BUF_SIZE  (1024 * 1024)
 #define DHD_LOG_DUMP_BUF_EX_SIZE       (8 * 1024)
 
+#define DHD_PKTLOG_DUMP_BUF_SIZE       (64 * 1024)
+
+#define DHD_STAT_REPORT_BUF_SIZE       (128 * 1024)
+
 #define WLAN_DHD_WLFC_HANGER_MAXITEMS          3072
 #define WLAN_DHD_WLFC_HANGER_ITEM_SIZE         32
 #define WLAN_DHD_WLFC_HANGER_SIZE      ((WLAN_DHD_WLFC_HANGER_ITEM_SIZE) + \
@@ -151,6 +151,19 @@ static void *wlan_static_dhd_pktid_map = NULL;
 static void *wlan_static_dhd_pktid_ioctl_map = NULL;
 static void *wlan_static_dhd_log_dump_buf = NULL;
 static void *wlan_static_dhd_log_dump_buf_ex = NULL;
+static void *wlan_static_dhd_pktlog_dump_buf = NULL;
+static void *wlan_static_stat_report_buf = NULL;
+
+#define GET_STATIC_BUF(section, config_size, req_size, buf) ({\
+       void *__ret; \
+       if (req_size > config_size) {\
+               pr_err("request " #section " size(%lu) is bigger than" \
+                               " static size(%d)\n", \
+                               req_size, config_size); \
+               __ret = NULL; \
+       } else { __ret = buf;} \
+       __ret; \
+})
 
 void
 *dhd_wlan_mem_prealloc(int section, unsigned long size)
@@ -258,6 +271,21 @@ void
                return wlan_static_dhd_log_dump_buf_ex;
        }
 
+       if (section == WLAN_STATIC_DHD_PKTLOG_DUMP_BUF) {
+               if (size > DHD_PKTLOG_DUMP_BUF_SIZE) {
+                       pr_err("request DHD_PKTLOG_DUMP_BUF size(%lu) is bigger then"
+                                       " static size(%d).\n",
+                                       size, DHD_PKTLOG_DUMP_BUF_SIZE);
+                       return NULL;
+               }
+               return wlan_static_dhd_pktlog_dump_buf;
+       }
+
+       if (section == WLAN_STATIC_STAT_REPORT_BUF) {
+               return GET_STATIC_BUF(WLAN_STATIC_STAT_REPORT_BUF,
+                       DHD_STAT_REPORT_BUF_SIZE, size, wlan_static_stat_report_buf);
+       }
+
        if ((section < 0) || (section >= PREALLOC_WLAN_SEC_NUM)) {
                return NULL;
        }
@@ -277,21 +305,21 @@ dhd_init_wlan_mem(void)
        int j;
 
        for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
-               wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
+               wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE, GFP_KERNEL);
                if (!wlan_static_skb[i]) {
                        goto err_skb_alloc;
                }
        }
 
        for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {
-               wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);
+               wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE, GFP_KERNEL);
                if (!wlan_static_skb[i]) {
                        goto err_skb_alloc;
                }
        }
 
 #if !defined(CONFIG_BCMDHD_PCIE)
-       wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
+       wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE, GFP_KERNEL);
        if (!wlan_static_skb[i]) {
                goto err_skb_alloc;
        }
@@ -385,6 +413,18 @@ dhd_init_wlan_mem(void)
        }
 #endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
 
+       wlan_static_dhd_pktlog_dump_buf = kmalloc(DHD_PKTLOG_DUMP_BUF_SIZE, GFP_KERNEL);
+       if (!wlan_static_dhd_pktlog_dump_buf) {
+               pr_err("Failed to alloc wlan_static_dhd_pktlog_dump_buf\n");
+               goto err_mem_alloc;
+       }
+
+       wlan_static_stat_report_buf = kmalloc(DHD_STAT_REPORT_BUF_SIZE, GFP_KERNEL);
+       if (!wlan_static_stat_report_buf) {
+               pr_err("Failed to alloc wlan_static_stat_report_buf\n");
+               goto err_mem_alloc;
+       }
+
        pr_err("%s: WIFI MEM Allocated\n", __FUNCTION__);
        return 0;
 
@@ -439,6 +479,14 @@ err_mem_alloc:
                kfree(wlan_static_scan_buf0);
        }
 
+       if (wlan_static_dhd_pktlog_dump_buf) {
+               kfree(wlan_static_dhd_pktlog_dump_buf);
+       }
+
+       if (wlan_static_stat_report_buf) {
+               kfree(wlan_static_stat_report_buf);
+       }
+
        pr_err("Failed to mem_alloc for WLAN\n");
 
        for (j = 0; j < i; j++) {
index 607e0d59660f4e401f8973fef04fa52104689e90..23e3124d96aa46f4de85145a2532aa3efcf26bba 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Platform Dependent file for Qualcomm MSM/APQ
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -23,7 +23,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_custom_msm.c 674523 2016-12-09 04:05:27Z $
+ * $Id: dhd_custom_msm.c 742443 2018-01-22 09:17:21Z $
  *
  */
 
@@ -51,7 +51,11 @@ extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
 
 #define WIFI_TURNON_DELAY       200
 static int wlan_reg_on = -1;
+#ifdef CONFIG_BCM4359
+#define DHD_DT_COMPAT_ENTRY            "samsung,bcmdhd_wlan"
+#else
 #define DHD_DT_COMPAT_ENTRY            "android,bcmdhd_wlan"
+#endif /* CONFIG_BCM4359 */
 #define WIFI_WL_REG_ON_PROPNAME                "wlan-en-gpio"
 
 #if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_ARCH_MSM8998)
index 07649d8b22107f67af11303056169e3891d3056a..17af8340820c8fc74e2b855fba636d6838e7acf5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Customer HW 4 dependant file
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
 #include <linux/fcntl.h>
 #include <linux/fs.h>
 
-#if defined(ARGOS_CPU_SCHEDULER)
+#if defined(ARGOS_CPU_SCHEDULER) && !defined(DHD_LB_IRQSET)
 extern int argos_irq_affinity_setup_label(unsigned int irq, const char *label,
        struct cpumask *affinity_cpu_mask,
        struct cpumask *default_cpu_mask);
-#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* ARGOS_CPU_SCHEDULER && !DHD_LB_IRQSET */
 
+#if !defined(DHD_USE_CLMINFO_PARSER)
 const struct cntry_locales_custom translate_custom_table[] = {
 #if defined(BCM4330_CHIP) || defined(BCM4334_CHIP) || defined(BCM43241_CHIP)
        /* 4330/4334/43241 */
@@ -173,13 +174,23 @@ const struct cntry_locales_custom translate_custom_table[] = {
        {"PS", "XZ", 11},       /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
        {"TL", "XZ", 11},       /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
        {"MH", "XZ", 11},       /* Universal if Country code is MARSHALL ISLANDS */
+#if defined(BCM4359_CHIP)
+       {"SX", "XZ", 11},       /* Universal if Country code is Sint Maarten */
+       {"CC", "XZ", 11},       /* Universal if Country code is COCOS (KEELING) ISLANDS */
+       {"HM", "XZ", 11},       /* Universal if Country code is HEARD ISLAND AND MCDONALD ISLANDS */
+       {"PN", "XZ", 11},       /* Universal if Country code is PITCAIRN */
+       {"AQ", "XZ", 11},       /* Universal if Country code is ANTARCTICA */
+       {"AX", "XZ", 11},       /* Universal if Country code is ALAND ISLANDS */
+       {"BV", "XZ", 11},       /* Universal if Country code is BOUVET ISLAND */
+       {"GS", "XZ", 11},       /* Universal if Country code is
+                                * SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS
+                                */
+       {"SH", "XZ", 11},       /* Universal if Country code is SAINT HELENA */
+       {"SJ", "XZ", 11},       /* Universal if Country code is SVALBARD AND JAN MAYEN */
+       {"SS", "XZ", 11},       /* Universal if Country code is SOUTH SUDAN */
+#endif /* BCM4359_CHIP */
        {"GL", "GP", 2},
        {"AL", "AL", 2},
-#ifdef DHD_SUPPORT_GB_999
-       {"DZ", "GB", 999},
-#else
-       {"DZ", "GB", 6},
-#endif /* DHD_SUPPORT_GB_999 */
        {"AS", "AS", 12},
        {"AI", "AI", 1},
        {"AF", "AD", 0},
@@ -227,7 +238,6 @@ const struct cntry_locales_custom translate_custom_table[] = {
        {"IE", "IE", 5},
        {"IL", "IL", 14},
        {"IT", "IT", 4},
-       {"JP", "JP", 45},
        {"JO", "JO", 3},
        {"KE", "SA", 0},
        {"KW", "KW", 5},
@@ -241,7 +251,13 @@ const struct cntry_locales_custom translate_custom_table[] = {
        {"MO", "SG", 0},
        {"MK", "MK", 2},
        {"MW", "MW", 1},
-       {"MY", "MY", 3},
+#if defined(BCM4359_CHIP)
+       {"DZ", "DZ", 2},
+#elif defined(DHD_SUPPORT_GB_999)
+       {"DZ", "GB", 999},
+#else
+       {"DZ", "GB", 6},
+#endif /* BCM4359_CHIP */
        {"MV", "MV", 3},
        {"MT", "MT", 4},
        {"MQ", "MQ", 2},
@@ -276,7 +292,6 @@ const struct cntry_locales_custom translate_custom_table[] = {
        {"LK", "LK", 1},
        {"SE", "SE", 4},
        {"CH", "CH", 4},
-       {"TW", "TW", 1},
        {"TH", "TH", 5},
        {"TT", "TT", 3},
        {"TR", "TR", 7},
@@ -299,13 +314,26 @@ const struct cntry_locales_custom translate_custom_table[] = {
 #else
        {"KR", "KR", 48},
 #endif
+#if defined(BCM4359_CHIP)
+       {"TW", "TW", 65},
+       {"JP", "JP", 968},
+       {"RU", "RU", 986},
+       {"UA", "UA", 16},
+       {"ZA", "ZA", 19},
+       {"AM", "AM", 1},
+       {"MY", "MY", 19},
+#else
+       {"TW", "TW", 1},
+       {"JP", "JP", 45},
        {"RU", "RU", 13},
        {"UA", "UA", 8},
+       {"ZA", "ZA", 6},
+       {"MY", "MY", 3},
+#endif /* BCM4359_CHIP */
        {"GT", "GT", 1},
        {"MN", "MN", 1},
        {"NI", "NI", 2},
        {"UZ", "MA", 2},
-       {"ZA", "ZA", 6},
        {"EG", "EG", 13},
        {"TN", "TN", 1},
        {"AO", "AD", 0},
@@ -316,11 +344,20 @@ const struct cntry_locales_custom translate_custom_table[] = {
        {"UM", "PR", 38},
        /* Support FCC 15.407 (Part 15E) Changes, effective June 2 2014 */
        /* US/988, Q2/993 country codes with higher power on UNII-1 5G band */
+#if defined(DHD_SUPPORT_US_949)
+       {"US", "US", 949},
+#elif defined(DHD_SUPPORT_US_945)
+       {"US", "US", 945},
+#else
        {"US", "US", 988},
+#endif /* DHD_SUPPORT_US_949 */
        {"CU", "US", 988},
        {"CA", "Q2", 993},
 #endif /* default ccode/regrev */
 };
+#else
+struct cntry_locales_custom translate_custom_table[NUM_OF_COUNTRYS];
+#endif /* !DHD_USE_CLMINFO_PARSER */
 
 /* Customized Locale convertor
 *  input : ISO 3166-1 country abbreviation
@@ -356,6 +393,7 @@ void get_customized_country_code(void *adapter, char *country_iso_code, wl_count
 #define RSDBINFO       PLATFORM_PATH".rsdb.info"
 #define LOGTRACEINFO   PLATFORM_PATH".logtrace.info"
 #define ADPSINFO       PLATFORM_PATH".adps.info"
+#define SOFTAPINFO     PLATFORM_PATH".softap.info"
 
 #ifdef DHD_PM_CONTROL_FROM_FILE
 extern bool g_pm_control;
@@ -364,7 +402,6 @@ void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
        struct file *fp = NULL;
        char *filepath = PSMINFO;
        char power_val = 0;
-       char iovbuf[WL_EVENTING_MASK_LEN + 12];
        int ret = 0;
 #ifdef DHD_ENABLE_LPC
        uint32 lpc = 0;
@@ -388,7 +425,6 @@ void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
 #ifdef ROAM_ENABLE
                        uint roamvar = 1;
 #endif
-                       uint32 ocl_enable = 0;
                        uint32 wl_updown = 1;
 
                        *power_mode = PM_OFF;
@@ -397,24 +433,19 @@ void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
                                sizeof(uint), TRUE, 0);
 #ifndef CUSTOM_SET_ANTNPM
                        /* Turn off MPC in AP mode */
-                       bcm_mkiovar("mpc", (char *)power_mode, 4,
-                               iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                               sizeof(iovbuf), TRUE, 0);
+                       dhd_iovar(dhd, 0, "mpc", (char *)power_mode, sizeof(*power_mode), NULL, 0,
+                                       TRUE);
 #endif /* !CUSTOM_SET_ANTNPM */
                        g_pm_control = TRUE;
 #ifdef ROAM_ENABLE
                        /* Roaming off of dongle */
-                       bcm_mkiovar("roam_off", (char *)&roamvar, 4,
-                               iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                               sizeof(iovbuf), TRUE, 0);
+                       dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar), NULL, 0,
+                                       TRUE);
 #endif
 #ifdef DHD_ENABLE_LPC
                        /* Set lpc 0 */
-                       bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf));
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                               sizeof(iovbuf), TRUE, 0)) < 0) {
+                       ret = dhd_iovar(dhd, 0, "lpc", (char *)&lpc, sizeof(lpc), NULL, 0, TRUE);
+                       if (ret < 0) {
                                DHD_ERROR(("[WIFI_SEC] %s: Set lpc failed  %d\n",
                                __FUNCTION__, ret));
                        }
@@ -431,21 +462,20 @@ void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
                        }
 
 #ifndef CUSTOM_SET_OCLOFF
-                       bcm_mkiovar("ocl_enable", (char *)&ocl_enable, 4, iovbuf, sizeof(iovbuf));
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                       sizeof(iovbuf), TRUE, 0)) < 0) {
-                               DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d failed %d\n",
+                       {
+                               uint32 ocl_enable = 0;
+                               ret = dhd_iovar(dhd, 0, "ocl_enable", (char *)&ocl_enable,
+                                               sizeof(ocl_enable), NULL, 0, TRUE);
+                               if (ret < 0) {
+                                       DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d failed %d\n",
                                                __FUNCTION__, ocl_enable, ret));
-                       } else {
-                               DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d succeeded %d\n",
+                               } else {
+                                       DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d OK %d\n",
                                                __FUNCTION__, ocl_enable, ret));
+                               }
                        }
 #else
-                       if (ocl_enable == 0) {
-                               dhd->ocl_off = TRUE;
-                       } else {
-                               dhd->ocl_off = FALSE;
-                       }
+                       dhd->ocl_off = TRUE;
 #endif /* CUSTOM_SET_OCLOFF */
 #ifdef WLADPS
                        if ((ret = dhd_enable_adps(dhd, ADPS_DISABLE)) < 0) {
@@ -481,12 +511,13 @@ int dhd_sel_ant_from_file(dhd_pub_t *dhd)
        uint32 ant_val = 0;
        uint32 btc_mode = 0;
 #ifndef CUSTOM_SET_ANTNPM
-       uint32 rsdb_mode = 0;
+       wl_config_t rsdb_mode;
 #endif /* !CUSTOM_SET_ANTNPM */
        char *filepath = ANTINFO;
-       char iovbuf[WLC_IOCTL_SMLEN];
        uint chip_id = dhd_bus_chip_id(dhd);
-
+#ifndef CUSTOM_SET_ANTNPM
+        memset(&rsdb_mode, 0, sizeof(rsdb_mode));
+#endif /* CUSTOM_SET_ANTNPM */
        /* Check if this chip can support MIMO */
        if (chip_id != BCM4324_CHIP_ID &&
                chip_id != BCM4350_CHIP_ID &&
@@ -533,8 +564,8 @@ int dhd_sel_ant_from_file(dhd_pub_t *dhd)
 
        /* bt coex mode off */
        if (dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) {
-               bcm_mkiovar("btc_mode", (char *)&btc_mode, 4, iovbuf, sizeof(iovbuf));
-               ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+               ret = dhd_iovar(dhd, 0, "btc_mode", (char *)&btc_mode, sizeof(btc_mode), NULL, 0,
+                               TRUE);
                if (ret) {
                        DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
                                "btc_mode, ret=%d\n",
@@ -546,9 +577,8 @@ int dhd_sel_ant_from_file(dhd_pub_t *dhd)
 #ifndef CUSTOM_SET_ANTNPM
        /* rsdb mode off */
        DHD_ERROR(("[WIFI_SEC] %s: %s the RSDB mode!\n",
-               __FUNCTION__, rsdb_mode ? "Enable" : "Disable"));
-       bcm_mkiovar("rsdb_mode", (char *)&rsdb_mode, 4, iovbuf, sizeof(iovbuf));
-       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+               __FUNCTION__, rsdb_mode.config ? "Enable" : "Disable"));
+       ret = dhd_iovar(dhd, 0, "rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode), NULL, 0, TRUE);
        if (ret) {
                DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
                        "rsdb_mode, ret=%d\n", __FUNCTION__, ret));
@@ -556,16 +586,14 @@ int dhd_sel_ant_from_file(dhd_pub_t *dhd)
        }
 
        /* Select Antenna */
-       bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
-       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       ret = dhd_iovar(dhd, 0, "txchain", (char *)&ant_val, sizeof(ant_val), NULL, 0, TRUE);
        if (ret) {
                DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
                        __FUNCTION__, ret));
                return ret;
        }
 
-       bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
-       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       ret = dhd_iovar(dhd, 0, "rxchain", (char *)&ant_val, sizeof(ant_val), NULL, 0, TRUE);
        if (ret) {
                DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
                        __FUNCTION__, ret));
@@ -590,9 +618,11 @@ int dhd_rsdb_mode_from_file(dhd_pub_t *dhd)
 {
        struct file *fp = NULL;
        int ret = -1;
-       uint32 rsdb_mode = 0;
+       wl_config_t  rsdb_mode;
+       uint32 rsdb_configuration = 0;
        char *filepath = RSDBINFO;
-       char iovbuf[WLC_IOCTL_SMLEN];
+
+       memset(&rsdb_mode, 0, sizeof(rsdb_mode));
 
        /* Read RSDB on/off request from the file */
        fp = filp_open(filepath, O_RDONLY, 0);
@@ -600,32 +630,31 @@ int dhd_rsdb_mode_from_file(dhd_pub_t *dhd)
                DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
                return ret;
        } else {
-               ret = kernel_read(fp, 0, (char *)&rsdb_mode, 4);
+               ret = kernel_read(fp, 0, (char *)&rsdb_configuration, 4);
                if (ret < 0) {
                        DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
                        filp_close(fp, NULL);
                        return ret;
                }
 
-               rsdb_mode = bcm_atoi((char *)&rsdb_mode);
+               rsdb_mode.config = bcm_atoi((char *)&rsdb_configuration);
+               DHD_ERROR(("[WIFI_SEC] %s: RSDB mode from file = %d\n",
+                       __FUNCTION__, rsdb_mode.config));
 
-               DHD_ERROR(("[WIFI_SEC] %s: RSDB mode from file = %d\n", __FUNCTION__, rsdb_mode));
                filp_close(fp, NULL);
 
                /* Check value from the file */
-               if (rsdb_mode > 2) {
+               if (rsdb_mode.config > 2) {
                        DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
-                               __FUNCTION__, rsdb_mode, filepath));
+                               __FUNCTION__, rsdb_mode.config, filepath));
                        return -1;
                }
        }
 
-       if (rsdb_mode == 0) {
-               bcm_mkiovar("rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode),
-                       iovbuf, sizeof(iovbuf));
-
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+       if (rsdb_mode.config == 0) {
+               ret = dhd_iovar(dhd, 0, "rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode), NULL, 0,
+                               TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("[WIFI_SEC] %s: rsdb_mode ret= %d\n", __FUNCTION__, ret));
                } else {
                        DHD_ERROR(("[WIFI_SEC] %s: rsdb_mode to MIMO(RSDB OFF) succeeded\n",
@@ -724,7 +753,7 @@ int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val)
        }
        fp = filp_open(filepath, O_RDONLY, 0);
        if (IS_ERR(fp) || (fp == NULL)) {
-               DHD_ERROR(("[WIFI_SEC] %s: File open failed, file path=%s\n",
+               DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n",
                        __FUNCTION__, filepath));
                return BCME_ERROR;
        } else {
@@ -962,7 +991,8 @@ dhd_force_disable_singlcore_scan(dhd_pub_t *dhd)
 }
 #endif /* FORCE_DISABLE_SINGLECORE_SCAN */
 
-#if defined(ARGOS_CPU_SCHEDULER)
+#if defined(ARGOS_CPU_SCHEDULER) && defined(CONFIG_SCHED_HMP) && \
+       !defined(DHD_LB_IRQSET)
 void
 set_irq_cpucore(unsigned int irq, cpumask_var_t default_cpu_mask,
        cpumask_var_t affinity_cpu_mask)
@@ -1063,3 +1093,89 @@ void dhd_adps_mode_from_file(dhd_pub_t *dhd)
        return;
 }
 #endif /* ADPS_MODE_FROM_FILE */
+
+#ifdef GEN_SOFTAP_INFO_FILE
+#define SOFTAP_INFO_FILE_FIRST_LINE    "#.softap.info"
+#define SOFTAP_INFO_BUF_SZ     512
+/*
+ * # Whether both wifi and hotspot can be turned on at the same time?
+ * DualBandConcurrency
+ * # 5Ghz band support?
+ * 5G
+ * # How many clients can be connected?
+ * maxClient
+ * # Does hotspot support PowerSave mode?
+ * PowerSave
+ * # Does android_net_wifi_set_Country_Code_Hal feature supported?
+ * HalFn_setCountryCodeHal
+ * # Does android_net_wifi_getValidChannels supported?
+ * HalFn_getValidChannels
+ */
+const char *softap_info_items[] = {
+       "DualBandConcurrency", "5G", "maxClient", "PowerSave",
+       "HalFn_setCountryCodeHal", "HalFn_getValidChannels", NULL
+};
+#if defined(BCM4361_CHIP)
+const char *softap_info_values[] = {
+       "yes", "yes", "10", "yes", "yes", "yes", NULL
+};
+#elif defined(BCM43454_CHIP) || defined(BCM43455_CHIP) || defined(BCM43456_CHIP)
+const char *softap_info_values[] = {
+#ifdef WL_RESTRICTED_APSTA_SCC
+       "yes", "yes", "10", "no", "yes", "yes", NULL
+#else
+       "no", "yes", "10", "no", "yes", "yes", NULL
+#endif /* WL_RESTRICTED_APSTA_SCC */
+};
+#elif defined(BCM43430_CHIP)
+const char *softap_info_values[] = {
+       "no", "no", "10", "no", "yes", "yes", NULL
+};
+#else
+const char *softap_info_values[] = {
+       "UNDEF", "UNDEF", "UNDEF", "UNDEF", "UNDEF", "UNDEF", NULL
+};
+#endif /* defined(BCM4361_CHIP) */
+#endif /* GEN_SOFTAP_INFO_FILE */
+
+#ifdef GEN_SOFTAP_INFO_FILE
+uint32 sec_save_softap_info(void)
+{
+       struct file *fp = NULL;
+       char *filepath = SOFTAPINFO;
+       char temp_buf[SOFTAP_INFO_BUF_SZ];
+       int ret = -1, idx = 0, rem = 0, written = 0;
+       char *pos = NULL;
+
+       DHD_TRACE(("[WIFI_SEC] %s: Entered.\n", __FUNCTION__));
+       memset(temp_buf, 0, sizeof(temp_buf));
+
+       pos = temp_buf;
+       rem = sizeof(temp_buf);
+       written = snprintf(pos, sizeof(temp_buf), "%s\n",
+               SOFTAP_INFO_FILE_FIRST_LINE);
+       do {
+               int len = strlen(softap_info_items[idx]) +
+                       strlen(softap_info_values[idx]) + 2;
+               pos += written;
+               rem -= written;
+               if (len > rem) {
+                       break;
+               }
+               written = snprintf(pos, rem, "%s=%s\n",
+                       softap_info_items[idx], softap_info_values[idx]);
+       } while (softap_info_items[++idx] != NULL);
+
+       fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
+       if (IS_ERR(fp) || (fp == NULL)) {
+               DHD_ERROR(("[WIFI_SEC] %s: %s File open failed.\n",
+                       SOFTAPINFO, __FUNCTION__));
+       } else {
+               ret = write_filesystem(fp, fp->f_pos, temp_buf, strlen(temp_buf));
+               DHD_INFO(("[WIFI_SEC] %s done. ret : %d\n", __FUNCTION__, ret));
+               DHD_ERROR(("[WIFI_SEC] save %s file.\n", SOFTAPINFO));
+               filp_close(fp, NULL);
+       }
+       return ret;
+}
+#endif /* GEN_SOFTAP_INFO_FILE */
index 3f90c522936f2a5ba557aa753acf6643351fe921..1f3dd3af7a35af9dc0d7f279d83168313bf761b4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Debug/trace/assert driver definitions for Dongle Host Driver.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 7b7a0706f37f88ea0cb543bccc006cfd39945142..d222ee10818990216a71d81f4a3ed514f63e8092 100644 (file)
@@ -3,7 +3,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -23,7 +23,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_debug.c 669249 2016-11-08 16:53:57Z $
+ * $Id: dhd_debug.c 711908 2017-07-20 10:37:34Z $
  */
 
 #include <typedefs.h>
@@ -59,6 +59,7 @@
                status.verbose_level = ring->log_level; \
        } while (0)
 
+#define DHD_PKT_INFO DHD_ERROR
 struct map_table {
        uint16 fw_id;
        uint16 host_id;
@@ -129,7 +130,11 @@ struct log_level_table fw_verbose_level_map[] = {
        {2, EVENT_LOG_TAG_WL_ROAM_LOG, EVENT_LOG_SET_WL, "ROAM_LOG"},
        {1, EVENT_LOG_TAG_TRACE_WL_INFO, EVENT_LOG_SET_WL, "WL_INFO"},
        {1, EVENT_LOG_TAG_TRACE_BTCOEX_INFO, EVENT_LOG_SET_WL, "BTCOEX_INFO"},
+#ifdef CUSTOMER_HW4_DEBUG
+       {3, EVENT_LOG_TAG_SCAN_WARN, EVENT_LOG_SET_WL, "SCAN_WARN"},
+#else
        {1, EVENT_LOG_TAG_SCAN_WARN, EVENT_LOG_SET_WL, "SCAN_WARN"},
+#endif /* CUSTOMER_HW4_DEBUG */
        {1, EVENT_LOG_TAG_SCAN_ERROR, EVENT_LOG_SET_WL, "SCAN_ERROR"},
        {2, EVENT_LOG_TAG_SCAN_TRACE_LOW, EVENT_LOG_SET_WL, "SCAN_TRACE_LOW"},
        {2, EVENT_LOG_TAG_SCAN_TRACE_HIGH, EVENT_LOG_SET_WL, "SCAN_TRACE_HIGH"}
@@ -138,7 +143,11 @@ struct log_level_table fw_verbose_level_map[] = {
 struct log_level_table fw_event_level_map[] = {
        {1, EVENT_LOG_TAG_TRACE_WL_INFO, EVENT_LOG_SET_WL, "WL_INFO"},
        {1, EVENT_LOG_TAG_TRACE_BTCOEX_INFO, EVENT_LOG_SET_WL, "BTCOEX_INFO"},
+#ifdef CUSTOMER_HW4_DEBUG
+       {3, EVENT_LOG_TAG_BEACON_LOG, EVENT_LOG_SET_WL, "BEACON LOG"},
+#else
        {2, EVENT_LOG_TAG_BEACON_LOG, EVENT_LOG_SET_WL, "BEACON LOG"},
+#endif /* CUSTOMER_HW4_DEBUG */
 };
 
 struct map_table nan_event_map[] = {
@@ -233,6 +242,7 @@ dhd_dbg_ring_pull_single(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_le
                ASSERT(0);
                return 0;
        }
+
        memcpy(data, buf, rlen);
        /* update ring context */
        ring->rp += ENTRY_LENGTH(r_entry);
@@ -519,6 +529,14 @@ dhd_dbg_nan_event_handler(dhd_pub_t *dhdp, event_log_hdr_t *hdr, uint32 *data)
                        nan_hdr.version, DIAG_VERSION));
                return BCME_VERSION;
        }
+
+       /* nan event log should at least contain a wl_event_log_id_ver_t
+        * header and a arm cycle count
+        */
+       if (hdr->count < NAN_EVENT_LOG_MIN_LENGTH) {
+               return BCME_BADLEN;
+       }
+
        memset(&msg_hdr, 0, sizeof(dhd_dbg_ring_entry_t));
        ts_hdr = (event_log_hdr_t *)((uint8 *)data - sizeof(event_log_hdr_t));
        if (ts_hdr->tag == EVENT_LOG_TAG_TS) {
@@ -611,6 +629,13 @@ dhd_dbg_custom_evnt_handler(dhd_pub_t *dhdp, event_log_hdr_t *hdr, uint32 *data)
        if (wl_log_id.version != DIAG_VERSION)
                return BCME_VERSION;
 
+       /* custom event log should at least contain a wl_event_log_id_ver_t
+        * header and a arm cycle count
+        */
+       if (hdr->count < NAN_EVENT_LOG_MIN_LENGTH) {
+               return BCME_BADLEN;
+       }
+
        ts_hdr = (event_log_hdr_t *)((uint8 *)data - sizeof(event_log_hdr_t));
        if (ts_hdr->tag == EVENT_LOG_TAG_TS) {
                ts_data = (uint32 *)ts_hdr - ts_hdr->count;
@@ -825,8 +850,7 @@ dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, event_log_hdr_t *hdr,
        }
 
        /* print the message out in a logprint  */
-       if (!(((raw_event->raw_sstr) || (raw_event->rom_raw_sstr)) &&
-               raw_event->fmts) || hdr->fmt_num == 0xffff) {
+       if (!(raw_event->fmts) || hdr->fmt_num == 0xffff) {
                if (dhdp->dbg) {
                        log_level = dhdp->dbg->dbg_rings[FW_VERBOSE_RING_ID].log_level;
                        for (id = 0; id < ARRAYSIZE(fw_verbose_level_map); id++) {
@@ -938,7 +962,8 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
        msgtrace_hdr_t *hdr;
        char *data;
        int id;
-       uint32 hdrlen = sizeof(event_log_hdr_t);
+       uint32 log_hdr_len = sizeof(event_log_hdr_t);
+       uint32 log_pyld_len;
        static uint32 seqnum_prev = 0;
        event_log_hdr_t *log_hdr;
        bool msg_processed = FALSE;
@@ -950,6 +975,14 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
        char *logbuf;
        struct tracelog_header *logentry_header;
 
+       /* log trace event consists of:
+        * msgtrace header
+        * event log block header
+        * event log payload
+        */
+       if (datalen <= MSGTRACE_HDRLEN + EVENT_LOG_BLOCK_HDRLEN) {
+               return;
+       }
        hdr = (msgtrace_hdr_t *)event_data;
        data = (char *)event_data + MSGTRACE_HDRLEN;
        datalen -= MSGTRACE_HDRLEN;
@@ -967,6 +1000,14 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
        logentry_header->buf_size = datalen;
        logentry_header->seq_num = hdr->seqnum;
        msg_hdr.type = DBG_RING_ENTRY_DATA_TYPE;
+
+       if ((sizeof(*logentry_header) + datalen) > PAYLOAD_MAX_LEN) {
+               DHD_ERROR(("%s:Payload len=%u exceeds max len\n", __FUNCTION__,
+                       ((uint)sizeof(*logentry_header) + datalen)));
+               VMFREE(dhdp->osh, logbuf, sizeof(*logentry_header) + datalen);
+               return;
+       }
+
        msg_hdr.len = sizeof(*logentry_header) + datalen;
        memcpy(logbuf + sizeof(*logentry_header), data, datalen);
        dhd_dbg_ring_push(dhdp, FW_VERBOSE_RING_ID, &msg_hdr, logbuf);
@@ -979,8 +1020,8 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
        DHD_MSGTRACE_LOG(("EVENT_LOG_HDR[0x%x]: Set: 0x%08x length = %d\n",
                ltoh16(*((uint16 *)(data+2))), ltoh32(*((uint32 *)(data + 4))),
                ltoh16(*((uint16 *)(data)))));
-       data += 8;
-       datalen -= 8;
+       data += EVENT_LOG_BLOCK_HDRLEN;
+       datalen -= EVENT_LOG_BLOCK_HDRLEN;
 
        /* start parsing from the tail of packet
         * Sameple format of a meessage
@@ -989,27 +1030,36 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
         * 0x0c580439 -- 39 is tag, 04 is count, 580c is format number
         * all these uint32 values comes in reverse order as group as EL data
         * while decoding we can only parse from last to first
+        * |<-                     datalen                     ->|
+        * |----(payload and maybe more logs)----|event_log_hdr_t|
+        * data                                  log_hdr
         */
        dll_init(&list_head);
-       while (datalen > 0) {
-               log_hdr = (event_log_hdr_t *)(data + datalen - hdrlen);
-               /* pratially overwritten entries */
-               if ((uint32 *)log_hdr - (uint32 *)data < log_hdr->count)
-                       break;
-               /* Check argument count (only when format is valid) */
-               if ((log_hdr->count > MAX_NO_OF_ARG) &&
-                   (log_hdr->fmt_num != 0xffff))
-                       break;
-               /* end of frame? */
+       while (datalen > log_hdr_len) {
+               log_hdr = (event_log_hdr_t *)(data + datalen - log_hdr_len);
+               /* skip zero padding at end of frame */
                if (log_hdr->tag == EVENT_LOG_TAG_NULL) {
-                       log_hdr--;
-                       datalen -= hdrlen;
+                       datalen -= log_hdr_len;
                        continue;
                }
+               /* Check argument count, any event log should contain at least
+                * one argument (4 bytes) for arm cycle count and up to 16
+                * arguments when the format is valid
+                */
+               if (log_hdr->count == 0) {
+                       break;
+               }
+               if ((log_hdr->count > MAX_NO_OF_ARG) && (log_hdr->fmt_num != 0xffff)) {
+                       break;
+               }
+
+               log_pyld_len = log_hdr->count * DATA_UNIT_FOR_LOG_CNT;
+               /* log data should not cross the event data boundary */
+               if ((char *)log_hdr - data < log_pyld_len)
+                       break;
                /* skip 4 bytes time stamp packet */
                if (log_hdr->tag == EVENT_LOG_TAG_TS) {
-                       datalen -= log_hdr->count * 4 + hdrlen;
-                       log_hdr -= log_hdr->count + hdrlen / 4;
+                       datalen -= log_pyld_len + log_hdr_len;
                        continue;
                }
                if (!(log_item = MALLOC(dhdp->osh, sizeof(*log_item)))) {
@@ -1019,7 +1069,7 @@ dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
                }
                log_item->hdr = log_hdr;
                dll_insert(&log_item->list, &list_head);
-               datalen -= (log_hdr->count * 4 + hdrlen);
+               datalen -= (log_pyld_len + log_hdr_len);
        }
 
        while (!dll_empty(&list_head)) {
@@ -1399,8 +1449,8 @@ dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len)
        return ret;
 }
 
-#ifdef DBG_PKT_MON
-static uint32
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
+uint32
 __dhd_dbg_pkt_hash(uintptr_t pkt, uint32 pktid)
 {
        uint32 __pkt;
@@ -1416,7 +1466,7 @@ __dhd_dbg_pkt_hash(uintptr_t pkt, uint32 pktid)
 #define __TIMESPEC_TO_US(ts) \
        (((uint32)(ts).tv_sec * USEC_PER_SEC) + ((ts).tv_nsec / NSEC_PER_USEC))
 
-static uint32
+uint32
 __dhd_dbg_driver_ts_usec(void)
 {
        struct timespec ts;
@@ -1425,7 +1475,7 @@ __dhd_dbg_driver_ts_usec(void)
        return ((uint32)(__TIMESPEC_TO_US(ts)));
 }
 
-static wifi_tx_packet_fate
+wifi_tx_packet_fate
 __dhd_dbg_map_tx_status_to_pkt_fate(uint16 status)
 {
        wifi_tx_packet_fate pkt_fate;
@@ -1452,13 +1502,16 @@ __dhd_dbg_map_tx_status_to_pkt_fate(uint16 status)
 
        return pkt_fate;
 }
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
 
+#ifdef DBG_PKT_MON
 static int
 __dhd_dbg_free_tx_pkts(dhd_pub_t *dhdp, dhd_dbg_tx_info_t *tx_pkts,
        uint16 pkt_count)
 {
        uint16 count;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        count = 0;
        while ((count < pkt_count) && tx_pkts) {
                if (tx_pkts->info.pkt)
@@ -1476,6 +1529,7 @@ __dhd_dbg_free_rx_pkts(dhd_pub_t *dhdp, dhd_dbg_rx_info_t *rx_pkts,
 {
        uint16 count;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        count = 0;
        while ((count < pkt_count) && rx_pkts) {
                if (rx_pkts->info.pkt)
@@ -1543,13 +1597,16 @@ dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
        gfp_t kflags;
        uint32 alloc_len;
        int ret = BCME_OK;
+       unsigned long flags;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
                        dhdp, (dhdp ? dhdp->dbg : NULL)));
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        tx_status_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
@@ -1559,6 +1616,7 @@ dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
                DHD_PKT_MON(("%s(): packet monitor is already attached, "
                        "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
                        __FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                /* return success as the intention was to initialize packet monitor */
                return BCME_OK;
        }
@@ -1587,8 +1645,8 @@ dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
        dhdp->dbg->pkt_mon.tx_report->tx_pkts = tx_pkts;
        dhdp->dbg->pkt_mon.tx_pkt_mon = tx_pkt_mon;
        dhdp->dbg->pkt_mon.tx_status_mon = tx_status_mon;
-       dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STARTED;
-       dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STARTED;
+       dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_ATTACHED;
+       dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_ATTACHED;
 
        /* allocate and initialze rx packet monitoring */
        alloc_len = sizeof(*rx_report);
@@ -1611,8 +1669,9 @@ dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
        dhdp->dbg->pkt_mon.rx_report = rx_report;
        dhdp->dbg->pkt_mon.rx_report->rx_pkts = rx_pkts;
        dhdp->dbg->pkt_mon.rx_pkt_mon = rx_pkt_mon;
-       dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STARTED;
+       dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_ATTACHED;
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        DHD_PKT_MON(("%s(): packet monitor attach succeeded\n", __FUNCTION__));
        return ret;
 
@@ -1643,6 +1702,7 @@ fail:
        dhdp->dbg->pkt_mon.rx_pkt_mon = NULL;
        dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_DETACHED;
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        DHD_ERROR(("%s(): packet monitor attach failed\n", __FUNCTION__));
        return ret;
 }
@@ -1655,13 +1715,16 @@ dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
        dhd_dbg_pkt_mon_state_t tx_pkt_state;
        dhd_dbg_pkt_mon_state_t tx_status_state;
        dhd_dbg_pkt_mon_state_t rx_pkt_state;
+       unsigned long flags;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
                        dhdp, (dhdp ? dhdp->dbg : NULL)));
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
        rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
@@ -1671,24 +1734,32 @@ dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
                DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
                        "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
                        __FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                return -EINVAL;
        }
 
+       dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STARTING;
+       dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STARTING;
+       dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STARTING;
+
        tx_report = dhdp->dbg->pkt_mon.tx_report;
        rx_report = dhdp->dbg->pkt_mon.rx_report;
        if (!tx_report || !rx_report) {
                DHD_PKT_MON(("%s(): tx_report=%p, rx_report=%p\n",
                        __FUNCTION__, tx_report, rx_report));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                return -EINVAL;
        }
 
-       if (PKT_MON_STOPPED(tx_pkt_state) || PKT_MON_STOPPED(tx_status_state)) {
-               __dhd_dbg_free_tx_pkts(dhdp, tx_report->tx_pkts, tx_report->pkt_pos);
-       }
 
-       if (PKT_MON_STOPPED(rx_pkt_state)) {
-               __dhd_dbg_free_rx_pkts(dhdp, rx_report->rx_pkts, rx_report->pkt_pos);
-       }
+       tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+       tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+       rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+
+       /* Safe to free packets as state pkt_state is STARTING */
+       __dhd_dbg_free_tx_pkts(dhdp, tx_report->tx_pkts, tx_report->pkt_pos);
+
+       __dhd_dbg_free_rx_pkts(dhdp, rx_report->rx_pkts, rx_report->pkt_pos);
 
        /* reset array postion */
        tx_report->pkt_pos = 0;
@@ -1698,6 +1769,7 @@ dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
 
        rx_report->pkt_pos = 0;
        dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STARTED;
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
 
        DHD_PKT_MON(("%s(): packet monitor started\n", __FUNCTION__));
        return BCME_OK;
@@ -1711,6 +1783,7 @@ dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid)
        dhd_dbg_pkt_mon_state_t tx_pkt_state;
        uint32 pkt_hash, driver_ts;
        uint16 pkt_pos;
+       unsigned long flags;
 
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
@@ -1718,6 +1791,7 @@ dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid)
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        if (PKT_MON_STARTED(tx_pkt_state)) {
                tx_report = dhdp->dbg->pkt_mon.tx_report;
@@ -1744,6 +1818,7 @@ dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid)
                }
        }
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        return BCME_OK;
 }
 
@@ -1759,6 +1834,7 @@ dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
        uint16 pkt_pos, status_pos;
        int16 count;
        bool found = FALSE;
+       unsigned long flags;
 
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
@@ -1766,6 +1842,7 @@ dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
        if (PKT_MON_STARTED(tx_status_state)) {
                tx_report = dhdp->dbg->pkt_mon.tx_report;
@@ -1821,6 +1898,7 @@ dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
                }
        }
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        return BCME_OK;
 }
 
@@ -1832,6 +1910,7 @@ dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt)
        dhd_dbg_pkt_mon_state_t rx_pkt_state;
        uint32 driver_ts;
        uint16 pkt_pos;
+       unsigned long flags;
 
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
@@ -1839,6 +1918,7 @@ dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt)
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
        if (PKT_MON_STARTED(rx_pkt_state)) {
                rx_report = dhdp->dbg->pkt_mon.rx_report;
@@ -1864,6 +1944,7 @@ dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt)
                }
        }
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        return BCME_OK;
 }
 
@@ -1873,13 +1954,16 @@ dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp)
        dhd_dbg_pkt_mon_state_t tx_pkt_state;
        dhd_dbg_pkt_mon_state_t tx_status_state;
        dhd_dbg_pkt_mon_state_t rx_pkt_state;
+       unsigned long flags;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
                        dhdp, (dhdp ? dhdp->dbg : NULL)));
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
        rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
@@ -1889,12 +1973,13 @@ dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp)
                DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
                        "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
                        __FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                return -EINVAL;
        }
-
        dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STOPPED;
        dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STOPPED;
        dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STOPPED;
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
 
        DHD_PKT_MON(("%s(): packet monitor stopped\n", __FUNCTION__));
        return BCME_OK;
@@ -1923,7 +2008,9 @@ dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
        dhd_dbg_pkt_mon_state_t tx_pkt_state;
        dhd_dbg_pkt_mon_state_t tx_status_state;
        uint16 pkt_count, count;
+       unsigned long flags;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        BCM_REFERENCE(ptr);
        BCM_REFERENCE(cptr);
 
@@ -1933,12 +2020,15 @@ dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
-       if (PKT_MON_DETACHED(tx_pkt_state) || PKT_MON_DETACHED(tx_status_state)) {
+       if (PKT_MON_NOT_OPERATIONAL(tx_pkt_state) ||
+                       PKT_MON_NOT_OPERATIONAL(tx_status_state)) {
                DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
                        "tx_pkt_state=%d, tx_status_state=%d\n", __FUNCTION__,
                        tx_pkt_state, tx_status_state));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                return -EINVAL;
        }
 
@@ -1992,6 +2082,7 @@ dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
        }
        *resp_count = pkt_count;
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        if (!pkt_count) {
                DHD_ERROR(("%s(): no tx_status in tx completion messages, "
                        "make sure that 'd11status' is enabled in firmware, "
@@ -2011,7 +2102,9 @@ dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
        compat_wifi_rx_report_t *cptr;
        dhd_dbg_pkt_mon_state_t rx_pkt_state;
        uint16 pkt_count, count;
+       unsigned long flags;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        BCM_REFERENCE(ptr);
        BCM_REFERENCE(cptr);
 
@@ -2021,10 +2114,12 @@ dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
-       if (PKT_MON_DETACHED(rx_pkt_state)) {
-               DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
+       if (PKT_MON_NOT_OPERATIONAL(rx_pkt_state)) {
+               DHD_PKT_MON(("%s(): packet fetch is not allowed , "
                        "rx_pkt_state=%d\n", __FUNCTION__, rx_pkt_state));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                return -EINVAL;
        }
 
@@ -2078,6 +2173,7 @@ dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
        }
 
        *resp_count = pkt_count;
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
 
        return BCME_OK;
 }
@@ -2090,13 +2186,16 @@ dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp)
        dhd_dbg_pkt_mon_state_t tx_pkt_state;
        dhd_dbg_pkt_mon_state_t tx_status_state;
        dhd_dbg_pkt_mon_state_t rx_pkt_state;
+       unsigned long flags;
 
+       DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
        if (!dhdp || !dhdp->dbg) {
                DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
                        dhdp, (dhdp ? dhdp->dbg : NULL)));
                return -EINVAL;
        }
 
+       DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
        tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
        tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
        rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
@@ -2106,6 +2205,7 @@ dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp)
                DHD_PKT_MON(("%s(): packet monitor is already detached, "
                        "tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
                        __FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+               DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
                return -EINVAL;
        }
 
@@ -2142,6 +2242,7 @@ dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp)
        }
        dhdp->dbg->pkt_mon.rx_pkt_mon = NULL;
 
+       DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
        DHD_PKT_MON(("%s(): packet monitor detach succeeded\n", __FUNCTION__));
        return BCME_OK;
 }
index d27e5e05fbb8cb8e94a2e2c4d53e145ba6537073..5e1d8e8144d7163668b0074d6ba028bd71602107 100644 (file)
@@ -3,7 +3,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -23,7 +23,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_debug.h 674228 2016-12-07 12:21:41Z $
+ * $Id: dhd_debug.h 705824 2017-06-19 13:58:39Z $
  */
 
 #ifndef _dhd_debug_h_
@@ -344,7 +344,7 @@ enum {
 };
 
 typedef struct dhd_dbg_ring_entry {
-       uint32 len; /* payload length excluding the header */
+       uint16 len; /* payload length excluding the header */
        uint8 flags;
        uint8 type; /* Per ring specific */
        uint64 timestamp; /* present if has_timestamp bit is set. */
@@ -354,6 +354,8 @@ typedef struct dhd_dbg_ring_entry {
 
 #define ENTRY_LENGTH(hdr) ((hdr)->len + DBG_RING_ENTRY_SIZE)
 
+#define PAYLOAD_MAX_LEN 65535
+
 typedef struct dhd_dbg_ring_status {
        uint8 name[DBGRING_NAME_MAX];
        uint32 flags;
@@ -393,6 +395,7 @@ struct log_level_table {
 
 #define MD5_PREFIX_LEN                         4
 #define MAX_FATE_LOG_LEN                       32
+
 #define MAX_FRAME_LEN_ETHERNET         1518
 #define MAX_FRAME_LEN_80211_MGMT       2352 /* 802.11-2012 Fig. 8-34 */
 
@@ -599,7 +602,9 @@ typedef struct compat_wifi_rx_report {
 typedef enum dhd_dbg_pkt_mon_state {
        PKT_MON_INVALID = 0,
        PKT_MON_ATTACHED,
+       PKT_MON_STARTING,
        PKT_MON_STARTED,
+       PKT_MON_STOPPING,
        PKT_MON_STOPPED,
        PKT_MON_DETACHED,
        } dhd_dbg_pkt_mon_state_t;
@@ -704,16 +709,21 @@ typedef struct dhd_dbg {
        dhd_dbg_ring_t dbg_rings[DEBUG_RING_ID_MAX];
        void *private;          /* os private_data */
        dhd_dbg_pkt_mon_t pkt_mon;
+       void *pkt_mon_lock; /* spin lock for packet monitoring */
        dbg_pullreq_t pullreq;
        dbg_urgent_noti_t urgent_notifier;
 } dhd_dbg_t;
 
 #define PKT_MON_ATTACHED(state) \
-               (((state) != PKT_MON_INVALID) && ((state) != PKT_MON_DETACHED))
+               (((state) > PKT_MON_INVALID) && ((state) < PKT_MON_DETACHED))
 #define PKT_MON_DETACHED(state) \
                (((state) == PKT_MON_INVALID) || ((state) == PKT_MON_DETACHED))
 #define PKT_MON_STARTED(state) ((state) == PKT_MON_STARTED)
 #define PKT_MON_STOPPED(state) ((state) == PKT_MON_STOPPED)
+#define PKT_MON_NOT_OPERATIONAL(state) \
+       (((state) != PKT_MON_STARTED) && ((state) != PKT_MON_STOPPED))
+#define PKT_MON_SAFE_TO_FREE(state) \
+       (((state) == PKT_MON_STARTING) || ((state) == PKT_MON_STOPPED))
 #define PKT_MON_PKT_FULL(pkt_count) ((pkt_count) >= MAX_FATE_LOG_LEN)
 #define PKT_MON_STATUS_FULL(pkt_count, status_count) \
                (((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN))
index 32e514ca98ca8d0ced0ccb301019914a36a91b38..6600d3a0b75f35240a20fdb38b954333c18fe6bc 100644 (file)
@@ -3,7 +3,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -23,7 +23,7 @@
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
- * $Id: dhd_debug_linux.c 669249 2016-11-08 16:53:57Z $
+ * $Id: dhd_debug_linux.c 744879 2018-02-06 02:45:32Z $
  */
 
 #include <typedefs.h>
@@ -288,7 +288,8 @@ dhd_os_suppress_logging(dhd_pub_t *dhdp, bool suppress)
                os_priv[FW_EVENT_RING_ID].log_level);
        if (max_log_level == SUPPRESS_LOG_LEVEL) {
                /* suppress the logging in FW not to wake up host while device in suspend mode */
-               ret = dhd_iovar(dhdp, 0, "logtrace", (char *)&enable, sizeof(enable), 1);
+               ret = dhd_iovar(dhdp, 0, "logtrace", (char *)&enable, sizeof(enable), NULL, 0,
+                               TRUE);
                if (ret < 0 && (ret != BCME_UNSUPPORTED)) {
                        DHD_ERROR(("logtrace is failed : %d\n", ret));
                }
@@ -435,6 +436,7 @@ dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features)
 {
        int ret = BCME_OK;
        *features = 0;
+#ifdef DEBUGABILITY
        *features |= DBG_MEMORY_DUMP_SUPPORTED;
        if (FW_SUPPORTED(dhdp, logtrace)) {
                *features |= DBG_CONNECT_EVENT_SUPPORTED;
@@ -448,6 +450,7 @@ dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features)
                *features |= DBG_PACKET_FATE_SUPPORTED;
        }
 #endif /* DBG_PKT_MON */
+#endif /* DEBUGABILITY */
        return ret;
 }
 
index 2fa7067279ee3cc0da60bb0d32508154cc06af38..7be798db5ea766f8d551b666fdd558093d05d67f 100644 (file)
@@ -4,7 +4,7 @@
  * Flow rings are transmit traffic (=propagating towards antenna) related entities
  *
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_flowring.c 676811 2016-12-24 20:48:46Z $
+ * $Id: dhd_flowring.c 710862 2017-07-14 07:43:59Z $
  */
 
 
@@ -1043,7 +1043,7 @@ int dhd_update_flow_prio_map(dhd_pub_t *dhdp, uint8 map)
 /** Inform firmware on updated flow priority mapping, called on IOVAR */
 int dhd_flow_prio_map(dhd_pub_t *dhd, uint8 *map, bool set)
 {
-       uint8 iovbuf[24];
+       uint8 iovbuf[24] = {0};
        if (!set) {
                bcm_mkiovar("bus:fl_prio_map", NULL, 0, (char*)iovbuf, sizeof(iovbuf));
                if (dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0) < 0) {
index d5faf0aa8cf359ff96acbb8e3c7063041b62d0a5..aa79e48b5cbfb2e287517d64b21adf430e57547f 100644 (file)
@@ -6,7 +6,7 @@
  * Provides type definitions and function prototypes used to create, delete and manage flow rings at
  * high level.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 42b2aafce27cfa6dcc515ec69e900bd4b6911be9..31608305aa14d2e2fb1d3b6d2e68450d35a629a9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * IP Packet Parser Module.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_ip.c 676811 2016-12-24 20:48:46Z $
+ * $Id: dhd_ip.c 700317 2017-05-18 15:13:29Z $
  */
 #include <typedefs.h>
 #include <osl.h>
@@ -209,7 +209,6 @@ _tdata_psh_info_pool_deq(tcpack_sup_module_t *tcpack_sup_mod)
        return tdata_psh_info;
 }
 
-#ifdef DHDTCPACK_SUPPRESS
 static int _tdata_psh_info_pool_init(dhd_pub_t *dhdp,
        tcpack_sup_module_t *tcpack_sup_mod)
 {
@@ -287,7 +286,6 @@ static void _tdata_psh_info_pool_deinit(dhd_pub_t *dhdp,
 
        return;
 }
-#endif /* DHDTCPACK_SUPPRESS */
 
 static void dhd_tcpack_send(ulong data)
 {
@@ -341,92 +339,136 @@ int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
        int ret = BCME_OK;
        unsigned long flags;
        tcpack_sup_module_t *tcpack_sup_module;
+       uint8 invalid_mode = FALSE;
+       int prev_mode;
+       int i = 0;
 
        flags = dhd_os_tcpacklock(dhdp);
        tcpack_sup_module = dhdp->tcpack_sup_module;
+       prev_mode = dhdp->tcpack_sup_mode;
 
-       if (dhdp->tcpack_sup_mode == mode) {
+       /* Check a new mode */
+       if (prev_mode == mode) {
                DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode));
                goto exit;
        }
 
-       if (mode >= TCPACK_SUP_LAST_MODE) {
-               DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode));
+       invalid_mode |= (mode >= TCPACK_SUP_LAST_MODE);
+#ifdef BCMSDIO
+       invalid_mode |= (mode == TCPACK_SUP_HOLD);
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+       invalid_mode |= ((mode == TCPACK_SUP_REPLACE) || (mode == TCPACK_SUP_DELAYTX));
+#endif /* BCMPCIE */
+
+       if (invalid_mode) {
+               DHD_ERROR(("%s %d: Invalid TCP ACK Suppress mode %d\n",
+                       __FUNCTION__, __LINE__, mode));
                ret = BCME_BADARG;
                goto exit;
        }
 
-       DHD_TRACE(("%s: %d -> %d\n",
+       DHD_TRACE(("%s: TCP ACK Suppress mode %d -> mode %d\n",
                __FUNCTION__, dhdp->tcpack_sup_mode, mode));
 
-#ifdef DHDTCPACK_SUPPRESS
-       /* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */
-       if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) {
-               /* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */
-               _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_module);
-               tcpack_sup_module->tcpdata_info_cnt = 0;
-               bzero(tcpack_sup_module->tcpdata_info_tbl,
-                       sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
-               /* For half duplex bus interface, tx precedes rx by default */
-               if (dhdp->bus)
-                       dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
-       }
-#endif /* DHDTCPACK_SUPPRESS */
-       dhdp->tcpack_sup_mode = mode;
-
-       if (mode == TCPACK_SUP_OFF) {
-               int i;
-               ASSERT(tcpack_sup_module != NULL);
-               /* Clean up timer/data structure for any remaining/pending packet or timer. */
-               if (tcpack_sup_module) {
-                       for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
-                               del_timer(&tcpack_sup_module->tcpack_info_tbl[i].timer);
-                               if (tcpack_sup_module->tcpack_info_tbl[i].pkt_in_q) {
-                                       PKTFREE(dhdp->osh,
-                                               tcpack_sup_module->tcpack_info_tbl[i].pkt_in_q,
-                                               TRUE);
+       /* Pre-process routines to change a new mode as per previous mode */
+       switch (prev_mode) {
+               case TCPACK_SUP_OFF:
+                       if (tcpack_sup_module == NULL) {
+                               tcpack_sup_module = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
+                               if (tcpack_sup_module == NULL) {
+                                       DHD_ERROR(("%s[%d]: Failed to allocate the new memory for "
+                                               "tcpack_sup_module\n", __FUNCTION__, __LINE__));
+                                       dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
+                                       ret = BCME_NOMEM;
+                                       goto exit;
                                }
+                               dhdp->tcpack_sup_module = tcpack_sup_module;
+                       }
+                       bzero(tcpack_sup_module, sizeof(tcpack_sup_module_t));
+                       break;
+               case TCPACK_SUP_DELAYTX:
+                       if (tcpack_sup_module) {
+                               /* We won't need tdata_psh_info pool and
+                                * tcpddata_info_tbl anymore
+                                */
+                               _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_module);
+                               tcpack_sup_module->tcpdata_info_cnt = 0;
+                               bzero(tcpack_sup_module->tcpdata_info_tbl,
+                                       sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
                        }
-               }
-               MFREE(dhdp->osh, tcpack_sup_module, sizeof(tcpack_sup_module_t));
-               dhdp->tcpack_sup_module = NULL;
-               goto exit;
-       }
 
-       if (tcpack_sup_module == NULL) {
-               tcpack_sup_module = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
-               if (tcpack_sup_module == NULL) {
-                       DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__));
-                       dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
-                       ret = BCME_NOMEM;
-                       goto exit;
-               }
-               bzero(tcpack_sup_module, sizeof(tcpack_sup_module_t));
-               dhdp->tcpack_sup_module = tcpack_sup_module;
-       }
+                       /* For half duplex bus interface, tx precedes rx by default */
+                       if (dhdp->bus) {
+                               dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
+                       }
 
-#ifdef DHDTCPACK_SUPPRESS
-       if (mode == TCPACK_SUP_DELAYTX) {
-               ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module);
-               if (ret != BCME_OK)
-                       DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret));
-               else if (dhdp->bus)
-                       dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
+                       if (tcpack_sup_module == NULL) {
+                               DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n",
+                                       __FUNCTION__, __LINE__));
+                               dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
+                               goto exit;
+                       }
+                       break;
        }
-#endif /* DHDTCPACK_SUPPRESS */
 
-       if (mode == TCPACK_SUP_HOLD) {
-               int i;
-               dhdp->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO;
-               dhdp->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME;
-               for (i = 0; i < TCPACK_INFO_MAXNUM; i++)
-               {
-                       tcpack_sup_module->tcpack_info_tbl[i].dhdp = dhdp;
-                       init_timer(&tcpack_sup_module->tcpack_info_tbl[i].timer);
-                       tcpack_sup_module->tcpack_info_tbl[i].timer.data =
-                               (ulong)&tcpack_sup_module->tcpack_info_tbl[i];
-                       tcpack_sup_module->tcpack_info_tbl[i].timer.function = dhd_tcpack_send;
-               }
+       /* Update a new mode */
+       dhdp->tcpack_sup_mode = mode;
+
+       /* Process for a new mode */
+       switch (mode) {
+               case TCPACK_SUP_OFF:
+                       ASSERT(tcpack_sup_module != NULL);
+                       /* Clean up timer/data structure for
+                        * any remaining/pending packet or timer.
+                        */
+                       if (tcpack_sup_module) {
+                               /* Check if previous mode is TCAPACK_SUP_HOLD */
+                               if (prev_mode == TCPACK_SUP_HOLD) {
+                                       for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+                                               tcpack_info_t *tcpack_info_tbl =
+                                                       &tcpack_sup_module->tcpack_info_tbl[i];
+                                               del_timer(&tcpack_info_tbl->timer);
+                                               if (tcpack_info_tbl->pkt_in_q) {
+                                                       PKTFREE(dhdp->osh,
+                                                               tcpack_info_tbl->pkt_in_q, TRUE);
+                                                       tcpack_info_tbl->pkt_in_q = NULL;
+                                               }
+                                       }
+                               }
+                               MFREE(dhdp->osh, tcpack_sup_module, sizeof(tcpack_sup_module_t));
+                               dhdp->tcpack_sup_module = NULL;
+                       } else {
+                               DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n",
+                                       __FUNCTION__, __LINE__));
+                       }
+                       break;
+               case TCPACK_SUP_REPLACE:
+                       /* There is nothing to configure for this mode */
+                       break;
+               case TCPACK_SUP_DELAYTX:
+                       ret = _tdata_psh_info_pool_init(dhdp, tcpack_sup_module);
+                       if (ret != BCME_OK) {
+                               DHD_ERROR(("%s %d: pool init fail with %d\n",
+                                       __FUNCTION__, __LINE__, ret));
+                               break;
+                       }
+                       if (dhdp->bus) {
+                               dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
+                       }
+                       break;
+               case TCPACK_SUP_HOLD:
+                       dhdp->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO;
+                       dhdp->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME;
+                       for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+                               tcpack_info_t *tcpack_info_tbl =
+                                       &tcpack_sup_module->tcpack_info_tbl[i];
+                               tcpack_info_tbl->dhdp = dhdp;
+                               init_timer(&tcpack_info_tbl->timer);
+                               tcpack_info_tbl->timer.data = (ulong)tcpack_info_tbl;
+                               tcpack_info_tbl->timer.function = dhd_tcpack_send;
+                       }
+                       break;
        }
 
 exit:
index 240d852151f4eb6b40154072d0b3973777111503..3af25f0f1cf5c77e4fdeec61e948493366f1e822 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Provides type definitions and function prototypes used to parse ip packet.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 32548b80044e331b946e54eb1b717458efd4401c..ad8f7df6b8b5f947b202e9b55b8a535f98bf8008 100644 (file)
@@ -2,7 +2,7 @@
  * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
  * Basically selected code segments from usb-cdc.c and usb-rndis.c
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -25,7 +25,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_linux.c 684400 2017-02-13 07:55:10Z $
+ * $Id: dhd_linux.c 752171 2018-03-15 02:55:35Z $
  */
 
 #include <typedefs.h>
@@ -56,7 +56,9 @@
 #ifdef ENABLE_ADAPTIVE_SCHED
 #include <linux/cpufreq.h>
 #endif /* ENABLE_ADAPTIVE_SCHED */
-
+#ifdef DHD_DUMP_MNGR
+#include <linux/namei.h>
+#endif /* DHD_DUMP_MNGR */
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 #include <dhd_ip.h>
 #endif /* DHDTCPACK_SUPPRESS */
 #include <dhd_daemon.h>
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+#if defined(STAT_REPORT)
+#include <wl_statreport.h>
+#endif /* STAT_REPORT */
 #ifdef DHD_DEBUG_PAGEALLOC
 typedef void (*page_corrupt_cb_t)(void *handle, void *addr_corrupt, size_t len);
 void dhd_page_corrupt_cb(void *handle, void *addr_corrupt, size_t len);
@@ -314,6 +322,10 @@ static void dhd_hang_process(void *dhd_info, void *event_data, u8 event);
 MODULE_LICENSE("GPL and additional rights");
 #endif /* LinuxVer */
 
+#ifdef CONFIG_BCM_DETECT_CONSECUTIVE_HANG
+#define MAX_CONSECUTIVE_HANG_COUNTS 5
+#endif /* CONFIG_BCM_DETECT_CONSECUTIVE_HANG */
+
 #include <dhd_bus.h>
 
 #ifdef DHD_ULP
@@ -407,18 +419,22 @@ extern int dhd_logtrace_from_file(dhd_pub_t *dhd);
 #ifdef ADPS_MODE_FROM_FILE
 extern int dhd_adps_mode_from_file(dhd_pub_t *dhd);
 #endif
+#ifdef GEN_SOFTAP_INFO_FILE
+extern uint32 sec_save_softap_info(void);
+#endif
 #endif /* CUSTOMER_HW4 */
 
-#ifdef ARGOS_CPU_SCHEDULER
+#if defined(ARGOS_CPU_SCHEDULER) && defined(CONFIG_SCHED_HMP) && \
+       !defined(DHD_LB_IRQSET)
 extern int argos_task_affinity_setup_label(struct task_struct *p, const char *label,
        struct cpumask * affinity_cpu_mask, struct cpumask * default_cpu_mask);
 extern struct cpumask hmp_slow_cpu_mask;
 extern struct cpumask hmp_fast_cpu_mask;
 extern void set_irq_cpucore(unsigned int irq, cpumask_var_t default_cpu_mask,
        cpumask_var_t affinity_cpu_mask);
-#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* ARGOS_CPU_SCHEDULER && CONFIG_SCHED_HMP && !DHD_LB_IRQSET */
 
-#if defined(ARGOS_CPU_SCHEDULER) && defined(ARGOS_RPS_CPU_CTL)
+#if defined(ARGOS_CPU_SCHEDULER)
 int argos_register_notifier_init(struct net_device *net);
 int argos_register_notifier_deinit(void);
 
@@ -430,9 +446,17 @@ static int argos_status_notifier_wifi_cb(struct notifier_block *notifier,
 static int argos_status_notifier_p2p_cb(struct notifier_block *notifier,
        unsigned long speed, void *v);
 
-/* ARGOS notifer data */
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+static int argos_status_notifier_config_mumimo_cb(struct notifier_block *notifier,
+       unsigned long speed, void *v);
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
+
+/* ARGOS notifier data */
 static struct notifier_block argos_wifi; /* STA */
 static struct notifier_block argos_p2p; /* P2P */
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+static struct notifier_block argos_mimo; /* STA */
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
 
 typedef struct {
        struct net_device *wlan_primary_netdev;
@@ -440,9 +464,30 @@ typedef struct {
 } argos_rps_ctrl;
 
 argos_rps_ctrl argos_rps_ctrl_data;
-#define RPS_TPUT_THRESHOLD             300
-#define DELAY_TO_CLEAR_RPS_CPUS                300
-#endif /* ARGOS_RPS_CPU_CTL && ARGOS_CPU_SCHEDULER */
+
+#ifdef DYNAMIC_MUMIMO_CONTROL
+typedef struct {
+       struct timer_list config_timer;
+       struct work_struct mumimo_ctrl_work;
+       struct net_device *dev;
+       int cur_murx_bfe_cap;
+} argos_mumimo_ctrl;
+
+argos_mumimo_ctrl argos_mumimo_ctrl_data;
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+
+#ifdef BCMPCIE
+#define RPS_TPUT_THRESHOLD                     300
+#else
+#define RPS_TPUT_THRESHOLD                     150
+#endif
+#define DELAY_TO_CLEAR_RPS_CPUS                        300
+#define SUMIMO_TO_MUMIMO_TPUT_THRESHOLD                0
+#define MUMIMO_TO_SUMIMO_TPUT_THRESHOLD                150
+#else
+static INLINE int argos_register_notifier_init(struct net_device *net) { return 0;}
+static INLINE int argos_register_notifier_deinit(void) { return 0;}
+#endif /* ARGOS_CPU_SCHEDULER */
 
 #if defined(BT_OVER_SDIO)
 extern void wl_android_set_wifi_on_flag(bool enable);
@@ -597,6 +642,7 @@ typedef struct dhd_info {
        wait_queue_head_t ioctl_resp_wait;
        wait_queue_head_t d3ack_wait;
        wait_queue_head_t dhd_bus_busy_state_wait;
+       wait_queue_head_t dmaxfer_wait;
        uint32  default_wd_interval;
 
        struct timer_list timer;
@@ -609,6 +655,7 @@ typedef struct dhd_info {
        struct tasklet_struct tasklet;
        spinlock_t      sdlock;
        spinlock_t      txqlock;
+       spinlock_t      rxqlock;
        spinlock_t      dhd_lock;
 
        struct semaphore sdsem;
@@ -1313,6 +1360,12 @@ dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 #pragma GCC diagnostic pop
 #endif
 
+       if (!dhd || !(dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE)) {
+               DHD_INFO(("%s(): LB data is not initialized yet.\n",
+                       __FUNCTION__));
+               return NOTIFY_BAD;
+       }
+
        switch (action)
        {
                case CPU_ONLINE:
@@ -1328,6 +1381,7 @@ dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
                        cpumask_clear_cpu(cpu, dhd->cpumask_curr_avail);
                        dhd_select_cpu_candidacy(dhd);
                        break;
+
                default:
                        break;
        }
@@ -2428,7 +2482,6 @@ dhd_del_sta(void *pub, int ifidx, void *ea)
        dhd_sta_t *sta, *next;
        dhd_if_t *ifp;
        unsigned long flags;
-       char macstr[ETHER_ADDR_STR_LEN];
 
        ASSERT(ea != NULL);
        ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
@@ -2442,8 +2495,8 @@ dhd_del_sta(void *pub, int ifidx, void *ea)
 #endif
        list_for_each_entry_safe(sta, next, &ifp->sta_list, list) {
                if (!memcmp(sta->ea.octet, ea, ETHER_ADDR_LEN)) {
-                       DHD_MAC_TO_STR(((char *)ea), macstr);
-                       DHD_ERROR(("%s: Deleting STA  %s\n", __FUNCTION__, macstr));
+                       DHD_ERROR(("%s: Deleting STA " MACDBG "\n",
+                               __FUNCTION__, MAC2STRDBG(sta->ea.octet)));
                        list_del(&sta->list);
                        dhd_sta_free(&ifp->info->pub, sta);
                }
@@ -2780,6 +2833,7 @@ dhd_napi_poll(struct napi_struct *napi, int budget)
        struct dhd_info *dhd;
        int processed = 0;
        struct sk_buff_head rx_process_queue;
+       int cnt = 0;
 
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
 #pragma GCC diagnostic push
@@ -2799,6 +2853,7 @@ dhd_napi_poll(struct napi_struct *napi, int budget)
        skb_queue_splice_tail_init(&dhd->rx_napi_queue, &rx_process_queue);
        spin_unlock_irqrestore(&dhd->rx_napi_queue.lock, flags);
 
+       cnt = (int)skb_queue_len(&rx_process_queue);
        while ((skb = __skb_dequeue(&rx_process_queue)) != NULL) {
                OSL_PREFETCH(skb->data);
 
@@ -2809,6 +2864,18 @@ dhd_napi_poll(struct napi_struct *napi, int budget)
 
                dhd_rx_frame(&dhd->pub, ifid, skb, pkt_count, chan);
                processed++;
+
+               if (cnt-- < 0) {
+                       DHD_ERROR(("%s list:%p, list->prev:%p, list->next=%p\n",
+                               __FUNCTION__,
+                               &rx_process_queue,
+                               rx_process_queue.prev,
+                               rx_process_queue.next));
+                       DHD_ERROR(("%s skb:%p, skb->prev:%p, skb->next=%p\n",
+                               __FUNCTION__, skb, skb->prev, skb->next));
+
+                       DHD_ERROR(("%s processed %d\n", __FUNCTION__, processed));
+               }
        }
 
        DHD_LB_STATS_UPDATE_NAPI_HISTO(&dhd->pub, processed);
@@ -2939,6 +3006,9 @@ dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp)
        dhd_info_t *dhd = dhdp->info;
        int curr_cpu;
        int on_cpu;
+#ifdef DHD_LB_IRQSET
+       cpumask_t cpus;
+#endif /* DHD_LB_IRQSET */
 
        if (dhd->rx_napi_netdev == NULL) {
                DHD_ERROR(("%s: dhd->rx_napi_netdev is NULL\n", __FUNCTION__));
@@ -2961,7 +3031,16 @@ dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp)
        put_cpu();
 
        on_cpu = atomic_read(&dhd->rx_napi_cpu);
-       if ((on_cpu == curr_cpu) || (!cpu_online(on_cpu))) {
+       DHD_INFO(("%s : curr_cpu : %d, cpumask : 0x%lx\n", __FUNCTION__,
+               curr_cpu, *cpumask_bits(dhd->cpumask_primary)));
+
+       if (0 ||
+#ifdef DHD_LB_IRQSET
+       cpumask_and(&cpus, cpumask_of(curr_cpu), dhd->cpumask_primary) ||
+#else
+       (on_cpu == curr_cpu) ||
+#endif /* DHD_LB_IRQSET */
+       (!cpu_online(on_cpu))) {
                dhd_napi_schedule(dhd);
        } else {
                schedule_work(&dhd->rx_napi_dispatcher_work);
@@ -2983,6 +3062,31 @@ dhd_lb_rx_pkt_enqueue(dhd_pub_t *dhdp, void *pkt, int ifidx)
 }
 #endif /* DHD_LB_RXP */
 
+#ifdef DHD_LB_IRQSET
+void
+dhd_irq_set_affinity(dhd_pub_t *dhdp)
+{
+       unsigned int irq = (unsigned int)-1;
+       int err = BCME_OK;
+
+       if (!dhdp) {
+               DHD_ERROR(("%s : dhdp is NULL\n", __FUNCTION__));
+               return;
+       }
+
+       if (!dhdp->bus) {
+               DHD_ERROR(("%s : bus is NULL\n", __FUNCTION__));
+               return;
+       }
+
+       dhdpcie_get_pcieirq(dhdp->bus, &irq);
+       err = irq_set_affinity(irq, dhdp->info->cpumask_primary);
+       if (err) {
+               DHD_ERROR(("%s : irq set affinity is failed cpu:0x%lx\n",
+                       __FUNCTION__, *cpumask_bits(dhdp->info->cpumask_primary)));
+       }
+}
+#endif /* DHD_LB_IRQSET */
 #endif /* DHD_LB */
 
 
@@ -3235,8 +3339,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
        shub_control_t shub_ctl;
 #endif /* SUPPORT_SENSORHUB */
        /* wl_pkt_filter_enable_t       enable_parm; */
-       char iovbuf[32];
        int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */
+       int ret = 0;
 #ifdef DHD_USE_EARLYSUSPEND
 #ifdef CUSTOM_BCN_TIMEOUT_IN_SUSPEND
        int bcn_timeout = 0;
@@ -3251,7 +3355,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
        int bcn_li_bcn;
 #endif /* ENABLE_BCN_LI_BCN_WAKEUP */
        uint nd_ra_filter = 0;
-       int ret = 0;
 #endif /* DHD_USE_EARLYSUSPEND */
 #ifdef PASS_ALL_MCAST_PKTS
        struct dhd_info *dhdinfo;
@@ -3261,6 +3364,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 #ifdef ENABLE_IPMCAST_FILTER
        int ipmcast_l2filter;
 #endif /* ENABLE_IPMCAST_FILTER */
+#ifdef CUSTOM_EVENT_PM_WAKE
+       uint32 pm_awake_thresh = CUSTOM_EVENT_PM_WAKE;
+#endif /* CUSTOM_EVENT_PM_WAKE */
 #ifdef DYNAMIC_SWOOB_DURATION
 #ifndef CUSTOM_INTR_WIDTH
 #define CUSTOM_INTR_WIDTH 100
@@ -3280,7 +3386,6 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 #endif /* CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND */
 #endif /* OEM_ANDROID && BCMPCIE */
 
-       BCM_REFERENCE(iovbuf);
        if (!dhd)
                return -ENODEV;
 
@@ -3327,10 +3432,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                shub_ctl.op_mode = 1;
                                shub_ctl.interval = 0;
                                if (dhd->info->shub_enable == 1) {
-                                       bcm_mkiovar("shub_msreq", (char *)&shub_ctl,
-                                               sizeof(shub_ctl), iovbuf, sizeof(iovbuf));
-                                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+                                       ret = dhd_iovar(dhd, 0, "shub_msreq",
+                                               (char *)&shub_ctl, sizeof(shub_ctl), NULL, 0, TRUE);
+                                       if (ret < 0) {
                                                DHD_ERROR(("%s SensorHub MS start: failed %d\n",
                                                        __FUNCTION__, ret));
                                        }
@@ -3340,12 +3444,11 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 
 #ifdef PASS_ALL_MCAST_PKTS
                                allmulti = 0;
-                               bcm_mkiovar("allmulti", (char *)&allmulti, 4,
-                                       iovbuf, sizeof(iovbuf));
                                for (i = 0; i < DHD_MAX_IFS; i++) {
                                        if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net)
-                                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                                       sizeof(iovbuf), TRUE, i);
+                                               dhd_iovar(dhd, i, "allmulti", (char *)&allmulti,
+                                                               sizeof(allmulti), NULL, 0, TRUE);
+
                                }
 #endif /* PASS_ALL_MCAST_PKTS */
 
@@ -3363,7 +3466,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd, &dtim_period,
                                        &bcn_interval);
                                dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim,
-                                       sizeof(bcn_li_dtim), 1);
+                                               sizeof(bcn_li_dtim), NULL, 0, TRUE);
+
                                if ((bcn_li_dtim * dtim_period * bcn_interval) >=
                                        MIN_DTIM_FOR_ROAM_THRES_EXTEND) {
                                        /*
@@ -3372,7 +3476,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                         * bcn_timeout/2)
                                         */
                                        lpas = 1;
-                                       dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), 1);
+                                       dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), NULL,
+                                                       0, TRUE);
 
                                        bcn_to_dly = 1;
                                        /*
@@ -3382,46 +3487,39 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                         * if we hit bcn_timeout while we are in roaming progress.
                                         */
                                        dhd_iovar(dhd, 0, "bcn_to_dly", (char *)&bcn_to_dly,
-                                               sizeof(bcn_to_dly), 1);
-
+                                                       sizeof(bcn_to_dly), NULL, 0, TRUE);
                                        /* Increase beacon timeout to 6 secs or use bigger one */
                                        bcn_timeout = max(bcn_timeout, BCN_TIMEOUT_IN_SUSPEND);
                                        dhd_iovar(dhd, 0, "bcn_timeout", (char *)&bcn_timeout,
-                                               sizeof(bcn_timeout), 1);
+                                                       sizeof(bcn_timeout), NULL, 0, TRUE);
                                }
 #else
                                bcn_li_dtim = dhd_get_suspend_bcn_li_dtim(dhd);
-                               bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
-                                       4, iovbuf, sizeof(iovbuf));
-                               if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf),
-                                       TRUE, 0) < 0)
+                               if (dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim,
+                                               sizeof(bcn_li_dtim), NULL, 0, TRUE) < 0)
                                        DHD_ERROR(("%s: set dtim failed\n", __FUNCTION__));
 #endif /* OEM_ANDROID && BCMPCIE */
 
 #ifdef DHD_USE_EARLYSUSPEND
 #ifdef CUSTOM_BCN_TIMEOUT_IN_SUSPEND
                                bcn_timeout = CUSTOM_BCN_TIMEOUT_IN_SUSPEND;
-                               bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "bcn_timeout", (char *)&bcn_timeout,
+                                               sizeof(bcn_timeout), NULL, 0, TRUE);
 #endif /* CUSTOM_BCN_TIMEOUT_IN_SUSPEND */
 #ifdef CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND
                                roam_time_thresh = CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND;
-                               bcm_mkiovar("roam_time_thresh", (char *)&roam_time_thresh,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "roam_time_thresh", (char *)&roam_time_thresh,
+                                               sizeof(roam_time_thresh), NULL, 0, TRUE);
 #endif /* CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND */
 #ifndef ENABLE_FW_ROAM_SUSPEND
                                /* Disable firmware roaming during suspend */
-                               bcm_mkiovar("roam_off", (char *)&roamvar, 4,
-                                       iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar),
+                                               NULL, 0, TRUE);
 #endif /* ENABLE_FW_ROAM_SUSPEND */
 #ifdef ENABLE_BCN_LI_BCN_WAKEUP
                                bcn_li_bcn = 0;
-                               bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn,
+                                               sizeof(bcn_li_bcn), NULL, 0, TRUE);
 #endif /* ENABLE_BCN_LI_BCN_WAKEUP */
 #ifdef NDO_CONFIG_SUPPORT
                                if (dhd->ndo_enable) {
@@ -3445,29 +3543,38 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 #endif /* APF */
                                        /* enable IPv6 RA filter in  firmware during suspend */
                                        nd_ra_filter = 1;
-                                       bcm_mkiovar("nd_ra_filter_enable", (char *)&nd_ra_filter, 4,
-                                               iovbuf, sizeof(iovbuf));
-                                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                               sizeof(iovbuf), TRUE, 0)) < 0)
+                                       ret = dhd_iovar(dhd, 0, "nd_ra_filter_enable",
+                                                       (char *)&nd_ra_filter, sizeof(nd_ra_filter),
+                                                       NULL, 0, TRUE);
+                                       if (ret < 0)
                                                DHD_ERROR(("failed to set nd_ra_filter (%d)\n",
                                                        ret));
                                }
                                dhd_os_suppress_logging(dhd, TRUE);
 #ifdef ENABLE_IPMCAST_FILTER
                                ipmcast_l2filter = 1;
-                               bcm_mkiovar("ipmcast_l2filter", (char *)&ipmcast_l2filter,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               ret = dhd_iovar(dhd, 0, "ipmcast_l2filter",
+                                               (char *)&ipmcast_l2filter, sizeof(ipmcast_l2filter),
+                                               NULL, 0, TRUE);
 #endif /* ENABLE_IPMCAST_FILTER */
 #ifdef DYNAMIC_SWOOB_DURATION
                                intr_width = CUSTOM_INTR_WIDTH;
-                               bcm_mkiovar("bus:intr_width", (char *)&intr_width, 4,
-                                       iovbuf, sizeof(iovbuf));
-                               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                       sizeof(iovbuf), TRUE, 0)) < 0) {
+                               ret = dhd_iovar(dhd, 0, "bus:intr_width", (char *)&intr_width,
+                                               sizeof(intr_width), NULL, 0, TRUE);
+                               if (ret < 0) {
                                        DHD_ERROR(("failed to set intr_width (%d)\n", ret));
                                }
 #endif /* DYNAMIC_SWOOB_DURATION */
+#ifdef CUSTOM_EVENT_PM_WAKE
+                               pm_awake_thresh = CUSTOM_EVENT_PM_WAKE * 4;
+                               ret = dhd_iovar(dhd, 0, "const_awake_thresh",
+                                       (char *)&pm_awake_thresh,
+                                       sizeof(pm_awake_thresh), NULL, 0, TRUE);
+                               if (ret < 0) {
+                                       DHD_ERROR(("%s set const_awake_thresh failed %d\n",
+                                               __FUNCTION__, ret));
+                               }
+#endif /* CUSTOM_EVENT_PM_WAKE */
 #endif /* DHD_USE_EARLYSUSPEND */
                        } else {
 #ifdef PKT_FILTER_SUPPORT
@@ -3482,10 +3589,10 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
                                shub_ctl.op_mode = 0;
                                shub_ctl.interval = 0;
                                if (dhd->info->shub_enable == 1) {
-                                       bcm_mkiovar("shub_msreq", (char *)&shub_ctl,
-                                               sizeof(shub_ctl), iovbuf, sizeof(iovbuf));
-                                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+                                       ret = dhd_iovar(dhd, 0, "shub_msreq",
+                                                       (char *)&shub_ctl, sizeof(shub_ctl),
+                                                       NULL, 0, TRUE);
+                                       if (ret < 0) {
                                                DHD_ERROR(("%s SensorHub MS stop: failed %d\n",
                                                        __FUNCTION__, ret));
                                        }
@@ -3494,10 +3601,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 
 #ifdef DYNAMIC_SWOOB_DURATION
                                intr_width = 0;
-                               bcm_mkiovar("bus:intr_width", (char *)&intr_width, 4,
-                                       iovbuf, sizeof(iovbuf));
-                               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                       sizeof(iovbuf), TRUE, 0)) < 0) {
+                               ret = dhd_iovar(dhd, 0, "bus:intr_width", (char *)&intr_width,
+                                               sizeof(intr_width), NULL, 0, TRUE);
+                               if (ret < 0) {
                                        DHD_ERROR(("failed to set intr_width (%d)\n", ret));
                                }
 #endif /* DYNAMIC_SWOOB_DURATION */
@@ -3515,54 +3621,54 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 #endif /* PKT_FILTER_SUPPORT */
 #ifdef PASS_ALL_MCAST_PKTS
                                allmulti = 1;
-                               bcm_mkiovar("allmulti", (char *)&allmulti, 4,
-                                       iovbuf, sizeof(iovbuf));
                                for (i = 0; i < DHD_MAX_IFS; i++) {
                                        if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net)
-                                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                                       sizeof(iovbuf), TRUE, i);
+                                               dhd_iovar(dhd, i, "allmulti", (char *)&allmulti,
+                                                               sizeof(allmulti), NULL, 0, TRUE);
                                }
 #endif /* PASS_ALL_MCAST_PKTS */
 #if defined(BCMPCIE)
                                /* restore pre-suspend setting */
                                dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim,
-                                       sizeof(bcn_li_dtim), 1);
-                               dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), 1);
+                                               sizeof(bcn_li_dtim), NULL, 0, TRUE);
+
+                               dhd_iovar(dhd, 0, "lpas", (char *)&lpas, sizeof(lpas), NULL, 0,
+                                               TRUE);
+
                                dhd_iovar(dhd, 0, "bcn_to_dly", (char *)&bcn_to_dly,
-                                       sizeof(bcn_to_dly), 1);
+                                               sizeof(bcn_to_dly), NULL, 0, TRUE);
+
                                dhd_iovar(dhd, 0, "bcn_timeout", (char *)&bcn_timeout,
-                                       sizeof(bcn_timeout), 1);
+                                               sizeof(bcn_timeout), NULL, 0, TRUE);
 #else
                                /* restore pre-suspend setting for dtim_skip */
-                               bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
-                                       4, iovbuf, sizeof(iovbuf));
-
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               ret = dhd_iovar(dhd, 0, "bcn_li_dtim", (char *)&bcn_li_dtim,
+                                               sizeof(bcn_li_dtim), NULL, 0, TRUE);
+                               if (ret < 0) {
+                                       DHD_ERROR(("%s:bcn_li_ditm fail:%d\n", __FUNCTION__, ret));
+                               }
 #endif /* OEM_ANDROID && BCMPCIE */
 #ifdef DHD_USE_EARLYSUSPEND
 #ifdef CUSTOM_BCN_TIMEOUT_IN_SUSPEND
                                bcn_timeout = CUSTOM_BCN_TIMEOUT;
-                               bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "bcn_timeout", (char *)&bcn_timeout,
+                                               sizeof(bcn_timeout), NULL, 0, TRUE);
 #endif /* CUSTOM_BCN_TIMEOUT_IN_SUSPEND */
 #ifdef CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND
                                roam_time_thresh = 2000;
-                               bcm_mkiovar("roam_time_thresh", (char *)&roam_time_thresh,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "roam_time_thresh", (char *)&roam_time_thresh,
+                                               sizeof(roam_time_thresh), NULL, 0, TRUE);
+
 #endif /* CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND */
 #ifndef ENABLE_FW_ROAM_SUSPEND
                                roamvar = dhd_roam_disable;
-                               bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf,
-                                       sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar),
+                                               NULL, 0, TRUE);
 #endif /* ENABLE_FW_ROAM_SUSPEND */
 #ifdef ENABLE_BCN_LI_BCN_WAKEUP
                                bcn_li_bcn = 1;
-                               bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn,
+                                               sizeof(bcn_li_bcn), NULL, 0, TRUE);
 #endif /* ENABLE_BCN_LI_BCN_WAKEUP */
 #ifdef NDO_CONFIG_SUPPORT
                                if (dhd->ndo_enable) {
@@ -3581,21 +3687,34 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
 #endif /* APF */
                                        /* disable IPv6 RA filter in  firmware during suspend */
                                        nd_ra_filter = 0;
-                                       bcm_mkiovar("nd_ra_filter_enable", (char *)&nd_ra_filter, 4,
-                                               iovbuf, sizeof(iovbuf));
-                                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                                               sizeof(iovbuf), TRUE, 0)) < 0)
+                                       ret = dhd_iovar(dhd, 0, "nd_ra_filter_enable",
+                                                       (char *)&nd_ra_filter, sizeof(nd_ra_filter),
+                                                       NULL, 0, TRUE);
+                                       if (ret < 0) {
                                                DHD_ERROR(("failed to set nd_ra_filter (%d)\n",
                                                        ret));
+                                       }
                                }
                                dhd_os_suppress_logging(dhd, FALSE);
 #ifdef ENABLE_IPMCAST_FILTER
                                ipmcast_l2filter = 0;
-                               bcm_mkiovar("ipmcast_l2filter", (char *)&ipmcast_l2filter,
-                                       4, iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                               ret = dhd_iovar(dhd, 0, "ipmcast_l2filter",
+                                               (char *)&ipmcast_l2filter, sizeof(ipmcast_l2filter),
+                                               NULL, 0, TRUE);
 #endif /* ENABLE_IPMCAST_FILTER */
+#ifdef CUSTOM_EVENT_PM_WAKE
+                               ret = dhd_iovar(dhd, 0, "const_awake_thresh",
+                                       (char *)&pm_awake_thresh,
+                                       sizeof(pm_awake_thresh), NULL, 0, TRUE);
+                               if (ret < 0) {
+                                       DHD_ERROR(("%s set const_awake_thresh failed %d\n",
+                                               __FUNCTION__, ret));
+                               }
+#endif /* CUSTOM_EVENT_PM_WAKE */
 #endif /* DHD_USE_EARLYSUSPEND */
+#ifdef DHD_LB_IRQSET
+                               dhd_irq_set_affinity(dhd);
+#endif /* DHD_LB_IRQSET */
                        }
        }
        dhd_suspend_unlock(dhd);
@@ -3971,35 +4090,14 @@ _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx)
         * were trying to set some addresses and dongle rejected it...
         */
 
-       buflen = sizeof("allmulti") + sizeof(allmulti);
-       if (!(buf = MALLOC(dhd->pub.osh, buflen))) {
-               DHD_ERROR(("%s: out of memory for allmulti\n", dhd_ifname(&dhd->pub, ifidx)));
-               return;
-       }
        allmulti = htol32(allmulti);
-
-       if (!bcm_mkiovar("allmulti", (void*)&allmulti, sizeof(allmulti), buf, buflen)) {
-               DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
-                          dhd_ifname(&dhd->pub, ifidx), (int)sizeof(allmulti), buflen));
-               MFREE(dhd->pub.osh, buf, buflen);
-               return;
-       }
-
-
-       memset(&ioc, 0, sizeof(ioc));
-       ioc.cmd = WLC_SET_VAR;
-       ioc.buf = buf;
-       ioc.len = buflen;
-       ioc.set = TRUE;
-
-       ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+       ret = dhd_iovar(&dhd->pub, ifidx, "allmulti", (char *)&allmulti,
+                       sizeof(allmulti), NULL, 0, TRUE);
        if (ret < 0) {
                DHD_ERROR(("%s: set allmulti %d failed\n",
                           dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti)));
        }
 
-       MFREE(dhd->pub.osh, buf, buflen);
-
        /* Finally, pick up the PROMISC flag as well, like the NIC driver does */
 
 #ifdef MCAST_LIST_ACCUMULATION
@@ -4032,21 +4130,10 @@ _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx)
 int
 _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, uint8 *addr)
 {
-       char buf[32];
-       wl_ioctl_t ioc;
        int ret;
 
-       if (!bcm_mkiovar("cur_etheraddr", (char*)addr, ETHER_ADDR_LEN, buf, 32)) {
-               DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx)));
-               return -1;
-       }
-       memset(&ioc, 0, sizeof(ioc));
-       ioc.cmd = WLC_SET_VAR;
-       ioc.buf = buf;
-       ioc.len = 32;
-       ioc.set = TRUE;
-
-       ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+       ret = dhd_iovar(&dhd->pub, ifidx, "cur_etheraddr", (char *)addr,
+                       ETHER_ADDR_LEN, NULL, 0, TRUE);
        if (ret < 0) {
                DHD_ERROR(("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx)));
        } else {
@@ -4221,13 +4308,9 @@ dhd_ifadd_event_handler(void *handle, void *event_info, u8 event)
 #ifndef PCIE_FULL_DONGLE
        /* Turn on AP isolation in the firmware for interfaces operating in AP mode */
        if (FW_SUPPORTED((&dhd->pub), ap) && (if_event->event.role != WLC_E_IF_ROLE_STA)) {
-               char iovbuf[WLC_IOCTL_SMLEN];
                uint32 var_int =  1;
-
-               memset(iovbuf, 0, sizeof(iovbuf));
-               bcm_mkiovar("ap_isolate", (char *)&var_int, 4, iovbuf, sizeof(iovbuf));
-               ret = dhd_wl_ioctl_cmd(&dhd->pub, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, ifidx);
-
+               ret = dhd_iovar(&dhd->pub, ifidx, "ap_isolate", (char *)&var_int, sizeof(var_int),
+                               NULL, 0, TRUE);
                if (ret != BCME_OK) {
                        DHD_ERROR(("%s: Failed to set ap_isolate to dongle\n", __FUNCTION__));
                        dhd_remove_if(&dhd->pub, ifidx, TRUE);
@@ -4695,6 +4778,13 @@ __dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
        }
 
        /* Use bus module to send data frame */
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       if (dhdp->reassoc_mumimo_sw &&
+               dhd_check_eapol_4way_message(PKTDATA(dhdp->osh, pktbuf)) == EAPOL_4WAY_M4) {
+               dhdp->reassoc_mumimo_sw = 0;
+               DHD_ENABLE_RUNTIME_PM(dhdp);
+       }
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #ifdef PROP_TXSTATUS
        {
                if (dhd_wlfc_commit_packets(dhdp, (f_commitpkt_t)dhd_bus_txdata,
@@ -5319,14 +5409,8 @@ dhd_event_logtrace_flush_queue(dhd_pub_t *dhdp)
 #endif /* SHOW_LOGTRACE */
 
 /** Called when a frame is received by the dongle on interface 'ifidx' */
-#ifdef DHD_WAKE_STATUS
-void
-dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan,
-               int pkt_wake, wake_counts_t *wcp)
-#else
 void
 dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
-#endif /* DHD_WAKE_STATUS */
 {
        dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
        struct sk_buff *skb;
@@ -5350,6 +5434,10 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
        if_flow_lkup_t *if_flow_lkup;
        unsigned long flags;
 #endif
+#ifdef DHD_WAKE_STATUS
+       int pkt_wake = 0;
+       wake_counts_t *wcp = NULL;
+#endif /* DHD_WAKE_STATUS */
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -5388,6 +5476,14 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 #endif /* SHOW_LOGTRACE */
                        continue;
                }
+#ifdef DHD_WAKE_STATUS
+               pkt_wake = dhd_bus_get_bus_wake(dhdp);
+               wcp = dhd_bus_get_wakecount(dhdp);
+               if (wcp == NULL) {
+                       /* If wakeinfo count buffer is null do not update wake count values */
+                       pkt_wake = 0;
+               }
+#endif /* DHD_WAKE_STATUS */
 
                ifp = dhd->iflist[ifidx];
                if (ifp == NULL) {
@@ -5521,6 +5617,15 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
                        }
                }
 #endif /* PCIE_FULL_DONGLE */
+#ifdef DYNAMIC_MUMIMO_CONTROL
+               if (dhdp->reassoc_mumimo_sw && dhdp->murx_block_eapol &&
+                       dhd_check_eapol_4way_message((void *)(skb->data)) == EAPOL_4WAY_M1) {
+                       DHD_ERROR(("%s: Reassoc is in progress..."
+                               " drop EAPOL M1 frame\n", __FUNCTION__));
+                       PKTFREE(dhdp->osh, pktbuf, FALSE);
+                       continue;
+               }
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 
                /* Get the protocol, maintain skb around eth_type_trans()
                 * The main reason for this hack is for the limitation of
@@ -5584,6 +5689,11 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 #endif /* DHD_RX_FULL_DUMP */
                }
 #endif /* DHD_RX_DUMP */
+#if defined(DHD_WAKE_STATUS) && defined(DHD_WAKEPKT_DUMP)
+               if (pkt_wake) {
+                       prhex("[wakepkt_dump]", (char*)dump_data, MIN(len, 32));
+               }
+#endif /* DHD_WAKE_STATUS && DHD_WAKEPKT_DUMP */
 
                skb->protocol = eth_type_trans(skb, skb->dev);
 
@@ -5598,7 +5708,9 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 #ifdef DBG_PKT_MON
                DHD_DBG_PKT_MON_RX(dhdp, skb);
 #endif /* DBG_PKT_MON */
-
+#ifdef DHD_PKT_LOGGING
+               DHD_PKTLOG_RX(dhdp, skb);
+#endif /* DHD_PKT_LOGGING */
                /* Strip header, count, deliver upward */
                skb_pull(skb, ETH_HLEN);
 
@@ -5674,12 +5786,13 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 
 #ifdef DHD_WAKE_STATUS
                        if (unlikely(pkt_wake)) {
-                               wcp->rcwake++;
 #ifdef DHD_WAKE_EVENT_STATUS
-                               if (event.event_type < WLC_E_LAST)
+                               if (event.event_type < WLC_E_LAST) {
                                        wcp->rc_event[event.event_type]++;
+                                       wcp->rcwake++;
+                                       pkt_wake = 0;
+                               }
 #endif /* DHD_WAKE_EVENT_STATUS */
-                               pkt_wake = 0;
                        }
 #endif /* DHD_WAKE_STATUS */
 
@@ -5705,10 +5818,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 #endif /* DHD_USE_STATIC_CTRLBUF */
                        continue;
 #else
-#ifdef DHD_WAKE_STATUS
-                       wcp->rcwake += pkt_wake;
-                       pkt_wake = 0;
-#endif /* DHD_WAKE_STATUS */
                        /*
                         * For the event packets, there is a possibility
                         * of ifidx getting modifed.Thus update the ifp
@@ -5829,12 +5938,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
                                bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
                                        __FUNCTION__, __LINE__);
 
-#if defined(ARGOS_RPS_CPU_CTL) && defined(ARGOS_CPU_SCHEDULER)
-               argos_register_notifier_deinit();
-#endif /* ARGOS_RPS_CPU_CTL && ARGOS_CPU_SCHEDULER */
-#if defined(BCMPCIE) && defined(DHDTCPACK_SUPPRESS)
-               dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
-#endif /* BCMPCIE && DHDTCPACK_SUPPRESS */
 #if defined(DHD_LB_RXP)
                                DHD_PERIM_UNLOCK_ALL((dhd->fwder_unit % FWDER_MAX_UNIT));
                                netif_receive_skb(skb);
@@ -5915,22 +6018,34 @@ dhd_get_stats(struct net_device *net)
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
+       if (!dhd) {
+               DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__));
+               goto error;
+       }
+
        ifidx = dhd_net2idx(dhd, net);
        if (ifidx == DHD_BAD_IF) {
                DHD_ERROR(("%s: BAD_IF\n", __FUNCTION__));
-
-               memset(&net->stats, 0, sizeof(net->stats));
-               return &net->stats;
+               goto error;
        }
 
        ifp = dhd->iflist[ifidx];
-       ASSERT(dhd && ifp);
+
+       if (!ifp) {
+               ASSERT(ifp);
+               DHD_ERROR(("%s: ifp is NULL\n", __FUNCTION__));
+               goto error;
+       }
 
        if (dhd->pub.up) {
                /* Use the protocol to get dongle stats */
                dhd_prot_dstats(&dhd->pub);
        }
        return &ifp->stats;
+
+error:
+       memset(&net->stats, 0, sizeof(net->stats));
+       return &net->stats;
 }
 
 static int
@@ -5953,10 +6068,15 @@ dhd_watchdog_thread(void *data)
                        unsigned long flags;
                        unsigned long jiffies_at_start = jiffies;
                        unsigned long time_lapse;
+#ifdef BCMPCIE
                        DHD_OS_WD_WAKE_LOCK(&dhd->pub);
+#endif /* BCMPCIE */
 
                        SMP_RD_BARRIER_DEPENDS();
                        if (tsk->terminated) {
+#ifdef BCMPCIE
+                               DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
                                break;
                        }
 
@@ -5986,7 +6106,9 @@ dhd_watchdog_thread(void *data)
                                }
                                DHD_GENERAL_UNLOCK(&dhd->pub, flags);
                        }
+#ifdef BCMPCIE
                        DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
                } else {
                        break;
                }
@@ -6009,7 +6131,9 @@ static void dhd_watchdog(ulong data)
                return;
        }
 
+#ifdef BCMPCIE
        DHD_OS_WD_WAKE_LOCK(&dhd->pub);
+#endif /* BCMPCIE */
        /* Call the bus module watchdog */
        dhd_bus_watchdog(&dhd->pub);
 
@@ -6029,7 +6153,9 @@ static void dhd_watchdog(ulong data)
        if (dhd->wd_timer_valid)
                mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
        DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+#ifdef BCMPCIE
        DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
 }
 
 #ifdef DHD_PCIE_RUNTIMEPM
@@ -6146,10 +6272,11 @@ exit:
 static int
 dhd_dpc_thread(void *data)
 {
-#ifdef ARGOS_CPU_SCHEDULER
+#if defined(ARGOS_CPU_SCHEDULER) && defined(CONFIG_SCHED_HMP) && \
+       !defined(DHD_LB_IRQSET)
        int ret = 0;
        unsigned long flags;
-#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* ARGOS_CPU_SCHEDULER && CONFIG_SCHED_HMP && !DHD_LB_IRQSET */
        tsk_ctl_t *tsk = (tsk_ctl_t *)data;
        dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
 
@@ -6163,7 +6290,8 @@ dhd_dpc_thread(void *data)
                setScheduler(current, SCHED_FIFO, &param);
        }
 
-#ifdef ARGOS_CPU_SCHEDULER
+#if defined(ARGOS_CPU_SCHEDULER) && defined(CONFIG_SCHED_HMP) && \
+       !defined(DHD_LB_IRQSET)
        if (!zalloc_cpumask_var(&dhd->pub.default_cpu_mask, GFP_KERNEL)) {
                DHD_ERROR(("dpc_thread, zalloc_cpumask_var error\n"));
                dhd->pub.affinity_isdpc = FALSE;
@@ -6213,7 +6341,7 @@ dhd_dpc_thread(void *data)
 #ifdef CUSTOM_SET_CPUCORE
        dhd->pub.current_dpc = current;
 #endif /* CUSTOM_SET_CPUCORE */
-#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* ARGOS_CPU_SCHEDULER && CONFIG_SCHED_HMP && !DHD_LB_IRQSET */
        /* Run until signal received */
        while (1) {
                if (!binary_sema_down(tsk)) {
@@ -6271,10 +6399,11 @@ dhd_rxf_thread(void *data)
 {
        tsk_ctl_t *tsk = (tsk_ctl_t *)data;
        dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
-#ifdef ARGOS_CPU_SCHEDULER
+#if defined(ARGOS_CPU_SCHEDULER) && defined(CONFIG_SCHED_HMP) && \
+       !defined(DHD_LB_IRQSET)
        int ret = 0;
        unsigned long flags;
-#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* ARGOS_CPU_SCHEDULER && CONFIG_SCHED_HMP !DHD_LB_IRQSET */
 #if defined(WAIT_DEQUEUE)
 #define RXF_WATCHDOG_TIME 250 /* BARK_TIME(1000) /  */
        ulong watchdogTime = OSL_SYSUPTIME(); /* msec */
@@ -6291,7 +6420,8 @@ dhd_rxf_thread(void *data)
                setScheduler(current, SCHED_FIFO, &param);
        }
 
-#ifdef ARGOS_CPU_SCHEDULER
+#if defined(ARGOS_CPU_SCHEDULER) && defined(CONFIG_SCHED_HMP) && \
+       !defined(DHD_LB_IRQSET)
        if (!zalloc_cpumask_var(&dhd->pub.rxf_affinity_cpu_mask, GFP_KERNEL)) {
                DHD_ERROR(("rxthread zalloc_cpumask_var error\n"));
                dhd->pub.affinity_isrxf = FALSE;
@@ -6315,7 +6445,7 @@ dhd_rxf_thread(void *data)
 #ifdef CUSTOM_SET_CPUCORE
        dhd->pub.current_rxf = current;
 #endif /* CUSTOM_SET_CPUCORE */
-#endif /* ARGOS_CPU_SCHEDULER */
+#endif /* ARGOS_CPU_SCHEDULER && CONFIG_SCHED_HMP && !DHD_LB_IRQSET */
        /* Run until signal received */
        while (1) {
                if (down_interruptible(&tsk->sema) == 0) {
@@ -6416,9 +6546,16 @@ dhd_dpc_kill(dhd_pub_t *dhdp)
                DHD_ERROR(("%s: tasklet disabled\n", __FUNCTION__));
        }
 
+#ifdef DHD_LB
 #ifdef DHD_LB_RXP
+       cancel_work_sync(&dhd->rx_napi_dispatcher_work);
        __skb_queue_purge(&dhd->rx_pend_queue);
 #endif /* DHD_LB_RXP */
+#ifdef DHD_LB_TXP
+       cancel_work_sync(&dhd->tx_dispatcher_work);
+       skb_queue_purge(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+
        /* Kill the Load Balancing Tasklets */
 #if defined(DHD_LB_TXC)
        tasklet_kill(&dhd->tx_compl_tasklet);
@@ -6426,14 +6563,10 @@ dhd_dpc_kill(dhd_pub_t *dhdp)
 #if defined(DHD_LB_RXC)
        tasklet_kill(&dhd->rx_compl_tasklet);
 #endif /* DHD_LB_RXC */
-
 #if defined(DHD_LB_TXP)
        tasklet_kill(&dhd->tx_tasklet);
 #endif /* DHD_LB_TXP */
-
-#ifdef DHD_LB_RXP
-       skb_queue_purge(&dhd->tx_pend_queue);
-#endif /* DHD_LB_RXP */
+#endif /* DHD_LB */
 }
 
 void
@@ -6526,24 +6659,15 @@ dhd_sched_rxf(dhd_pub_t *dhdp, void *skb)
 static int
 dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol)
 {
-       wl_ioctl_t ioc;
        char buf[32];
        int ret;
 
-       memset(&ioc, 0, sizeof(ioc));
-
-       ioc.cmd = WLC_GET_VAR;
-       ioc.buf = buf;
-       ioc.len = (uint)sizeof(buf);
-       ioc.set = FALSE;
+       ret = dhd_iovar(&dhd->pub, ifidx, "toe_ol", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
 
-       strncpy(buf, "toe_ol", sizeof(buf) - 1);
-       buf[sizeof(buf) - 1] = '\0';
-       if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
-               /* Check for older dongle image that doesn't support toe_ol */
+       if (ret < 0) {
                if (ret == -EIO) {
-                       DHD_ERROR(("%s: toe not supported by device\n",
-                               dhd_ifname(&dhd->pub, ifidx)));
+                       DHD_ERROR(("%s: toe not supported by device\n", dhd_ifname(&dhd->pub,
+                               ifidx)));
                        return -EOPNOTSUPP;
                }
 
@@ -6559,37 +6683,20 @@ dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol)
 static int
 dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol)
 {
-       wl_ioctl_t ioc;
-       char buf[32];
        int toe, ret;
 
-       memset(&ioc, 0, sizeof(ioc));
-
-       ioc.cmd = WLC_SET_VAR;
-       ioc.buf = buf;
-       ioc.len = (uint)sizeof(buf);
-       ioc.set = TRUE;
-
        /* Set toe_ol as requested */
-
-       strncpy(buf, "toe_ol", sizeof(buf) - 1);
-       buf[sizeof(buf) - 1] = '\0';
-       memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(uint32));
-
-       if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
+       ret = dhd_iovar(&dhd->pub, ifidx, "toe_ol", (char *)&toe_ol, sizeof(toe_ol), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s: could not set toe_ol: ret=%d\n",
                        dhd_ifname(&dhd->pub, ifidx), ret));
                return ret;
        }
 
        /* Enable toe globally only if any components are enabled. */
-
        toe = (toe_ol != 0);
-
-       strcpy(buf, "toe");
-       memcpy(&buf[sizeof("toe")], &toe, sizeof(uint32));
-
-       if ((ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len)) < 0) {
+       ret = dhd_iovar(&dhd->pub, ifidx, "toe", (char *)&toe, sizeof(toe), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret));
                return ret;
        }
@@ -6602,27 +6709,23 @@ dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol)
 void dhd_set_scb_probe(dhd_pub_t *dhd)
 {
        wl_scb_probe_t scb_probe;
-       char iovbuf[WL_EVENTING_MASK_LEN + sizeof(wl_scb_probe_t)];
-
-       memset(&scb_probe, 0, sizeof(wl_scb_probe_t));
+       int ret;
 
        if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
                return;
        }
 
-       bcm_mkiovar("scb_probe", NULL, 0, iovbuf, sizeof(iovbuf));
-
-       if (dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0) < 0) {
+       ret = dhd_iovar(dhd, 0, "scb_probe", NULL, 0,
+                       (char *)&scb_probe, sizeof(scb_probe), FALSE);
+       if (ret < 0) {
                DHD_ERROR(("%s: GET max_scb_probe failed\n", __FUNCTION__));
        }
 
-       memcpy(&scb_probe, iovbuf, sizeof(wl_scb_probe_t));
-
        scb_probe.scb_max_probe = NUM_SCB_MAX_PROBE;
 
-       bcm_mkiovar("scb_probe", (char *)&scb_probe,
-               sizeof(wl_scb_probe_t), iovbuf, sizeof(iovbuf));
-       if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) {
+       ret = dhd_iovar(dhd, 0, "scb_probe", (char *)&scb_probe, sizeof(scb_probe),
+                       NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s: max_scb_probe setting failed\n", __FUNCTION__));
                return;
        }
@@ -7774,9 +7877,7 @@ dhd_stop(struct net_device *net)
 #endif /* DHD_LB_TXP */
                }
 
-#if defined(ARGOS_RPS_CPU_CTL) && defined(ARGOS_CPU_SCHEDULER)
                argos_register_notifier_deinit();
-#endif /* ARGOS_RPS_CPU_CTL && ARGOS_CPU_SCHEDULER */
 #ifdef DHDTCPACK_SUPPRESS
                dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
 #endif /* DHDTCPACK_SUPPRESS */
@@ -7892,12 +7993,10 @@ extern bool g_first_broadcast_scan;
 #ifdef WL11U
 static int dhd_interworking_enable(dhd_pub_t *dhd)
 {
-       char iovbuf[WLC_IOCTL_SMLEN];
        uint32 enable = true;
        int ret = BCME_OK;
 
-       bcm_mkiovar("interworking", (char *)&enable, sizeof(enable), iovbuf, sizeof(iovbuf));
-       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       ret = dhd_iovar(dhd, 0, "interworking", (char *)&enable, sizeof(enable), NULL, 0, TRUE);
        if (ret < 0) {
                DHD_ERROR(("%s: enableing interworking failed, ret=%d\n", __FUNCTION__, ret));
        }
@@ -7981,6 +8080,10 @@ dhd_open(struct net_device *net)
 #ifdef DHD_LOSSLESS_ROAMING
        dhd->pub.dequeue_prec_map = ALLPRIO;
 #endif
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       dhd->pub.reassoc_mumimo_sw = FALSE;
+       dhd->pub.murx_block_eapol = FALSE;
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #if !defined(WL_CFG80211)
        /*
         * Force start if ifconfig_up gets called before START command
@@ -8104,6 +8207,9 @@ dhd_open(struct net_device *net)
                        skb_queue_head_init(&dhd->rx_napi_queue);
                } /* rx_napi_netdev == NULL */
 #endif /* DHD_LB_RXP */
+#ifdef DHD_LB_IRQSET
+               dhd_irq_set_affinity(&dhd->pub);
+#endif /* DHD_LB_IRQSET */
 
 #if defined(DHD_LB_TXP)
                /* Use the variant that uses locks */
@@ -8132,16 +8238,10 @@ dhd_open(struct net_device *net)
 #endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
                }
 
-#if defined(ARGOS_CPU_SCHEDULER) && defined(ARGOS_RPS_CPU_CTL)
                argos_register_notifier_init(net);
-#endif /* ARGOS_CPU_SCHEDULER && ARGOS_RPS_CPU_CTL */
-#if defined(BCMPCIE) && defined(DHDTCPACK_SUPPRESS)
-#if defined(SET_RPS_CPUS) || defined(ARGOS_RPS_CPU_CTL)
-               dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
-#else
-               dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_HOLD);
-#endif /* ARGOS_CPU_SCHEDULER && ARGOS_RPS_CPU_CTL */
-#endif /* BCMPCIE && DHDTCPACK_SUPPRESS */
+#if defined(DHDTCPACK_SUPPRESS)
+               dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_DEFAULT);
+#endif /* DHDTCPACK_SUPPRESS */
 #if defined(NUM_SCB_MAX_PROBE)
                dhd_set_scb_probe(&dhd->pub);
 #endif /* NUM_SCB_MAX_PROBE */
@@ -8452,11 +8552,9 @@ dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock)
 #if defined(SET_RPS_CPUS)
                                custom_rps_map_clear(ifp->net->_rx);
 #endif /* SET_RPS_CPUS */
-#if (defined(SET_RPS_CPUS) || defined(ARGOS_RPS_CPU_CTL))
-#if (defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE))
+#if defined(ARGOS_CPU_SCHEDULER) && defined(DHDTCPACK_SUPPRESS)
                                dhd_tcpack_suppress_set(dhdpub, TCPACK_SUP_OFF);
-#endif /* DHDTCPACK_SUPPRESS && BCMPCIE */
-#endif /* SET_RPS_CPUS || ARGOS_RPS_CPU_CTL */
+#endif /* ARGOS_CPU_SCHEDULER && DHDTCPACK_SUPPRESS */
                                if (need_rtnl_lock)
                                        unregister_netdev(ifp->net);
                                else
@@ -8563,12 +8661,12 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
        filep = filp_open(logstrs_path, O_RDONLY, 0);
 
        if (IS_ERR(filep)) {
-               DHD_ERROR(("%s: Failed to open the file %s \n", __FUNCTION__, logstrs_path));
+               DHD_INFO(("%s: Failed to open the file %s \n", __FUNCTION__, logstrs_path));
                goto fail;
        }
        error = vfs_stat(logstrs_path, &stat);
        if (error) {
-               DHD_ERROR(("%s: Failed to stat file %s \n", __FUNCTION__, logstrs_path));
+               DHD_INFO(("%s: Failed to stat file %s \n", __FUNCTION__, logstrs_path));
                goto fail;
        }
        logstrs_size = (int) stat.size;
@@ -8578,13 +8676,17 @@ dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
                goto fail1;
        }
 
+       if (temp->raw_fmts != NULL) {
+               DHD_ERROR(("raw_fmts was not released\n"));
+               goto fail;
+       }
        raw_fmts = MALLOC(osh, logstrs_size);
        if (raw_fmts == NULL) {
                DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__));
                goto fail;
        }
        if (vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) !=   logstrs_size) {
-               DHD_ERROR(("%s: Failed to read file %s", __FUNCTION__, logstrs_path));
+               DHD_INFO(("%s: Failed to read file %s", __FUNCTION__, logstrs_path));
                goto fail;
        }
 
@@ -8628,7 +8730,7 @@ dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
 
        filep = filp_open(fname, O_RDONLY, 0);
        if (IS_ERR(filep)) {
-               DHD_ERROR(("%s: Failed to open %s \n",  __FUNCTION__, fname));
+               DHD_INFO(("%s: Failed to open %s \n",  __FUNCTION__, fname));
                goto fail;
        }
 
@@ -8650,7 +8752,7 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
 {
        struct file *filep = NULL;
        mm_segment_t fs;
-       char *raw_fmts =  NULL;
+       char *raw_sstr =  NULL;
        uint32 logstrs_size = 0;
 
        int error = 0;
@@ -8664,9 +8766,15 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
                DHD_ERROR(("readmap Error!! \n"));
                /* don't do event log parsing in actual case */
                if (strstr(str_file, ram_file_str) != NULL) {
-                       temp->raw_sstr = NULL;
+                       if (temp->raw_sstr != NULL) {
+                               MFREE(osh, temp->raw_sstr, temp->raw_sstr_size);
+                               temp->raw_sstr = NULL;
+                       }
                } else if (strstr(str_file, rom_file_str) != NULL) {
-                       temp->rom_raw_sstr = NULL;
+                       if (temp->rom_raw_sstr != NULL) {
+                               MFREE(osh, temp->rom_raw_sstr, temp->rom_raw_sstr_size);
+                               temp->rom_raw_sstr = NULL;
+                       }
                }
                return error;
        }
@@ -8690,9 +8798,17 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
                goto fail1;
        }
 
-       raw_fmts = MALLOC(osh, logstrs_size);
-       if (raw_fmts == NULL) {
-               DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+       if (strstr(str_file, ram_file_str) != NULL && temp->raw_sstr != NULL) {
+               DHD_ERROR(("raw_sstr was not released\n"));
+               goto fail;
+       } else if (strstr(str_file, rom_file_str) != NULL && temp->rom_raw_sstr != NULL) {
+               DHD_ERROR(("rom_raw_sstr was not released\n"));
+               goto fail;
+       }
+
+       raw_sstr = MALLOC(osh, logstrs_size);
+       if (raw_sstr == NULL) {
+               DHD_ERROR(("%s: Failed to allocate raw_sstr memory \n", __FUNCTION__));
                goto fail;
        }
 
@@ -8704,20 +8820,20 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
                goto fail;
        }
 
-       error = vfs_read(filep, raw_fmts, logstrs_size, (&filep->f_pos));
+       error = vfs_read(filep, raw_sstr, logstrs_size, (&filep->f_pos));
        if (error != logstrs_size) {
                DHD_ERROR(("%s: %s read failed %d \n", __FUNCTION__, str_file, error));
                goto fail;
        }
 
        if (strstr(str_file, ram_file_str) != NULL) {
-               temp->raw_sstr = raw_fmts;
+               temp->raw_sstr = raw_sstr;
                temp->raw_sstr_size = logstrs_size;
                temp->ramstart = ramstart;
                temp->rodata_start = rodata_start;
                temp->rodata_end = rodata_end;
        } else if (strstr(str_file, rom_file_str) != NULL) {
-               temp->rom_raw_sstr = raw_fmts;
+               temp->rom_raw_sstr = raw_sstr;
                temp->rom_raw_sstr_size = logstrs_size;
                temp->rom_ramstart = ramstart;
                temp->rom_rodata_start = rodata_start;
@@ -8730,9 +8846,9 @@ dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, ch
        return BCME_OK;
 
 fail:
-       if (raw_fmts) {
-               MFREE(osh, raw_fmts, logstrs_size);
-               raw_fmts = NULL;
+       if (raw_sstr) {
+               MFREE(osh, raw_sstr, logstrs_size);
+               raw_sstr = NULL;
        }
 
 fail1:
@@ -8742,9 +8858,15 @@ fail1:
        set_fs(fs);
 
        if (strstr(str_file, ram_file_str) != NULL) {
-               temp->raw_sstr = NULL;
+               if (temp->raw_sstr != NULL) {
+                       MFREE(osh, temp->raw_sstr, temp->raw_sstr_size);
+                       temp->raw_sstr = NULL;
+               }
        } else if (strstr(str_file, rom_file_str) != NULL) {
-               temp->rom_raw_sstr = NULL;
+               if (temp->rom_raw_sstr != NULL) {
+                       MFREE(osh, temp->rom_raw_sstr, temp->rom_raw_sstr_size);
+                       temp->rom_raw_sstr = NULL;
+               }
        }
 
        return error;
@@ -8913,11 +9035,13 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 #endif /* PCIE_INB_DW */
        init_waitqueue_head(&dhd->ctrl_wait);
        init_waitqueue_head(&dhd->dhd_bus_busy_state_wait);
+       init_waitqueue_head(&dhd->dmaxfer_wait);
        dhd->pub.dhd_bus_busy_state = 0;
 
        /* Initialize the spinlocks */
        spin_lock_init(&dhd->sdlock);
        spin_lock_init(&dhd->txqlock);
+       spin_lock_init(&dhd->rxqlock);
        spin_lock_init(&dhd->dhd_lock);
        spin_lock_init(&dhd->rxf_lock);
 #ifdef WLTDLS
@@ -9007,12 +9131,16 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
                goto fail;
        }
 
-
-#if defined(DBG_PKT_MON_INIT_DEFAULT) && defined(DBG_PKT_MON)
+#ifdef DBG_PKT_MON
+       dhd->pub.dbg->pkt_mon_lock = dhd_os_spin_lock_init(dhd->pub.osh);
+#ifdef DBG_PKT_MON_INIT_DEFAULT
        dhd_os_dbg_attach_pkt_monitor(&dhd->pub);
-#endif /* DHD_DEBUG && DBG_PKT_MON */
-
+#endif /* DBG_PKT_MON_INIT_DEFAULT */
+#endif /* DBG_PKT_MON */
 #endif /* DEBUGABILITY */
+#ifdef DHD_PKT_LOGGING
+       dhd_os_attach_pktlog(&dhd->pub);
+#endif /* DHD_PKT_LOGGING */
 
        if (dhd_sta_pool_init(&dhd->pub, DHD_MAX_STA) != BCME_OK) {
                DHD_ERROR(("%s: Initializing %u sta\n", __FUNCTION__, DHD_MAX_STA));
@@ -9067,7 +9195,8 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
                        goto fail;
                }
        } else {
-#if defined(ARGOS_CPU_SCHEDULER) && defined(ARGOS_DPC_TASKLET_CTL)
+#if defined(ARGOS_CPU_SCHEDULER) && defined(ARGOS_DPC_TASKLET_CTL) && \
+       defined(CONFIG_SCHED_HMP) && !defined(DHD_LB_IRQSET)
                if (!zalloc_cpumask_var(&dhd->pub.default_cpu_mask, GFP_KERNEL)) {
                        DHD_ERROR(("dpc tasklet, zalloc_cpumask_var error\n"));
                        dhd->pub.affinity_isdpc = FALSE;
@@ -9099,7 +9228,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
                                dhd->pub.affinity_isdpc = TRUE;
                        }
                }
-#endif /* ARGOS_CPU_SCHEDULER && ARGOS_DPC_TASKLET_CTL */
+#endif /* ARGOS_CPU_SCHEDULER && ARGOS_DPC_TASKLET_CTL && CONFIG_SCHED_HMP && !DHD_LB_IRQSET */
                /*  use tasklet for dpc */
                tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd);
                dhd->thr_dpc_ctl.thr_pid = -1;
@@ -9155,22 +9284,12 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        cpufreq_register_notifier(&dhd->freq_trans, CPUFREQ_TRANSITION_NOTIFIER);
 #endif
 #ifdef DHDTCPACK_SUPPRESS
-#ifdef BCMSDIO
-       dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_DELAYTX);
-#elif defined(BCMPCIE)
-       dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_HOLD);
-#else
-       dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
-#endif /* BCMSDIO */
+       dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_DEFAULT);
 #endif /* DHDTCPACK_SUPPRESS */
 
 #if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
 #endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
 
-       dhd_state |= DHD_ATTACH_STATE_DONE;
-       dhd->dhd_state = dhd_state;
-
-       dhd_found++;
 
 #ifdef DHD_DEBUG_PAGEALLOC
        register_page_corrupt_cb(dhd_page_corrupt_cb, &dhd->pub);
@@ -9245,6 +9364,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        DHD_INFO(("%s load balance init tx_pend_queue\n", __FUNCTION__));
 #endif /* DHD_LB_TXP */
 
+       dhd_state |= DHD_ATTACH_STATE_LB_ATTACH_DONE;
 #endif /* DHD_LB */
 
 #ifdef SHOW_LOGTRACE
@@ -9265,6 +9385,20 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
 
        (void)dhd_sysfs_init(dhd);
 
+       dhd_state |= DHD_ATTACH_STATE_DONE;
+       dhd->dhd_state = dhd_state;
+
+       dhd_found++;
+
+#ifdef DHD_DUMP_MNGR
+       dhd->pub.dump_file_manage =
+               (dhd_dump_file_manage_t *)MALLOCZ(dhd->pub.osh, sizeof(dhd_dump_file_manage_t));
+       if (unlikely(!dhd->pub.dump_file_manage)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "dhd_dump_file_manage_t\n", __FUNCTION__));
+       }
+#endif /* DHD_DUMP_MNGR */
+
        return &dhd->pub;
 
 fail:
@@ -9293,6 +9427,11 @@ int dhd_get_fw_mode(dhd_info_t *dhdinfo)
        return DHD_FLAG_STA_MODE;
 }
 
+int dhd_bus_get_fw_mode(dhd_pub_t *dhdp)
+{
+       return dhd_get_fw_mode(dhdp->info);
+}
+
 bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
 {
        int fw_len;
@@ -9304,7 +9443,8 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
        const char *uc = NULL;
 #endif /* DHD_UCODE_DOWNLOAD */
        wifi_adapter_info_t *adapter = dhdinfo->adapter;
-
+       int fw_path_len = sizeof(dhdinfo->fw_path);
+       int nv_path_len = sizeof(dhdinfo->nv_path);
 
        /* Update firmware and nvram path. The path may be from adapter info or module parameter
         * The path from adapter info is used for initialization only (as it won't change).
@@ -9319,10 +9459,10 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
        /* set default firmware and nvram path for built-in type driver */
        if (!dhd_download_fw_on_driverload) {
 #ifdef CONFIG_BCMDHD_FW_PATH
-               fw = CONFIG_BCMDHD_FW_PATH;
+               fw = VENDOR_PATH CONFIG_BCMDHD_FW_PATH;
 #endif /* CONFIG_BCMDHD_FW_PATH */
 #ifdef CONFIG_BCMDHD_NVRAM_PATH
-               nv = CONFIG_BCMDHD_NVRAM_PATH;
+               nv = VENDOR_PATH CONFIG_BCMDHD_NVRAM_PATH;
 #endif /* CONFIG_BCMDHD_NVRAM_PATH */
        }
 
@@ -9343,8 +9483,10 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
         */
        if (firmware_path[0] != '\0')
                fw = firmware_path;
+
        if (nvram_path[0] != '\0')
                nv = nvram_path;
+
 #ifdef DHD_UCODE_DOWNLOAD
        if (ucode_path[0] != '\0')
                uc = ucode_path;
@@ -9352,21 +9494,49 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
 
        if (fw && fw[0] != '\0') {
                fw_len = strlen(fw);
-               if (fw_len >= sizeof(dhdinfo->fw_path)) {
+               if (fw_len >= fw_path_len) {
                        DHD_ERROR(("fw path len exceeds max len of dhdinfo->fw_path\n"));
                        return FALSE;
                }
-               strncpy(dhdinfo->fw_path, fw, sizeof(dhdinfo->fw_path));
+               strncpy(dhdinfo->fw_path, fw, fw_path_len);
                if (dhdinfo->fw_path[fw_len-1] == '\n')
                       dhdinfo->fw_path[fw_len-1] = '\0';
        }
        if (nv && nv[0] != '\0') {
                nv_len = strlen(nv);
-               if (nv_len >= sizeof(dhdinfo->nv_path)) {
+               if (nv_len >= nv_path_len) {
                        DHD_ERROR(("nvram path len exceeds max len of dhdinfo->nv_path\n"));
                        return FALSE;
                }
-               strncpy(dhdinfo->nv_path, nv, sizeof(dhdinfo->nv_path));
+               memset(dhdinfo->nv_path, 0, nv_path_len);
+               strncpy(dhdinfo->nv_path, nv, nv_path_len);
+#ifdef DHD_USE_SINGLE_NVRAM_FILE
+               /* Remove "_net" or "_mfg" tag from current nvram path */
+               {
+                       char *nvram_tag = "nvram_";
+                       char *ext_tag = ".txt";
+                       char *sp_nvram = strnstr(dhdinfo->nv_path, nvram_tag, nv_path_len);
+                       bool valid_buf = sp_nvram && ((uint32)(sp_nvram + strlen(nvram_tag) +
+                               strlen(ext_tag) - dhdinfo->nv_path) <= nv_path_len);
+                       if (valid_buf) {
+                               char *sp = sp_nvram + strlen(nvram_tag) - 1;
+                               uint32 padding_size = (uint32)(dhdinfo->nv_path +
+                                       nv_path_len - sp);
+                               memset(sp, 0, padding_size);
+                               strncat(dhdinfo->nv_path, ext_tag, strlen(ext_tag));
+                               nv_len = strlen(dhdinfo->nv_path);
+                               DHD_INFO(("%s: new nvram path = %s\n",
+                                       __FUNCTION__, dhdinfo->nv_path));
+                       } else if (sp_nvram) {
+                               DHD_ERROR(("%s: buffer space for nvram path is not enough\n",
+                                       __FUNCTION__));
+                               return FALSE;
+                       } else {
+                               DHD_ERROR(("%s: Couldn't find the nvram tag. current"
+                                       " nvram path = %s\n", __FUNCTION__, dhdinfo->nv_path));
+                       }
+               }
+#endif /* DHD_USE_SINGLE_NVRAM_FILE */
                if (dhdinfo->nv_path[nv_len-1] == '\n')
                       dhdinfo->nv_path[nv_len-1] = '\0';
        }
@@ -9498,7 +9668,7 @@ bool dhd_validate_chipid(dhd_pub_t *dhdp)
        config_chipid = BCM43430_CHIP_ID;
 #elif defined(BCM43018_CHIP)
        config_chipid = BCM43018_CHIP_ID;
-#elif defined(BCM43455_CHIP)
+#elif defined(BCM43455_CHIP) || defined(BCM43456_CHIP)
        config_chipid = BCM4345_CHIP_ID;
 #elif defined(BCM4334W_CHIP)
        config_chipid = BCM43342_CHIP_ID;
@@ -9658,6 +9828,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
                DHD_DISABLE_RUNTIME_PM(&dhd->pub);
                DHD_PERIM_UNLOCK(dhdp);
                DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
+               DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
                return -ENODEV;
        }
 
@@ -9705,6 +9876,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
                dhd_os_sdunlock(dhdp);
 #endif /* BCMSDIO */
                DHD_PERIM_UNLOCK(dhdp);
+               DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
                return -ENODEV;
        }
 
@@ -9755,7 +9927,6 @@ dhd_bus_start(dhd_pub_t *dhdp)
 #ifdef WLTDLS
 int _dhd_tdls_enable(dhd_pub_t *dhd, bool tdls_on, bool auto_on, struct ether_addr *mac)
 {
-       char iovbuf[WLC_IOCTL_SMLEN];
        uint32 tdls = tdls_on;
        int ret = 0;
        uint32 tdls_auto_op = 0;
@@ -9768,8 +9939,8 @@ int _dhd_tdls_enable(dhd_pub_t *dhd, bool tdls_on, bool auto_on, struct ether_ad
 
        if (dhd->tdls_enable == tdls_on)
                goto auto_mode;
-       bcm_mkiovar("tdls_enable", (char *)&tdls, sizeof(tdls), iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "tdls_enable", (char *)&tdls, sizeof(tdls), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s: tdls %d failed %d\n", __FUNCTION__, tdls, ret));
                goto exit;
        }
@@ -9777,31 +9948,29 @@ int _dhd_tdls_enable(dhd_pub_t *dhd, bool tdls_on, bool auto_on, struct ether_ad
 auto_mode:
 
        tdls_auto_op = auto_on;
-       bcm_mkiovar("tdls_auto_op", (char *)&tdls_auto_op, sizeof(tdls_auto_op),
-               iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "tdls_auto_op", (char *)&tdls_auto_op, sizeof(tdls_auto_op), NULL,
+                       0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s: tdls_auto_op failed %d\n", __FUNCTION__, ret));
                goto exit;
        }
 
        if (tdls_auto_op) {
-               bcm_mkiovar("tdls_idle_time", (char *)&tdls_idle_time,
-                       sizeof(tdls_idle_time), iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "tdls_idle_time", (char *)&tdls_idle_time,
+                               sizeof(tdls_idle_time), NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: tdls_idle_time failed %d\n", __FUNCTION__, ret));
                        goto exit;
                }
-               bcm_mkiovar("tdls_rssi_high", (char *)&tdls_rssi_high, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "tdls_rssi_high", (char *)&tdls_rssi_high,
+                               sizeof(tdls_rssi_high), NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: tdls_rssi_high failed %d\n", __FUNCTION__, ret));
                        goto exit;
                }
-               bcm_mkiovar("tdls_rssi_low", (char *)&tdls_rssi_low, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "tdls_rssi_low", (char *)&tdls_rssi_low,
+                               sizeof(tdls_rssi_low), NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: tdls_rssi_low failed %d\n", __FUNCTION__, ret));
                        goto exit;
                }
@@ -9823,7 +9992,6 @@ int dhd_tdls_enable(struct net_device *dev, bool tdls_on, bool auto_on, struct e
 int
 dhd_tdls_set_mode(dhd_pub_t *dhd, bool wfd_mode)
 {
-       char iovbuf[WLC_IOCTL_SMLEN];
        int ret = 0;
        bool auto_on = false;
        uint32 mode =  wfd_mode;
@@ -9843,12 +10011,8 @@ dhd_tdls_set_mode(dhd_pub_t *dhd, bool wfd_mode)
                return ret;
        }
 
-
-       bcm_mkiovar("tdls_wfd_mode", (char *)&mode, sizeof(mode),
-                       iovbuf, sizeof(iovbuf));
-       if (((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) &&
-                       (ret != BCME_UNSUPPORTED)) {
+       ret = dhd_iovar(dhd, 0, "tdls_wfd_mode", (char *)&mode, sizeof(mode), NULL, 0, TRUE);
+       if ((ret < 0) && (ret != BCME_UNSUPPORTED)) {
                DHD_ERROR(("%s: tdls_wfd_mode faile_wfd_mode %d\n", __FUNCTION__, ret));
                return ret;
        }
@@ -9971,9 +10135,9 @@ dhd_get_concurrent_capabilites(dhd_pub_t *dhd)
        } else {
                /* Chip supports p2p but ensure that p2p is really implemented in firmware or not */
                memset(buf, 0, sizeof(buf));
-               bcm_mkiovar("p2p", 0, 0, buf, sizeof(buf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf),
-                       FALSE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "p2p", NULL, 0, (char *)&buf,
+                               sizeof(buf), FALSE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret));
                        return 0;
                } else {
@@ -10012,7 +10176,6 @@ int
 dhd_preinit_aibss_ioctls(dhd_pub_t *dhd, char *iov_buf_smlen)
 {
        int ret = BCME_OK;
-       char iovbuf[WL_EVENTING_MASK_LEN + 12]; /*  Room for "event_msgs" + '\0' + bitvec  */
        aibss_bcn_force_config_t bcn_config;
        uint32 aibss;
 #ifdef WLAIBSS_PS
@@ -10022,9 +10185,8 @@ dhd_preinit_aibss_ioctls(dhd_pub_t *dhd, char *iov_buf_smlen)
        int ibss_coalesce;
 
        aibss = 1;
-       bcm_mkiovar("aibss", (char *)&aibss, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "aibss", (char *)&aibss, sizeof(aibss), NULL, 0, TRUE);
+       if (ret < 0) {
                if (ret == BCME_UNSUPPORTED) {
                        DHD_ERROR(("%s aibss is not supported\n",
                                __FUNCTION__));
@@ -10038,9 +10200,8 @@ dhd_preinit_aibss_ioctls(dhd_pub_t *dhd, char *iov_buf_smlen)
 
 #ifdef WLAIBSS_PS
        aibss_ps = 1;
-       bcm_mkiovar("aibss_ps", (char *)&aibss_ps, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "aibss_ps", (char *)&aibss_ps, sizeof(aibss_ps), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set aibss PS to %d failed  %d\n",
                        __FUNCTION__, aibss, ret));
                return ret;
@@ -10062,21 +10223,19 @@ dhd_preinit_aibss_ioctls(dhd_pub_t *dhd, char *iov_buf_smlen)
        bcn_config.version = AIBSS_BCN_FORCE_CONFIG_VER_0;
        bcn_config.len = sizeof(bcn_config);
 
-       bcm_mkiovar("aibss_bcn_force_config", (char *)&bcn_config,
-               sizeof(aibss_bcn_force_config_t), iov_buf_smlen, WLC_IOCTL_SMLEN);
-       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iov_buf_smlen, WLC_IOCTL_SMLEN, TRUE, 0);
+       ret = dhd_iovar(dhd, 0, "aibss_bcn_force_config", (char *)&bcn_config,
+                       sizeof(aibss_bcn_force_config_t), NULL, 0, TRUE);
        if (ret < 0) {
-               DHD_ERROR(("%s Set aibss_bcn_force_config to %d, %d, %d failed %d\n",
+               DHD_ERROR(("%s Set aibss_bcn_force_config to %d, %d, %d returned (%d)\n",
                        __FUNCTION__, AIBSS_INITIAL_MIN_BCN_DUR, AIBSS_MIN_BCN_DUR,
                        AIBSS_BCN_FLOOD_DUR, ret));
                return ret;
        }
 
        ibss_coalesce = IBSS_COALESCE_DEFAULT;
-       bcm_mkiovar("ibss_coalesce_allowed", (char *)&ibss_coalesce, 4,
-               iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "ibss_coalesce_allowed", (char *)&ibss_coalesce,
+                       sizeof(ibss_coalesce), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set ibss_coalesce_allowed failed  %d\n",
                        __FUNCTION__, ret));
                return ret;
@@ -10087,7 +10246,7 @@ dhd_preinit_aibss_ioctls(dhd_pub_t *dhd, char *iov_buf_smlen)
 }
 #endif /* WLAIBSS */
 
-#ifdef WLADPS
+#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD)
 int
 dhd_enable_adps(dhd_pub_t *dhd, uint8 on)
 {
@@ -10139,7 +10298,7 @@ exit:
        }
        return ret;
 }
-#endif /* WLADPS */
+#endif /* WLADPS || WLADPS_PRIVATE_CMD */
 
 int
 dhd_preinit_ioctls(dhd_pub_t *dhd)
@@ -10182,14 +10341,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifndef PCIE_FULL_DONGLE
        uint32 wl_ap_isolate;
 #endif /* PCIE_FULL_DONGLE */
-
-#if defined(BCMSDIO) || defined(DISABLE_FRAMEBURST)
-       /* default frame burst enabled for PCIe, disabled for SDIO dongles and media targets */
-       uint32 frameburst = 0;
-#else
-       uint32 frameburst = 1;
-#endif /* BCMSDIO */
+       uint32 frameburst = CUSTOM_FRAMEBURST_SET;
        uint wnm_bsstrans_resp = 0;
+#ifdef SUPPORT_SET_CAC
+       uint32 cac = 1;
+#endif /* SUPPORT_SET_CAC */
+
+#if defined(DHD_NON_DMA_M2M_CORRUPTION)
+       dhd_pcie_dmaxfer_lpbk_t pcie_dmaxfer_lpbk;
+#endif /* DHD_NON_DMA_M2M_CORRUPTION */
 
 #ifdef DHD_ENABLE_LPC
        uint32 lpc = 1;
@@ -10292,19 +10452,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef DISABLE_11N_PROPRIETARY_RATES
        uint32 ht_features = 0;
 #endif /* DISABLE_11N_PROPRIETARY_RATES */
-#ifdef CUSTOM_PSPRETEND_THR
-       uint32 pspretend_thr = CUSTOM_PSPRETEND_THR;
-#endif
 #ifdef CUSTOM_EVENT_PM_WAKE
        uint32 pm_awake_thresh = CUSTOM_EVENT_PM_WAKE;
 #endif /* CUSTOM_EVENT_PM_WAKE */
-       uint32 rsdb_mode = 0;
+       wl_config_t rsdb_mode;
 #ifdef ENABLE_TEMP_THROTTLING
        wl_temp_control_t temp_control;
 #endif /* ENABLE_TEMP_THROTTLING */
 #ifdef DISABLE_PRUNED_SCAN
        uint32 scan_features = 0;
 #endif /* DISABLE_PRUNED_SCAN */
+#ifdef DHD_2G_ONLY_SUPPORT
+       uint band = WLC_BAND_2G;
+#endif /* DHD_2G_ONLY_SUPPORT */
 #ifdef PKT_FILTER_SUPPORT
        dhd_pkt_filter_enable = TRUE;
 #ifdef APF
@@ -10357,9 +10517,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef GET_CUSTOM_MAC_ENABLE
        ret = wifi_platform_get_mac_addr(dhd->info->adapter, ea_addr.octet);
        if (!ret) {
-               memset(buf, 0, sizeof(buf));
-               bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf));
-               ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+               ret = dhd_iovar(dhd, 0, "cur_etheraddr", (char *)&ea_addr, ETHER_ADDR_LEN, NULL, 0,
+                               TRUE);
                if (ret < 0) {
                        DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
                        ret = BCME_NOTUP;
@@ -10369,10 +10528,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        } 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) {
+               ret = dhd_iovar(dhd, 0, "cur_etheraddr", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
                        ret = BCME_NOTUP;
                        goto done;
@@ -10384,6 +10541,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #endif /* GET_CUSTOM_MAC_ENABLE */
 
+#ifdef DHD_USE_CLMINFO_PARSER
+       if ((ret = dhd_get_clminfo(dhd, clm_path)) < 0) {
+               if (dhd->is_clm_mult_regrev) {
+                       DHD_ERROR(("%s: CLM Information load failed. Abort initialization.\n",
+                               __FUNCTION__));
+                       goto done;
+               }
+       }
+#endif /* DHD_USE_CLMINFO_PARSER */
        if ((ret = dhd_apply_default_clm(dhd, clm_path)) < 0) {
                DHD_ERROR(("%s: CLM set failed. Abort initialization.\n", __FUNCTION__));
                goto done;
@@ -10393,10 +10559,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        {
                uint32 cap_buf_size = sizeof(dhd->fw_capabilities);
                memset(dhd->fw_capabilities, 0, cap_buf_size);
-               bcm_mkiovar("cap", 0, 0, dhd->fw_capabilities, cap_buf_size - 1);
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, dhd->fw_capabilities,
-                       (cap_buf_size - 1), FALSE, 0)) < 0)
-               {
+               ret = dhd_iovar(dhd, 0, "cap", NULL, 0, dhd->fw_capabilities, (cap_buf_size - 1),
+                               FALSE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: Get Capability failed (error=%d)\n",
                                __FUNCTION__, ret));
                        return 0;
@@ -10430,8 +10595,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                iovbuf[4] = (unsigned char)(rand_mac >> 8);
                iovbuf[5] = (unsigned char)(rand_mac >> 16);
 
-               bcm_mkiovar("cur_etheraddr", (void *)iovbuf, ETHER_ADDR_LEN, buf, sizeof(buf));
-               ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+               ret = dhd_iovar(dhd, 0, "cur_etheraddr", (char *)&iovbuf, ETHER_ADDR_LEN, NULL, 0,
+                               TRUE);
                if (ret < 0) {
                        DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
                } else
@@ -10441,9 +10606,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                dhdsdio_func_blocksize(dhd, 2, DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY);
 #endif /* USE_DYNAMIC_F2_BLKSIZE */
 #ifdef SOFTAP_UAPSD_OFF
-               bcm_mkiovar("wme_apsd", (char *)&wme_apsd, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "wme_apsd", (char *)&wme_apsd, sizeof(wme_apsd), NULL, 0,
+                               TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s: set wme_apsd 0 fail (error=%d)\n",
                                __FUNCTION__, ret));
                }
@@ -10461,10 +10626,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                dhdsdio_func_blocksize(dhd, 2, DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY);
 #endif /* USE_DYNAMIC_F2_BLKSIZE */
                if (FW_SUPPORTED(dhd, rsdb)) {
-                       rsdb_mode = 0;
-                       bcm_mkiovar("rsdb_mode", (char *)&rsdb_mode, 4, iovbuf, sizeof(iovbuf));
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+                       memset(&rsdb_mode, 0, sizeof(rsdb_mode));
+                       ret = dhd_iovar(dhd, 0, "rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode),
+                                       NULL, 0, TRUE);
+                       if (ret < 0) {
                                DHD_ERROR(("%s Disable rsdb_mode is failed ret= %d\n",
                                        __FUNCTION__, ret));
                        }
@@ -10496,11 +10661,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 
                /* Check if we are enabling p2p */
                if (dhd->op_mode & DHD_FLAG_P2P_MODE) {
-                       bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+                       ret = dhd_iovar(dhd, 0, "apsta", (char *)&apsta, sizeof(apsta), NULL, 0,
+                                       TRUE);
+                       if (ret < 0)
                                DHD_ERROR(("%s APSTA for P2P failed ret= %d\n", __FUNCTION__, ret));
-                       }
 
 #if defined(SOFTAP_AND_GC)
                if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_AP,
@@ -10508,17 +10672,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                                DHD_ERROR(("%s WLC_SET_AP failed %d\n", __FUNCTION__, ret));
                }
 #endif
-               memcpy(&p2p_ea, &dhd->mac, ETHER_ADDR_LEN);
-               ETHER_SET_LOCALADDR(&p2p_ea);
-               bcm_mkiovar("p2p_da_override", (char *)&p2p_ea,
-                       ETHER_ADDR_LEN, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
-                       DHD_ERROR(("%s p2p_da_override ret= %d\n", __FUNCTION__, ret));
-               } else {
-                       DHD_INFO(("dhd_preinit_ioctls: p2p_da_override succeeded\n"));
+                       memcpy(&p2p_ea, &dhd->mac, ETHER_ADDR_LEN);
+                       ETHER_SET_LOCALADDR(&p2p_ea);
+                       ret = dhd_iovar(dhd, 0, "p2p_da_override", (char *)&p2p_ea, sizeof(p2p_ea),
+                                       NULL, 0, TRUE);
+                       if (ret < 0)
+                               DHD_ERROR(("%s p2p_da_override ret= %d\n", __FUNCTION__, ret));
+                       else
+                               DHD_INFO(("dhd_preinit_ioctls: p2p_da_override succeeded\n"));
                }
-       }
 #else
        (void)concurrent_mode;
 #endif 
@@ -10530,21 +10692,17 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 
 #ifdef DISABLE_PRUNED_SCAN
        if (FW_SUPPORTED(dhd, rsdb)) {
-               memset(iovbuf, 0, sizeof(iovbuf));
-               bcm_mkiovar("scan_features", (char *)&scan_features,
-                       4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR,
-                       iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "scan_features", (char *)&scan_features,
+                               sizeof(scan_features), iovbuf, sizeof(iovbuf), FALSE);
+               if (ret < 0) {
                        DHD_ERROR(("%s get scan_features is failed ret=%d\n",
                                __FUNCTION__, ret));
                } else {
                        memcpy(&scan_features, iovbuf, 4);
                        scan_features &= ~RSDB_SCAN_DOWNGRADED_CH_PRUNE_ROAM;
-                       memset(iovbuf, 0, sizeof(iovbuf));
-                       bcm_mkiovar("scan_features", (char *)&scan_features,
-                               4, iovbuf, sizeof(iovbuf));
-                       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                               iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+                       ret = dhd_iovar(dhd, 0, "scan_features", (char *)&scan_features,
+                                       sizeof(scan_features), NULL, 0, TRUE);
+                       if (ret < 0) {
                                DHD_ERROR(("%s set scan_features is failed ret=%d\n",
                                        __FUNCTION__, ret));
                        }
@@ -10563,16 +10721,25 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif
        /* Set Country code  */
        if (dhd->dhd_cspec.ccode[0] != 0) {
-               bcm_mkiovar("country", (char *)&dhd->dhd_cspec,
-                       sizeof(wl_country_t), iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+               ret = dhd_iovar(dhd, 0, "country", (char *)&dhd->dhd_cspec, sizeof(wl_country_t),
+                               NULL, 0, TRUE);
+               if (ret < 0)
                        DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__));
        }
 
 
+#ifdef DHD_2G_ONLY_SUPPORT
+       DHD_ERROR(("Enabled DHD 2G only support!!\n"));
+       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_BAND, (char *)&band, sizeof(band), TRUE, 0);
+       if (ret < 0) {
+               DHD_ERROR(("%s Set Band B failed %d\n", __FUNCTION__, ret));
+       }
+#endif /* DHD_2G_ONLY_SUPPORT */
+
        /* Set Listen Interval */
-       bcm_mkiovar("assoc_listen", (char *)&listen_interval, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+       ret = dhd_iovar(dhd, 0, "assoc_listen", (char *)&listen_interval, sizeof(listen_interval),
+                       NULL, 0, TRUE);
+       if (ret < 0)
                DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret));
 
 #if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
@@ -10582,13 +10749,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #endif /* USE_WFA_CERT_CONF */
        /* Disable built-in roaming to allowed ext supplicant to take care of roaming */
-       bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar), NULL, 0, TRUE);
 #endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
 #if defined(ROAM_ENABLE)
 #ifdef DISABLE_BCNLOSS_ROAM
-       bcm_mkiovar("roam_bcnloss_off", (char *)&roam_bcnloss_off, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "roam_bcnloss_off", (char *)&roam_bcnloss_off, sizeof(roam_bcnloss_off),
+                       NULL, 0, TRUE);
 #endif /* DISABLE_BCNLOSS_ROAM */
        if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger,
                sizeof(roam_trigger), TRUE, 0)) < 0)
@@ -10599,35 +10765,33 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta,
                sizeof(roam_delta), TRUE, 0)) < 0)
                DHD_ERROR(("%s: roam delta set failed %d\n", __FUNCTION__, ret));
-       bcm_mkiovar("fullroamperiod", (char *)&roam_fullscan_period, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+       ret = dhd_iovar(dhd, 0, "fullroamperiod", (char *)&roam_fullscan_period,
+                       sizeof(roam_fullscan_period), NULL, 0, TRUE);
+       if (ret < 0)
                DHD_ERROR(("%s: roam fullscan period set failed %d\n", __FUNCTION__, ret));
 #ifdef ROAM_AP_ENV_DETECTION
        if (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER) {
-               bcm_mkiovar("roam_env_detection", (char *)&roam_env_mode,
-                       4, iovbuf, sizeof(iovbuf));
-               if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) == BCME_OK)
+               if (dhd_iovar(dhd, 0, "roam_env_detection", (char *)&roam_env_mode,
+                               sizeof(roam_env_mode), NULL, 0, TRUE) == BCME_OK)
                        dhd->roam_env_detection = TRUE;
-               else {
+               else
                        dhd->roam_env_detection = FALSE;
-               }
        }
 #endif /* ROAM_AP_ENV_DETECTION */
 #endif /* ROAM_ENABLE */
 
 #ifdef CUSTOM_EVENT_PM_WAKE
-       bcm_mkiovar("const_awake_thresh", (char *)&pm_awake_thresh, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "const_awake_thresh", (char *)&pm_awake_thresh,
+                       sizeof(pm_awake_thresh), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s set const_awake_thresh failed %d\n", __FUNCTION__, ret));
        }
 #endif /* CUSTOM_EVENT_PM_WAKE */
 #ifdef OKC_SUPPORT
-       bcm_mkiovar("okc_enable", (char *)&okc, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "okc_enable", (char *)&okc, sizeof(okc), NULL, 0, TRUE);
 #endif
 #ifdef BCMCCX
-       bcm_mkiovar("ccx_enable", (char *)&ccx, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "ccx_enable", (char *)&ccx, sizeof(ccx), NULL, 0, TRUE);
 #endif /* BCMCCX */
 #ifdef WLTDLS
 #ifdef ENABLE_TDLS_AUTO_MODE
@@ -10641,9 +10805,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 
 #ifdef DHD_ENABLE_LPC
        /* Set lpc 1 */
-       bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "lpc", (char *)&lpc, sizeof(lpc), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set lpc failed  %d\n", __FUNCTION__, ret));
 
                if (ret == BCME_NOTDOWN) {
@@ -10652,8 +10815,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                                (char *)&wl_down, sizeof(wl_down), TRUE, 0);
                        DHD_ERROR(("%s lpc fail WL_DOWN : %d, lpc = %d\n", __FUNCTION__, ret, lpc));
 
-                       bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf));
-                       ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                       ret = dhd_iovar(dhd, 0, "lpc", (char *)&lpc, sizeof(lpc), NULL, 0, TRUE);
                        DHD_ERROR(("%s Set lpc ret --> %d\n", __FUNCTION__, ret));
                }
        }
@@ -10679,13 +10841,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        sec_control_pm(dhd, &power_mode);
 #else
        /* Set PowerSave mode */
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
+       (void) dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
 #endif /* DHD_PM_CONTROL_FROM_FILE */
 
 #if defined(BCMSDIO)
        /* Match Host and Dongle rx alignment */
-       bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "bus:txglomalign", (char *)&dongle_align, sizeof(dongle_align),
+                       NULL, 0, TRUE);
 
 
 #ifdef USE_WFA_CERT_CONF
@@ -10695,20 +10857,19 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* USE_WFA_CERT_CONF */
        if (glom != DEFAULT_GLOM_VALUE) {
                DHD_INFO(("%s set glom=0x%X\n", __FUNCTION__, glom));
-               bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
-               dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+               dhd_iovar(dhd, 0, "bus:txglom", (char *)&glom, sizeof(glom), NULL, 0, TRUE);
        }
 #endif /* defined(BCMSDIO) */
 
        /* Setup timeout if Beacons are lost and roam is off to report link down */
-       bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "bcn_timeout", (char *)&bcn_timeout, sizeof(bcn_timeout), NULL, 0, TRUE);
+
        /* Setup assoc_retry_max count to reconnect target AP in dongle */
-       bcm_mkiovar("assoc_retry_max", (char *)&retry_max, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "assoc_retry_max", (char *)&retry_max, sizeof(retry_max), NULL, 0, TRUE);
+
 #if defined(AP) && !defined(WLP2P)
-       bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "apsta", (char *)&apsta, sizeof(apsta), NULL, 0, TRUE);
+
 #endif /* defined(AP) && !defined(WLP2P) */
 
 #ifdef MIMO_ANT_SETTING
@@ -10739,23 +10900,22 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* defined(KEEP_ALIVE) */
 
 #ifdef USE_WL_TXBF
-       bcm_mkiovar("txbf", (char *)&txbf, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
-               DHD_ERROR(("%s Set txbf failed  %d\n", __FUNCTION__, ret));
-       }
+       ret = dhd_iovar(dhd, 0, "txbf", (char *)&txbf, sizeof(txbf), NULL, 0, TRUE);
+       if (ret < 0)
+               DHD_ERROR(("%s Set txbf returned (%d)\n", __FUNCTION__, ret));
+
 #endif /* USE_WL_TXBF */
 
-       bcm_mkiovar("scancache", (char *)&scancache_enab, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "scancache", (char *)&scancache_enab, sizeof(scancache_enab), NULL,
+                       0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set scancache failed %d\n", __FUNCTION__, ret));
        }
 
 #ifdef DISABLE_TXBFR
-       bcm_mkiovar("txbf_bfr_cap", (char *)&txbf_bfr_cap, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "txbf_bfr_cap", (char *)&txbf_bfr_cap, sizeof(txbf_bfr_cap), NULL,
+                       0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Clear txbf_bfr_cap failed  %d\n", __FUNCTION__, ret));
        }
 #endif /* DISABLE_TXBFR */
@@ -10783,16 +10943,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #ifdef DHD_SET_FW_HIGHSPEED
        /* Set ack_ratio */
-       bcm_mkiovar("ack_ratio", (char *)&ack_ratio, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "ack_ratio", (char *)&ack_ratio, sizeof(ack_ratio), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set ack_ratio failed  %d\n", __FUNCTION__, ret));
        }
 
        /* Set ack_ratio_depth */
-       bcm_mkiovar("ack_ratio_depth", (char *)&ack_ratio_depth, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "ack_ratio_depth", (char *)&ack_ratio_depth,
+                       sizeof(ack_ratio_depth), NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set ack_ratio_depth failed  %d\n", __FUNCTION__, ret));
        }
 #endif /* DHD_SET_FW_HIGHSPEED */
@@ -10824,9 +10983,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                ampdu_ba_wsize = CUSTOM_IBSS_AMPDU_BA_WSIZE;
 #endif /* WLAIBSS && CUSTOM_IBSS_AMPDU_BA_WSIZE */
        if (ampdu_ba_wsize != 0) {
-               bcm_mkiovar("ampdu_ba_wsize", (char *)&ampdu_ba_wsize, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "ampdu_ba_wsize", (char *)&ampdu_ba_wsize,
+                               sizeof(ampdu_ba_wsize), NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s Set ampdu_ba_wsize to %d failed  %d\n",
                                __FUNCTION__, ampdu_ba_wsize, ret));
                }
@@ -10838,9 +10997,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                memset(&temp_control, 0, sizeof(temp_control));
                temp_control.enable = 1;
                temp_control.control_bit = TEMP_THROTTLE_CONTROL_BIT;
-               bcm_mkiovar("temp_throttle_control", (char *)&temp_control,
-                       sizeof(wl_temp_control_t), iov_buf, WLC_IOCTL_SMLEN);
-               ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iov_buf, WLC_IOCTL_SMLEN, TRUE, 0);
+               ret = dhd_iovar(dhd, 0, "temp_throttle_control", (char *)&temp_control,
+                               sizeof(temp_control), NULL, 0, TRUE);
                if (ret < 0) {
                        DHD_ERROR(("%s Set temp_throttle_control to %d failed \n",
                                __FUNCTION__, ret));
@@ -10851,9 +11009,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #if defined(CUSTOM_AMPDU_MPDU)
        ampdu_mpdu = CUSTOM_AMPDU_MPDU;
        if (ampdu_mpdu != 0 && (ampdu_mpdu <= ampdu_ba_wsize)) {
-               bcm_mkiovar("ampdu_mpdu", (char *)&ampdu_mpdu, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "ampdu_mpdu", (char *)&ampdu_mpdu, sizeof(ampdu_mpdu),
+                               NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s Set ampdu_mpdu to %d failed  %d\n",
                                __FUNCTION__, CUSTOM_AMPDU_MPDU, ret));
                }
@@ -10863,9 +11021,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #if defined(CUSTOM_AMPDU_RELEASE)
        ampdu_release = CUSTOM_AMPDU_RELEASE;
        if (ampdu_release != 0 && (ampdu_release <= ampdu_ba_wsize)) {
-               bcm_mkiovar("ampdu_release", (char *)&ampdu_release, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-                       sizeof(iovbuf), TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "ampdu_release", (char *)&ampdu_release,
+                               sizeof(ampdu_release), NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s Set ampdu_release to %d failed  %d\n",
                                __FUNCTION__, CUSTOM_AMPDU_RELEASE, ret));
                }
@@ -10875,10 +11033,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #if defined(CUSTOM_AMSDU_AGGSF)
        amsdu_aggsf = CUSTOM_AMSDU_AGGSF;
        if (amsdu_aggsf != 0) {
-               bcm_mkiovar("amsdu_aggsf", (char *)&amsdu_aggsf, 4, iovbuf, sizeof(iovbuf));
-               ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+               ret = dhd_iovar(dhd, 0, "amsdu_aggsf", (char *)&amsdu_aggsf, sizeof(amsdu_aggsf),
+                               NULL, 0, TRUE);
                if (ret < 0) {
-                       DHD_ERROR(("%s Set amsdu_aggsf to %d failed  %d\n",
+                       DHD_ERROR(("%s Set amsdu_aggsf to %d failed %d\n",
                                __FUNCTION__, CUSTOM_AMSDU_AGGSF, ret));
                }
        }
@@ -10887,8 +11045,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #if defined(BCMSUP_4WAY_HANDSHAKE)
        /* Read 4-way handshake requirements */
        if (dhd_use_idsup == 1) {
-               bcm_mkiovar("sup_wpa", (char *)&sup_wpa, 4, iovbuf, sizeof(iovbuf));
-               ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+               ret = dhd_iovar(dhd, 0, "sup_wpa", (char *)&sup_wpa, sizeof(sup_wpa),
+                               (char *)&iovbuf, sizeof(iovbuf), FALSE);
                /* sup_wpa iovar returns NOTREADY status on some platforms using modularized
                 * in-dongle supplicant.
                 */
@@ -10907,9 +11065,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #endif /* SUPPORT_5G_1024QAM_VHT */
        if (vht_features) {
-               bcm_mkiovar("vht_features", (char *)&vht_features, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0))
-                       < 0) {
+               ret = dhd_iovar(dhd, 0, "vht_features", (char *)&vht_features, sizeof(vht_features),
+                               NULL, 0, TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s vht_features set failed %d\n", __FUNCTION__, ret));
 
                        if (ret == BCME_NOTDOWN) {
@@ -10920,46 +11078,44 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                                        " vht_features = 0x%x\n",
                                        __FUNCTION__, ret, vht_features));
 
-                               bcm_mkiovar("vht_features", (char *)&vht_features, 4,
-                                       iovbuf, sizeof(iovbuf));
-                               ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf),
-                                       TRUE, 0);
+                               ret = dhd_iovar(dhd, 0, "vht_features", (char *)&vht_features,
+                                       sizeof(vht_features), NULL, 0, TRUE);
                                DHD_ERROR(("%s vht_features set. ret --> %d\n", __FUNCTION__, ret));
                        }
                }
        }
 #endif /* SUPPORT_2G_VHT || SUPPORT_5G_1024QAM_VHT */
 #ifdef DISABLE_11N_PROPRIETARY_RATES
-       bcm_mkiovar("ht_features", (char *)&ht_features, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "ht_features", (char *)&ht_features, sizeof(ht_features), NULL, 0,
+                       TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s ht_features set failed %d\n", __FUNCTION__, ret));
        }
 #endif /* DISABLE_11N_PROPRIETARY_RATES */
-#ifdef CUSTOM_PSPRETEND_THR
-       /* Turn off MPC in AP mode */
-       bcm_mkiovar("pspretend_threshold", (char *)&pspretend_thr, 4,
-               iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
-               DHD_ERROR(("%s pspretend_threshold for HostAPD failed  %d\n",
-                       __FUNCTION__, ret));
-       }
-#endif
+#ifdef DHD_DISABLE_VHTMODE
+       dhd_disable_vhtmode(dhd);
+#endif /* DHD_DISABLE_VHTMODE */
 
-       bcm_mkiovar("buf_key_b4_m4", (char *)&buf_key_b4_m4, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
-               sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "buf_key_b4_m4", (char *)&buf_key_b4_m4, sizeof(buf_key_b4_m4),
+                       NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s buf_key_b4_m4 set failed %d\n", __FUNCTION__, ret));
        }
-
+#ifdef SUPPORT_SET_CAC
+       bcm_mkiovar("cac", (char *)&cac, sizeof(cac), iovbuf, sizeof(iovbuf));
+       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+               DHD_ERROR(("%s Failed to set cac to %d, %d\n", __FUNCTION__, cac, ret));
+       }
+#endif /* SUPPORT_SET_CAC */
 #ifdef DHD_ULP
        /* Get the required details from dongle during preinit ioctl */
        dhd_ulp_preinit(dhd);
 #endif /* DHD_ULP */
 
        /* Read event_msgs mask */
-       bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
-       if ((ret  = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+                       sizeof(iovbuf), FALSE);
+       if (ret < 0) {
                DHD_ERROR(("%s read Event mask failed %d\n", __FUNCTION__, ret));
                goto done;
        }
@@ -11048,6 +11204,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef DHD_LOSSLESS_ROAMING
        setbit(eventmask, WLC_E_ROAM_PREP);
 #endif
+#ifdef SUPPORT_EVT_SDB_LOG
+       setbit(eventmask, WLC_E_SDB_TRANSITION);
+#endif /* SUPPORT_EVT_SDB_LOG */
 #if defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING)
        dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
 #endif /* defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING) */
@@ -11057,8 +11216,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* defined(BCMPCIE) && defined(EAPOL_PKT_PRIO) */
 
        /* Write updated Event mask */
-       bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret = dhd_iovar(dhd, 0, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, NULL, 0, TRUE);
+       if (ret < 0) {
                DHD_ERROR(("%s Set Event mask failed %d\n", __FUNCTION__, ret));
                goto done;
        }
@@ -11076,8 +11235,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        eventmask_msg->len = ROUNDUP(WLC_E_LAST, NBBY)/NBBY;
 
        /* Read event_msgs_ext mask */
-       bcm_mkiovar("event_msgs_ext", (char *)eventmask_msg, msglen, iov_buf, WLC_IOCTL_SMLEN);
-       ret2  = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iov_buf, WLC_IOCTL_SMLEN, FALSE, 0);
+       ret2 = dhd_iovar(dhd, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, iov_buf,
+                       WLC_IOCTL_SMLEN, FALSE);
+
        if (ret2 == 0) { /* event_msgs_ext must be supported */
                bcopy(iov_buf, eventmask_msg, msglen);
 #ifdef RSSI_MONITOR_SUPPORT
@@ -11086,7 +11246,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef GSCAN_SUPPORT
                setbit(eventmask_msg->mask, WLC_E_PFN_GSCAN_FULL_RESULT);
                setbit(eventmask_msg->mask, WLC_E_PFN_SCAN_COMPLETE);
-               setbit(eventmask_msg->mask, WLC_E_PFN_SWC);
                setbit(eventmask_msg->mask, WLC_E_PFN_SSID_EXT);
                setbit(eventmask_msg->mask, WLC_E_ROAM_EXP_EVENT);
 #endif /* GSCAN_SUPPORT */
@@ -11108,10 +11267,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                eventmask_msg->ver = EVENTMSGS_VER;
                eventmask_msg->command = EVENTMSGS_SET_MASK;
                eventmask_msg->len = ROUNDUP(WLC_E_LAST, NBBY)/NBBY;
-               bcm_mkiovar("event_msgs_ext", (char *)eventmask_msg,
-                       msglen, iov_buf, WLC_IOCTL_SMLEN);
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
-                       iov_buf, WLC_IOCTL_SMLEN, TRUE, 0)) < 0) {
+               ret = dhd_iovar(dhd, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, NULL, 0,
+                               TRUE);
+               if (ret < 0) {
                        DHD_ERROR(("%s write event mask ext failed %d\n", __FUNCTION__, ret));
                        goto done;
                }
@@ -11201,9 +11359,20 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd->pktfilter[DHD_BROADCAST_ARP_FILTER_NUM] = NULL;
        if (FW_SUPPORTED(dhd, pf6)) {
                /* Immediately pkt filter TYPE 6 Dicard Broadcast IP packet */
-               dhd->pktfilter[DHD_IP4BCAST_DROP_FILTER_NUM] =
-                       "107 1 6 IP4_H:16 0xf0 !0xe0 IP4_H:19 0xff 0xff";
-               dhd->pktfilter_count = 8;
+               dhd->pktfilter[DHD_IP4BCAST_DROP_FILTER_NUM] = DISCARD_IPV4_BCAST;
+               /* Immediately pkt filter TYPE 6 Dicard Cisco STP packet */
+               dhd->pktfilter[DHD_CISCO_STP_DROP_FILTER_NUM] =
+                       "108 1 6 ETH_H:14 0xFFFFFFFFFFFF 0xAAAA0300000C";
+               /* Immediately pkt filter TYPE 6 Dicard Cisco XID protocol */
+               dhd->pktfilter[DHD_CISCO_XID_DROP_FILTER_NUM] =
+                       "109 1 6 ETH_H:14 0xFFFFFF 0x0001AF";
+
+               dhd->pktfilter_count = 10;
+#ifdef DISCARD_UDPNETBIOS
+               /* Immediately pkt filter TYPE 6 Dicard Broadcast IP packet */
+               dhd->pktfilter[DHD_UDPNETBIOS_DROP_FILTER_NUM] = DISCARD_UDPNETBIOS;
+               dhd->pktfilter_count++;
+#endif /* DISCARD_UDPNETBIOS */
        }
 
 #ifdef GAN_LITE_NAT_KEEPALIVE_FILTER
@@ -11226,30 +11395,27 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_set_packet_filter(dhd);
 #endif /* PKT_FILTER_SUPPORT */
 #ifdef DISABLE_11N
-       bcm_mkiovar("nmode", (char *)&nmode, 4, iovbuf, sizeof(iovbuf));
-       if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+       ret = dhd_iovar(dhd, 0, "nmode", (char *)&nmode, sizeof(nmode), NULL, 0, TRUE);
+       if (ret < 0)
                DHD_ERROR(("%s wl nmode 0 failed %d\n", __FUNCTION__, ret));
 #endif /* DISABLE_11N */
 
 #ifdef ENABLE_BCN_LI_BCN_WAKEUP
-       bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, 4, iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn, sizeof(bcn_li_bcn), NULL, 0, TRUE);
 #endif /* ENABLE_BCN_LI_BCN_WAKEUP */
 #ifdef AMPDU_VO_ENABLE
        tid.tid = PRIO_8021D_VO; /* Enable TID(6) for voice */
        tid.enable = TRUE;
-       bcm_mkiovar("ampdu_tid", (char *)&tid, sizeof(tid), iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "ampdu_tid", (char *)&tid, sizeof(tid), NULL, 0, TRUE);
 
        tid.tid = PRIO_8021D_NC; /* Enable TID(7) for voice */
        tid.enable = TRUE;
-       bcm_mkiovar("ampdu_tid", (char *)&tid, sizeof(tid), iovbuf, sizeof(iovbuf));
-       dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+       dhd_iovar(dhd, 0, "ampdu_tid", (char *)&tid, sizeof(tid), NULL, 0, TRUE);
 #endif
        /* query for 'clmver' to get clm version info from firmware */
        memset(buf, 0, sizeof(buf));
-       bcm_mkiovar("clmver", (char *)&buf, 4, buf, sizeof(buf));
-       if ((ret  = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0)
+       ret = dhd_iovar(dhd, 0, "clmver", NULL, 0, buf, sizeof(buf), FALSE);
+       if (ret < 0)
                DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
        else {
                char *clmver_temp_buf = NULL;
@@ -11272,8 +11438,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        /* query for 'ver' to get version info from firmware */
        memset(buf, 0, sizeof(buf));
        ptr = buf;
-       bcm_mkiovar("ver", (char *)&buf, 4, buf, sizeof(buf));
-       if ((ret  = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0)
+       ret = dhd_iovar(dhd, 0, "ver", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+       if (ret < 0)
                DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
        else {
                bcmstrtok(&ptr, "\n", 0);
@@ -11288,6 +11454,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                sec_save_wlinfo(buf, EPI_VERSION_STR, dhd->info->nv_path, clm_version);
 #endif /* WRITE_WLANINFO */
        }
+#ifdef GEN_SOFTAP_INFO_FILE
+       sec_save_softap_info();
+#endif /* GEN_SOFTAP_INFO_FILE */
 
 #if defined(BCMSDIO)
        dhd_txglom_enable(dhd, TRUE);
@@ -11315,8 +11484,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #endif /* PROP_TXSTATUS */
 
 #ifndef DISABLE_11N
-       bcm_mkiovar("ampdu_hostreorder", (char *)&hostreorder, 4, iovbuf, sizeof(iovbuf));
-       if ((ret2 = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+       ret2 = dhd_iovar(dhd, 0, "ampdu_hostreorder", (char *)&hostreorder, sizeof(hostreorder),
+                       NULL, 0, TRUE);
+       if (ret2 < 0) {
                DHD_ERROR(("%s wl ampdu_hostreorder failed %d\n", __FUNCTION__, ret2));
                if (ret2 != BCME_UNSUPPORTED)
                        ret = ret2;
@@ -11328,9 +11498,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                        DHD_ERROR(("%s ampdu_hostreorder fail WL_DOWN : %d, hostreorder :%d\n",
                                __FUNCTION__, ret2, hostreorder));
 
-                       bcm_mkiovar("ampdu_hostreorder", (char *)&hostreorder, 4,
-                               iovbuf, sizeof(iovbuf));
-                       ret2 = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                       ret2 = dhd_iovar(dhd, 0, "ampdu_hostreorder", (char *)&hostreorder,
+                                       sizeof(hostreorder), NULL, 0, TRUE);
                        DHD_ERROR(("%s wl ampdu_hostreorder. ret --> %d\n", __FUNCTION__, ret2));
                        if (ret2 != BCME_UNSUPPORTED)
                                        ret = ret2;
@@ -11354,8 +11523,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        /* For FD we need all the packets at DHD to handle intra-BSS forwarding */
        if (FW_SUPPORTED(dhd, ap)) {
                wl_ap_isolate = AP_ISOLATE_SENDUP_ALL;
-               bcm_mkiovar("ap_isolate", (char *)&wl_ap_isolate, 4, iovbuf, sizeof(iovbuf));
-               if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+               ret = dhd_iovar(dhd, 0, "ap_isolate", (char *)&wl_ap_isolate, sizeof(wl_ap_isolate),
+                               NULL, 0, TRUE);
+               if (ret < 0)
                        DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
        }
 #endif /* PCIE_FULL_DONGLE */
@@ -11379,14 +11549,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef SUPPORT_SENSORHUB
        DHD_ERROR(("%s: SensorHub enabled %d\n",
                        __FUNCTION__, dhd->info->shub_enable));
-       bcm_mkiovar("shub", (char *)&(shub_ctl.enable), 4, iovbuf, sizeof(iovbuf));
-       if ((ret2 = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf),
-               FALSE, 0)) < 0) {
+       ret2 = dhd_iovar(dhd, 0, "shub", NULL, 0,
+                       (char *)&shub_ctl, sizeof(shub_ctl), FALSE);
+       if (ret2 < 0) {
                DHD_ERROR(("%s failed to get shub hub enable information %d\n",
                        __FUNCTION__, ret2));
                dhd->info->shub_enable = 0;
        } else {
-               memcpy(&shub_ctl, iovbuf, sizeof(shub_ctl));
                dhd->info->shub_enable = shub_ctl.enable;
                DHD_ERROR(("%s: checking sensorhub enable %d\n",
                        __FUNCTION__, dhd->info->shub_enable));
@@ -11396,10 +11565,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                        __FUNCTION__, dhd->info->shub_enable));
        dhd->info->shub_enable = FALSE;
        shub_ctl.enable = FALSE;
-       bcm_mkiovar("shub", (char *)&shub_ctl, sizeof(shub_ctl),
-               iovbuf, sizeof(iovbuf));
-       if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf),
-               FALSE, 0)) < 0) {
+       ret2 = dhd_iovar(dhd, 0, "shub", (char *)&shub_ctl, sizeof(shub_ctl),
+                       NULL, 0, TRUE);
+       if (ret2 < 0) {
                DHD_ERROR(("%s failed to set ShubHub disable\n",
                        __FUNCTION__));
        }
@@ -11446,6 +11614,35 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        }
 #endif /* !WBTEXT */
 
+#if defined(DHD_NON_DMA_M2M_CORRUPTION)
+       /* check pcie non dma loopback */
+       if (dhd->op_mode == DHD_FLAG_MFG_MODE) {
+               memset(&pcie_dmaxfer_lpbk, 0, sizeof(dhd_pcie_dmaxfer_lpbk_t));
+               pcie_dmaxfer_lpbk.u.length = PCIE_DMAXFER_LPBK_LENGTH;
+               pcie_dmaxfer_lpbk.lpbkmode = M2M_NON_DMA_LPBK;
+               pcie_dmaxfer_lpbk.wait = TRUE;
+
+               if ((ret = dhd_bus_iovar_op(dhd, "pcie_dmaxfer", NULL, 0,
+                       (char *)&pcie_dmaxfer_lpbk, sizeof(dhd_pcie_dmaxfer_lpbk_t),
+                       IOV_SET)) < 0) {
+                       DHD_ERROR(("failed to check PCIe Non DMA Loopback Test!!! Reason : %d\n",
+                               ret));
+                       goto done;
+               }
+
+               if (pcie_dmaxfer_lpbk.u.status != BCME_OK) {
+                       DHD_ERROR(("failed to check PCIe Non DMA Loopback Test!!! Reason : %d"
+                               " Status : %d\n", ret, pcie_dmaxfer_lpbk.u.status));
+                       ret = BCME_ERROR;
+                       goto done;
+               } else {
+
+                       DHD_ERROR(("successful to check PCIe Non DMA Loopback Test\n"));
+               }
+       }
+#endif /* DHD_NON_DMA_M2M_CORRUPTION */
+
+
        /* WNM capabilities */
        wnm_cap = 0
 #ifdef WL11U
@@ -11455,11 +11652,22 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
                | WL_WNM_BSSTRANS | WL_WNM_MAXIDLE
 #endif
                ;
-       bcm_mkiovar("wnm", (char *)&wnm_cap, sizeof(wnm_cap), iovbuf, sizeof(iovbuf));
-       if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0) < 0) {
+       if (dhd_iovar(dhd, 0, "wnm", (char *)&wnm_cap, sizeof(wnm_cap), NULL, 0, TRUE) < 0) {
                DHD_ERROR(("failed to set WNM capabilities\n"));
        }
 
+#ifdef CUSTOM_ASSOC_TIMEOUT
+       /* set recreate_bi_timeout to increase assoc timeout :
+       * 20 * 100TU * 1024 / 1000 = 2 secs
+       * (beacon wait time = recreate_bi_timeout * beacon_period * 1024 / 1000)
+       */
+       if (dhd_wl_ioctl_set_intiovar(dhd, "recreate_bi_timeout",
+                       CUSTOM_ASSOC_TIMEOUT,
+                       WLC_SET_VAR, TRUE, 0) != BCME_OK) {
+               DHD_ERROR(("failed to set assoc timeout\n"));
+       }
+#endif /* CUSTOM_ASSOC_TIMEOUT */
+
 done:
 
        if (eventmask_msg)
@@ -11475,26 +11683,96 @@ done:
 
 
 int
-dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, int set)
+dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *param_buf, uint param_len, char *res_buf,
+               uint res_len, int set)
 {
-       char buf[strlen(name) + 1 + cmd_len];
-       int len = sizeof(buf);
+       char *buf = NULL;
+       int input_len;
        wl_ioctl_t ioc;
        int ret;
 
-       len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+       if (res_len > WLC_IOCTL_MAXLEN || param_len > WLC_IOCTL_MAXLEN)
+               return BCME_BADARG;
 
-       memset(&ioc, 0, sizeof(ioc));
+       input_len = strlen(name) + 1 + param_len;
+       if (input_len > WLC_IOCTL_MAXLEN)
+               return BCME_BADARG;
 
-       ioc.cmd = set? WLC_SET_VAR : WLC_GET_VAR;
-       ioc.buf = buf;
-       ioc.len = len;
-       ioc.set = set;
+       buf = NULL;
+       if (set) {
+               if (res_buf || res_len != 0) {
+                       DHD_ERROR(("%s: SET wrong arguemnet\n", __FUNCTION__));
+                       ret = BCME_BADARG;
+                       goto exit;
+               }
+               buf = kzalloc(input_len, GFP_KERNEL);
+               if (!buf) {
+                       DHD_ERROR(("%s: mem alloc failed\n", __FUNCTION__));
+                       ret = BCME_NOMEM;
+                       goto exit;
+               }
+               ret = bcm_mkiovar(name, param_buf, param_len, buf, input_len);
+               if (!ret) {
+                       ret = BCME_NOMEM;
+                       goto exit;
+               }
 
-       ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
-       if (!set && ret >= 0)
-               memcpy(cmd_buf, buf, cmd_len);
+               ioc.cmd = WLC_SET_VAR;
+               ioc.buf = buf;
+               ioc.len = input_len;
+               ioc.set = set;
+
+               ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+       } else {
+               if (!res_buf || !res_len) {
+                       DHD_ERROR(("%s: GET failed. resp_buf NULL or length 0.\n", __FUNCTION__));
+                       ret = BCME_BADARG;
+                       goto exit;
+               }
+
+               if (res_len < input_len) {
+                       DHD_INFO(("%s: res_len(%d) < input_len(%d)\n", __FUNCTION__,
+                                       res_len, input_len));
+                       buf = kzalloc(input_len, GFP_KERNEL);
+                       if (!buf) {
+                               DHD_ERROR(("%s: mem alloc failed\n", __FUNCTION__));
+                               ret = BCME_NOMEM;
+                               goto exit;
+                       }
+                       ret = bcm_mkiovar(name, param_buf, param_len, buf, input_len);
+                       if (!ret) {
+                               ret = BCME_NOMEM;
+                               goto exit;
+                       }
+
+                       ioc.cmd = WLC_GET_VAR;
+                       ioc.buf = buf;
+                       ioc.len = input_len;
+                       ioc.set = set;
+
+                       ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+
+                       if (ret == BCME_OK) {
+                               memcpy(res_buf, buf, res_len);
+                       }
+               } else {
+                       memset(res_buf, 0, res_len);
+                       ret = bcm_mkiovar(name, param_buf, param_len, res_buf, res_len);
+                       if (!ret) {
+                               ret = BCME_NOMEM;
+                               goto exit;
+                       }
+
+                       ioc.cmd = WLC_GET_VAR;
+                       ioc.buf = res_buf;
+                       ioc.len = res_len;
+                       ioc.set = set;
 
+                       ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+               }
+       }
+exit:
+       kfree(buf);
        return ret;
 }
 
@@ -11511,7 +11789,10 @@ dhd_getiovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf,
 
        memset(buf, 0, resp_len);
 
-       bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+       ret = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+       if (ret == 0) {
+               return BCME_BUFTOOSHORT;
+       }
 
        memset(&ioc, 0, sizeof(ioc));
 
@@ -11686,11 +11967,15 @@ static int dhd_inetaddr_notifier_call(struct notifier_block *this,
 #ifdef AOE_IP_ALIAS_SUPPORT
                        DHD_ARPOE(("%s:interface is down, AOE clr all for this if\n",
                                __FUNCTION__));
-                       aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx);
-#else
-                       dhd_aoe_hostip_clr(&dhd->pub, idx);
-                       dhd_aoe_arp_clr(&dhd->pub, idx);
+                       if ((dhd_pub->op_mode & DHD_FLAG_HOSTAP_MODE) ||
+                               (ifa->ifa_dev->dev != dhd_linux_get_primary_netdev(dhd_pub))) {
+                               aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx);
+                       } else
 #endif /* AOE_IP_ALIAS_SUPPORT */
+                       {
+                               dhd_aoe_hostip_clr(&dhd->pub, idx);
+                               dhd_aoe_arp_clr(&dhd->pub, idx);
+                       }
                        break;
 
                default:
@@ -11985,9 +12270,9 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
                        dhd_event_logtrace_flush_queue(dhdp);
 #endif /* SHOW_LOGTRACE */
 
-#if defined(BCMPCIE) && defined(DHDTCPACK_SUPPRESS)
+#ifdef DHDTCPACK_SUPPRESS
                        dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF);
-#endif /* BCMPCIE && DHDTCPACK_SUPPRESS */
+#endif /* DHDTCPACK_SUPPRESS */
                        dhd_net_bus_devreset(net, TRUE);
 #ifdef BCMLXSDMMC
                        dhd_net_bus_suspend(net);
@@ -12193,9 +12478,7 @@ void dhd_detach(dhd_pub_t *dhdp)
                        if (ifp->net->reg_state == NETREG_UNINITIALIZED) {
                                free_netdev(ifp->net);
                        } else {
-#if defined(ARGOS_CPU_SCHEDULER) && defined(ARGOS_RPS_CPU_CTL)
                                argos_register_notifier_deinit();
-#endif /*  ARGOS_CPU_SCHEDULER && ARGOS_RPS_CPU_CTL */
 #ifdef SET_RPS_CPUS
                                custom_rps_map_clear(ifp->net->_rx);
 #endif /* SET_RPS_CPUS */
@@ -12252,33 +12535,37 @@ void dhd_detach(dhd_pub_t *dhdp)
                {
                        tasklet_kill(&dhd->tasklet);
                }
-#if defined(DHD_LB_RXP) && defined(PCIE_FULL_DONGLE)
-               __skb_queue_purge(&dhd->rx_pend_queue);
-#endif /* DHD_LB_RXP && PCIE_FULL_DONGLE */
-
-#if defined(DHD_LB_TXP) && defined(PCIE_FULL_DONGLE)
-               __skb_queue_purge(&dhd->tx_pend_queue);
-#endif /* DHD_LB_TXP && PCIE_FULL_DONGLE */
-
        }
 
-#if defined(DHD_LB)
-       /* Kill the Load Balancing Tasklets */
-#if defined(DHD_LB_TXC)
-       tasklet_kill(&dhd->tx_compl_tasklet);
+#ifdef DHD_LB
+       if (dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE) {
+               /* Clear the flag first to avoid calling the cpu notifier */
+               dhd->dhd_state &= ~DHD_ATTACH_STATE_LB_ATTACH_DONE;
+
+               /* Kill the Load Balancing Tasklets */
+#ifdef DHD_LB_RXP
+               cancel_work_sync(&dhd->rx_napi_dispatcher_work);
+               __skb_queue_purge(&dhd->rx_pend_queue);
+#endif /* DHD_LB_RXP */
+#ifdef DHD_LB_TXP
+               cancel_work_sync(&dhd->tx_dispatcher_work);
+               tasklet_kill(&dhd->tx_tasklet);
+               __skb_queue_purge(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+#ifdef DHD_LB_TXC
+               cancel_work_sync(&dhd->tx_compl_dispatcher_work);
+               tasklet_kill(&dhd->tx_compl_tasklet);
 #endif /* DHD_LB_TXC */
-#if defined(DHD_LB_RXC)
-       tasklet_kill(&dhd->rx_compl_tasklet);
+#ifdef DHD_LB_RXC
+               tasklet_kill(&dhd->rx_compl_tasklet);
 #endif /* DHD_LB_RXC */
-#if defined(DHD_LB_TXP)
-       tasklet_kill(&dhd->tx_tasklet);
-#endif /* DHD_LB_TXP */
 
-       if (dhd->cpu_notifier.notifier_call != NULL) {
-               unregister_cpu_notifier(&dhd->cpu_notifier);
+               if (dhd->cpu_notifier.notifier_call != NULL) {
+                       unregister_cpu_notifier(&dhd->cpu_notifier);
+               }
+               dhd_cpumasks_deinit(dhd);
+               DHD_LB_STATS_DEINIT(&dhd->pub);
        }
-       dhd_cpumasks_deinit(dhd);
-       DHD_LB_STATS_DEINIT(&dhd->pub);
 #endif /* DHD_LB */
 
        DHD_SSSR_MEMPOOL_DEINIT(&dhd->pub);
@@ -12298,15 +12585,19 @@ void dhd_detach(dhd_pub_t *dhdp)
        }
 #endif
 
-#ifdef SHOW_LOGTRACE
 #ifdef DEBUGABILITY
        if (dhdp->dbg) {
 #ifdef DBG_PKT_MON
                dhd_os_dbg_detach_pkt_monitor(dhdp);
+               dhd_os_spin_lock_deinit(dhd->pub.osh, dhd->pub.dbg->pkt_mon_lock);
 #endif /* DBG_PKT_MON */
                dhd_os_dbg_detach(dhdp);
        }
 #endif /* DEBUGABILITY */
+#ifdef SHOW_LOGTRACE
+#ifdef DHD_PKT_LOGGING
+       dhd_os_detach_pktlog(dhdp);
+#endif /* DHD_PKT_LOGGING */
        /* Release the skbs from queue for WLC_E_TRACE event */
        dhd_event_logtrace_flush_queue(dhdp);
 
@@ -12425,6 +12716,13 @@ void dhd_detach(dhd_pub_t *dhdp)
        cancel_work_sync(&dhd->event_log_dispatcher_work);
 #endif /* SHOW_LOGTRACE */
 
+#ifdef DHD_DUMP_MNGR
+       if (dhd->pub.dump_file_manage) {
+               MFREE(dhd->pub.osh, dhd->pub.dump_file_manage,
+                               sizeof(dhd_dump_file_manage_t));
+       }
+#endif /* DHD_DUMP_MNGR */
+
        dhd_sysfs_exit(dhd);
        dhd->pub.fw_download_done = FALSE;
 }
@@ -12842,6 +13140,27 @@ dhd_os_busbusy_wait_condition(dhd_pub_t *pub, uint *var, uint condition)
        return timeout;
 }
 
+int
+dhd_os_dmaxfer_wait(dhd_pub_t *pub, uint *condition)
+{
+       int ret = 0;
+       dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+       DHD_PERIM_UNLOCK(pub);
+       ret = wait_event_interruptible(dhd->dmaxfer_wait, (*condition));
+       DHD_PERIM_LOCK(pub);
+
+       return ret;
+}
+
+int
+dhd_os_dmaxfer_wake(dhd_pub_t *pub)
+{
+       dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+       wake_up(&dhd->dmaxfer_wait);
+       return 0;
+}
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
 /* Fix compilation error for FC11 */
@@ -12889,6 +13208,11 @@ dhd_os_wd_timer(void *bus, uint wdtick)
        /* don't start the wd until fw is loaded */
        if (pub->busstate == DHD_BUS_DOWN) {
                DHD_GENERAL_UNLOCK(pub, flags);
+#ifdef BCMSDIO
+               if (!wdtick) {
+                       DHD_OS_WD_WAKE_UNLOCK(pub);
+               }
+#endif /* BCMSDIO */
                return;
        }
 
@@ -12897,10 +13221,16 @@ dhd_os_wd_timer(void *bus, uint wdtick)
                dhd->wd_timer_valid = FALSE;
                DHD_GENERAL_UNLOCK(pub, flags);
                del_timer_sync(&dhd->timer);
+#ifdef BCMSDIO
+               DHD_OS_WD_WAKE_UNLOCK(pub);
+#endif /* BCMSDIO */
                return;
        }
 
        if (wdtick) {
+#ifdef BCMSDIO
+               DHD_OS_WD_WAKE_LOCK(pub);
+#endif /* BCMSDIO */
                dhd_watchdog_ms = (uint)wdtick;
                /* Re arm the timer, at last watchdog period */
                mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
@@ -13116,11 +13446,19 @@ dhd_os_sdunlock_txq(dhd_pub_t *pub)
 void
 dhd_os_sdlock_rxq(dhd_pub_t *pub)
 {
+       dhd_info_t *dhd;
+
+       dhd = (dhd_info_t *)(pub->info);
+       spin_lock_bh(&dhd->rxqlock);
 }
 
 void
 dhd_os_sdunlock_rxq(dhd_pub_t *pub)
 {
+       dhd_info_t *dhd;
+
+       dhd = (dhd_info_t *)(pub->info);
+       spin_unlock_bh(&dhd->rxqlock);
 }
 
 static void
@@ -13226,6 +13564,9 @@ dhd_wl_host_event(dhd_info_t *dhd, int ifidx, void *pktdata, uint16 pktlen,
        int bcmerror = 0;
 #ifdef WL_CFG80211
        unsigned long flags = 0;
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       static uint32 reassoc_err = 0;
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #endif /* WL_CFG80211 */
        ASSERT(dhd != NULL);
 
@@ -13265,6 +13606,29 @@ dhd_wl_host_event(dhd_info_t *dhd, int ifidx, void *pktdata, uint16 pktlen,
                }
                spin_unlock_irqrestore(&dhd->pub.up_lock, flags);
        }
+#ifdef DYNAMIC_MUMIMO_CONTROL
+#define REASSOC_ERROR_RETRY_LIMIT      1
+       if (dhd->pub.reassoc_mumimo_sw) {
+               uint event_type = ntoh32(event->event_type);
+               uint status = ntoh32(event->status);
+
+               if (event_type == WLC_E_REASSOC) {
+                       if (status == WLC_E_STATUS_SUCCESS) {
+                               reassoc_err = 0;
+                       } else {
+                               reassoc_err++;
+                       }
+
+                       if (reassoc_err > REASSOC_ERROR_RETRY_LIMIT) {
+                               dhd->pub.reassoc_mumimo_sw = FALSE;
+                               dhd->pub.murx_block_eapol = FALSE;
+                               DHD_ENABLE_RUNTIME_PM(&dhd->pub);
+                               dhd_txflowcontrol(&dhd->pub, ALL_INTERFACES, OFF);
+                       }
+               }
+       }
+#undef REASSOC_ERROR_RETRY_LIMIT
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #endif /* defined(WL_CFG80211) */
 
        return (bcmerror);
@@ -13409,9 +13773,18 @@ dhd_net_bus_devreset(struct net_device *dev, uint8 flag)
 #endif /* BCMSDIO */
 
        ret = dhd_bus_devreset(&dhd->pub, flag);
+
+       if (flag) {
+               /* Clear some flags for recovery logic */
+               dhd->pub.dongle_trap_occured = 0;
+               dhd->pub.iovar_timeout_occured = 0;
+#ifdef PCIE_FULL_DONGLE
+               dhd->pub.d3ack_timeout_occured = 0;
+#endif /* PCIE_FULL_DONGLE */
+       }
+
        if (ret) {
                DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
-               return ret;
        }
 
        return ret;
@@ -14080,15 +14453,6 @@ dhd_dev_pno_enable_full_scan_result(struct net_device *dev, bool real_time_flag)
        return (dhd_pno_enable_full_scan_result(&dhd->pub, real_time_flag));
 }
 
-/* Linux wrapper to call common dhd_handle_swc_evt */
-void *
-dhd_dev_swc_scan_event(struct net_device *dev, const void  *data, int *send_evt_bytes)
-{
-       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
-
-       return (dhd_handle_swc_evt(&dhd->pub, data, send_evt_bytes));
-}
-
 /* Linux wrapper to call common dhd_handle_hotlist_scan_evt */
 void *
 dhd_dev_hotlist_scan_event(struct net_device *dev,
@@ -14102,11 +14466,11 @@ dhd_dev_hotlist_scan_event(struct net_device *dev,
 /* Linux wrapper to call common dhd_process_full_gscan_result */
 void *
 dhd_dev_process_full_gscan_result(struct net_device *dev,
-const void  *data, int *send_evt_bytes)
+const void  *data, uint32 len, int *send_evt_bytes)
 {
        dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
 
-       return (dhd_process_full_gscan_result(&dhd->pub, data, send_evt_bytes));
+       return (dhd_process_full_gscan_result(&dhd->pub, data, len, send_evt_bytes));
 }
 
 void
@@ -14170,8 +14534,9 @@ dhd_dev_set_lazy_roam_cfg(struct net_device *dev,
        if (dhd->pub.lazy_roam_enable) {
                roam_exp_cfg.flags |= ROAM_EXP_ENABLE_FLAG;
        }
-       err = dhd_iovar(&(dhd->pub), 0, "roam_exp_params",
-                       (char *)&roam_exp_cfg, sizeof(roam_exp_cfg), 1);
+       err = dhd_iovar(&dhd->pub, 0, "roam_exp_params",
+                       (char *)&roam_exp_cfg, sizeof(roam_exp_cfg), NULL, 0,
+                       TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : Failed to execute roam_exp_params %d\n", __FUNCTION__, err));
        }
@@ -14191,8 +14556,9 @@ dhd_dev_lazy_roam_enable(struct net_device *dev, uint32 enable)
                roam_exp_cfg.flags = ROAM_EXP_ENABLE_FLAG;
        }
 
-       err = dhd_iovar(&(dhd->pub), 0, "roam_exp_params",
-               (char *)&roam_exp_cfg, sizeof(roam_exp_cfg), 1);
+       err = dhd_iovar(&dhd->pub, 0, "roam_exp_params",
+                       (char *)&roam_exp_cfg, sizeof(roam_exp_cfg), NULL, 0,
+                       TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : Failed to execute roam_exp_params %d\n", __FUNCTION__, err));
        } else {
@@ -14214,7 +14580,7 @@ dhd_dev_set_lazy_roam_bssid_pref(struct net_device *dev,
        len = sizeof(wl_bssid_pref_cfg_t);
        len += (bssid_pref->count - 1) * sizeof(wl_bssid_pref_list_t);
        err = dhd_iovar(&(dhd->pub), 0, "roam_exp_bssid_pref", (char *)bssid_pref,
-              len, 1);
+               len, NULL, 0, TRUE);
        if (err != BCME_OK) {
                DHD_ERROR(("%s : Failed to execute roam_exp_bssid_pref %d\n", __FUNCTION__, err));
        }
@@ -14265,7 +14631,7 @@ dhd_dev_set_whitelist_ssid(struct net_device *dev, wl_ssid_whitelist_t *ssid_whi
        ssid_whitelist->version = SSID_WHITELIST_VERSION;
        ssid_whitelist->flags = flush ? ROAM_EXP_CLEAR_SSID_WHITELIST : 0;
        err = dhd_iovar(&(dhd->pub), 0, "roam_exp_ssid_whitelist", (char *)ssid_whitelist,
-              len, 1);
+                       len, NULL, 0, TRUE);
        if (err != BCME_OK) {
                DHD_ERROR(("%s : Failed to execute roam_exp_bssid_pref %d\n", __FUNCTION__, err));
        }
@@ -14299,7 +14665,7 @@ dhd_dev_set_rssi_monitor_cfg(struct net_device *dev, int start,
        rssi_monitor.min_rssi = min_rssi;
        rssi_monitor.flags = start ? 0: RSSI_MONITOR_STOP;
        err = dhd_iovar(&(dhd->pub), 0, "rssi_monitor", (char *)&rssi_monitor,
-              sizeof(rssi_monitor), 1);
+               sizeof(rssi_monitor), NULL, 0, TRUE);
        if (err < 0 && err != BCME_UNSUPPORTED) {
                DHD_ERROR(("%s : Failed to execute rssi_monitor %d\n", __FUNCTION__, err));
        }
@@ -14338,8 +14704,8 @@ dhd_dev_cfg_rand_mac_oui(struct net_device *dev, uint8 *oui)
        } else {
                uint8 *rand_mac_oui = dhdp->rand_mac_oui;
                memcpy(rand_mac_oui, oui, DOT11_OUI_LEN);
-               DHD_ERROR(("Random MAC OUI to be used - %02x:%02x:%02x\n", rand_mac_oui[0],
-                   rand_mac_oui[1], rand_mac_oui[2]));
+               DHD_ERROR(("Random MAC OUI to be used - "MACOUIDBG"\n",
+                       MACOUI2STRDBG(rand_mac_oui)));
        }
        return BCME_OK;
 }
@@ -14360,10 +14726,10 @@ dhd_set_rand_mac_oui(dhd_pub_t *dhd)
                wl_cfg.flags = (WL_PFN_MAC_OUI_ONLY_MASK | WL_PFN_SET_MAC_UNASSOC_MASK);
        }
 
-       DHD_ERROR(("Setting rand mac oui to FW - %02x:%02x:%02x\n", rand_mac_oui[0],
-               rand_mac_oui[1], rand_mac_oui[2]));
+       DHD_ERROR(("Setting rand mac oui to FW - "MACOUIDBG"\n",
+               MACOUI2STRDBG(rand_mac_oui)));
 
-       err = dhd_iovar(dhd, 0, "pfn_macaddr", (char *)&wl_cfg, sizeof(wl_cfg), 1);
+       err = dhd_iovar(dhd, 0, "pfn_macaddr", (char *)&wl_cfg, sizeof(wl_cfg), NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_macaddr %d\n", __FUNCTION__, err));
        }
@@ -14483,11 +14849,9 @@ dhd_dev_start_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id, uint8 *ip_pk
        /*
         * Get current mkeep-alive status.
         */
-       bcm_mkiovar("mkeep_alive", &mkeep_alive_id, sizeof(mkeep_alive_id),
-                       pbuf, KA_TEMP_BUF_SIZE);
-
-       if ((res = dhd_wl_ioctl_cmd(dhd_pub, WLC_GET_VAR, pbuf, KA_TEMP_BUF_SIZE,
-                       FALSE, 0)) < 0) {
+       res = dhd_iovar(dhd_pub, 0, "mkeep_alive", &mkeep_alive_id, sizeof(mkeep_alive_id), pbuf,
+                       KA_TEMP_BUF_SIZE, FALSE);
+       if (res < 0) {
                DHD_ERROR(("%s: Get mkeep_alive failed (error=%d)\n", __FUNCTION__, res));
                goto exit;
        } else {
@@ -14582,14 +14946,11 @@ exit:
 int
 dhd_dev_stop_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id)
 {
-       char                    *pbuf = NULL;
-       const char              *str;
+       char                    *pbuf;
        wl_mkeep_alive_pkt_t    mkeep_alive_pkt;
-       wl_mkeep_alive_pkt_t    *mkeep_alive_pktp = NULL;
-       int                     buf_len = 0;
-       int                     str_len = 0;
+       wl_mkeep_alive_pkt_t    *mkeep_alive_pktp;
        int                     res = BCME_ERROR;
-       int                     i = 0;
+       int                     i;
 
        /*
         * The mkeep_alive packet is for STA interface only; if the bss is configured as AP,
@@ -14603,14 +14964,14 @@ dhd_dev_stop_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id)
        /*
         * Get current mkeep-alive status. Skip ID 0 which is being used for NULL pkt.
         */
-       if ((pbuf = kzalloc(KA_TEMP_BUF_SIZE, GFP_KERNEL)) == NULL) {
+       if ((pbuf = kmalloc(KA_TEMP_BUF_SIZE, GFP_KERNEL)) == NULL) {
                DHD_ERROR(("failed to allocate buf with size %d\n", KA_TEMP_BUF_SIZE));
                return res;
        }
 
-       bcm_mkiovar("mkeep_alive", &mkeep_alive_id, sizeof(mkeep_alive_id), pbuf, KA_TEMP_BUF_SIZE);
-
-       if ((res = dhd_wl_ioctl_cmd(dhd_pub, WLC_GET_VAR, pbuf, KA_TEMP_BUF_SIZE, FALSE, 0)) < 0) {
+       res = dhd_iovar(dhd_pub, 0, "mkeep_alive", &mkeep_alive_id,
+                       sizeof(mkeep_alive_id), pbuf, KA_TEMP_BUF_SIZE, FALSE);
+       if (res < 0) {
                DHD_ERROR(("%s: Get mkeep_alive failed (error=%d)\n", __FUNCTION__, res));
                goto exit;
        } else {
@@ -14635,29 +14996,15 @@ dhd_dev_stop_mkeep_alive(dhd_pub_t *dhd_pub, uint8 mkeep_alive_id)
        if (dtoh32(mkeep_alive_pktp->period_msec != 0)) {
                DHD_INFO(("stop mkeep_alive on ID %d\n", mkeep_alive_id));
                memset(&mkeep_alive_pkt, 0, sizeof(wl_mkeep_alive_pkt_t));
-               memset(pbuf, 0, KA_TEMP_BUF_SIZE);
-               str = "mkeep_alive";
-               str_len = strlen(str);
-               strncpy(pbuf, str, str_len);
-               pbuf[str_len] = '\0';
-
-               mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (pbuf + str_len + 1);
 
                mkeep_alive_pkt.period_msec = 0;
-               buf_len = str_len + 1;
                mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION);
                mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
                mkeep_alive_pkt.keep_alive_id = mkeep_alive_id;
-               buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
-
-               /*
-                * Keep-alive attributes are set in local variable (mkeep_alive_pkt), and
-                * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no
-                * guarantee that the buffer is properly aligned.
-                */
-               memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN);
 
-               res = dhd_wl_ioctl_cmd(dhd_pub, WLC_SET_VAR, pbuf, buf_len, TRUE, 0);
+               res = dhd_iovar(dhd_pub, 0, "mkeep_alive",
+                               (char *)&mkeep_alive_pkt,
+                               WL_MKEEP_ALIVE_FIXED_LEN, NULL, 0, TRUE);
        } else {
                DHD_ERROR(("%s: ID %u does not exist.\n", __FUNCTION__, mkeep_alive_id));
                res = BCME_NOTFOUND;
@@ -15057,6 +15404,14 @@ int dhd_os_send_hang_message(dhd_pub_t *dhdp)
 #endif /* DHD_HANG_SEND_UP_TEST */
 
                if (!dhdp->hang_was_sent) {
+#if defined(CONFIG_BCM_DETECT_CONSECUTIVE_HANG)
+                       dhdp->hang_counts++;
+                       if (dhdp->hang_counts >= MAX_CONSECUTIVE_HANG_COUNTS) {
+                               DHD_ERROR(("%s, Consecutive hang from Dongle :%u\n",
+                                       __func__, dhdp->hang_counts));
+                               BUG_ON(1);
+                       }
+#endif /* CONFIG_BCM_DETECT_CONSECUTIVE_HANG */
 #ifdef DHD_DEBUG_UART
                        /* If PCIe lane has broken, execute the debug uart application
                         * to gether a ramdump data from dongle via uart
@@ -15155,10 +15510,10 @@ void dhd_get_customized_country_code(struct net_device *dev, char *country_iso_c
        wl_country_t *cspec)
 {
        dhd_info_t *dhd = DHD_DEV_INFO(dev);
-#if defined(DHD_BLOB_EXISTENCE_CHECK)
-       if (!dhd->pub.is_blob)
-#endif /* DHD_BLOB_EXISTENCE_CHECK */
-       {
+       dhd_pub_t *dhdp = &dhd->pub;
+
+       BCM_REFERENCE(dhdp);
+       if (!CHECK_IS_BLOB(dhdp) || CHECK_IS_MULT_REGREV(dhdp)) {
 #if defined(CUSTOM_COUNTRY_CODE)
                get_customized_country_code(dhd->adapter, country_iso_code, cspec,
                        dhd->pub.dhd_cflags);
@@ -15167,17 +15522,24 @@ void dhd_get_customized_country_code(struct net_device *dev, char *country_iso_c
 #endif /* CUSTOM_COUNTRY_CODE */
        }
 
+#if defined(KEEP_KR_REGREV)
+       if (strncmp(country_iso_code, "KR", 3) == 0) {
+               if (!CHECK_IS_BLOB(dhdp) || CHECK_IS_MULT_REGREV(dhdp)) {
+                       if (strncmp(dhd->pub.vars_ccode, "KR", 3) == 0) {
+                               cspec->rev = dhd->pub.vars_regrev;
+                       }
+               }
+       }
+#endif /* KEEP_KR_REGREV */
+
 #ifdef KEEP_JP_REGREV
        if (strncmp(country_iso_code, "JP", 3) == 0) {
-#if defined(DHD_BLOB_EXISTENCE_CHECK)
-               if (dhd->pub.is_blob) {
+               if (CHECK_IS_BLOB(dhdp) && !CHECK_IS_MULT_REGREV(dhdp)) {
                        if (strncmp(dhd->pub.vars_ccode, "J1", 3) == 0) {
                                memcpy(cspec->ccode, dhd->pub.vars_ccode,
                                        sizeof(dhd->pub.vars_ccode));
                        }
-               } else
-#endif /* DHD_BLOB_EXISTENCE_CHECK */
-               {
+               } else {
                        if (strncmp(dhd->pub.vars_ccode, "JP", 3) == 0) {
                                cspec->rev = dhd->pub.vars_regrev;
                        }
@@ -15195,27 +15557,83 @@ void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notif
 
        if (dhd && dhd->pub.up) {
                memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
+#ifdef DHD_DISABLE_VHTMODE
+               dhd_disable_vhtmode(&dhd->pub);
+#endif /* DHD_DISABLE_VHTMODE */
+
 #ifdef WL_CFG80211
                wl_update_wiphybands(cfg, notify);
 #endif
        }
 }
 
-void dhd_bus_band_set(struct net_device *dev, uint band)
+#ifdef DHD_DISABLE_VHTMODE
+void
+dhd_disable_vhtmode(dhd_pub_t *dhd)
 {
-       dhd_info_t *dhd = DHD_DEV_INFO(dev);
-#ifdef WL_CFG80211
-       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
-#endif
-       if (dhd && dhd->pub.up) {
-#ifdef WL_CFG80211
-               wl_update_wiphybands(cfg, true);
-#endif
+       int ret = 0;
+       uint32 vhtmode = FALSE;
+       char buf[32];
+
+       /* Get vhtmode */
+       ret = dhd_iovar(dhd, 0, "vhtmode", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+       if (ret < 0) {
+               DHD_ERROR(("%s Get vhtmode Fail ret %d\n", __FUNCTION__, ret));
+               return;
        }
-}
+       memcpy(&vhtmode, buf, sizeof(uint32));
+       if (vhtmode == 0) {
+               DHD_ERROR(("%s Get vhtmode is 0\n", __FUNCTION__));
+               return;
+       }
+       vhtmode = FALSE;
 
-int dhd_net_set_fw_path(struct net_device *dev, char *fw)
-{
+       /* Set vhtmode */
+       ret = dhd_iovar(dhd, 0, "vhtmode", (char *)&vhtmode, sizeof(vhtmode), NULL, 0, TRUE);
+       if (ret == 0) {
+               DHD_ERROR(("%s Set vhtmode Success %d\n", __FUNCTION__, vhtmode));
+       } else {
+               if (ret == BCME_NOTDOWN) {
+                       uint wl_down = 1;
+                       ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN,
+                               (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+                       if (ret) {
+                               DHD_ERROR(("%s WL_DOWN Fail ret %d\n", __FUNCTION__, ret));
+                               return;
+                       }
+
+                       ret = dhd_iovar(dhd, 0, "vhtmode", (char *)&vhtmode,
+                               sizeof(vhtmode), NULL, 0, TRUE);
+                       DHD_ERROR(("%s Set vhtmode %d, ret %d\n", __FUNCTION__, vhtmode, ret));
+
+                       ret = dhd_wl_ioctl_cmd(dhd, WLC_UP,
+                               (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+                       if (ret) {
+                               DHD_ERROR(("%s WL_UP Fail ret %d\n", __FUNCTION__, ret));
+                       }
+               } else {
+                       DHD_ERROR(("%s Set vhtmode 0 failed  %d\n", __FUNCTION__, ret));
+               }
+       }
+}
+#endif /* DHD_DISABLE_VHTMODE */
+
+
+void dhd_bus_band_set(struct net_device *dev, uint band)
+{
+       dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#ifdef WL_CFG80211
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif
+       if (dhd && dhd->pub.up) {
+#ifdef WL_CFG80211
+               wl_update_wiphybands(cfg, true);
+#endif
+       }
+}
+
+int dhd_net_set_fw_path(struct net_device *dev, char *fw)
+{
        dhd_info_t *dhd = DHD_DEV_INFO(dev);
 
        if (!fw || fw[0] == '\0')
@@ -15452,7 +15870,7 @@ dhd_convert_memdump_type_to_str(uint32 type, char *buf)
                        type_str = "SCAN_Busy";
                        break;
                case DUMP_TYPE_BY_SYSDUMP:
-                       type_str = "BY_SYSDUMP";
+                       type_str = "BY_SYSDUMP_USER";
                        break;
                case DUMP_TYPE_BY_LIVELOCK:
                        type_str = "BY_LIVELOCK";
@@ -15484,6 +15902,11 @@ dhd_convert_memdump_type_to_str(uint32 type, char *buf)
                case DUMP_TYPE_HANG_ON_IFACE_OP_FAIL:
                        type_str = "HANG_IFACE_OP_FAIL";
                        break;
+#ifdef DEBUG_DNGL_INIT_FAIL
+               case DUMP_TYPE_DONGLE_INIT_FAILURE;
+                       type_str = "DONGLE_INIT_FAIL";
+                       break;
+#endif /* DEBUG_DNGL_INIT_FAIL */
 #ifdef SUPPORT_LINKDOWN_RECOVERY
                case DUMP_TYPE_READ_SHM_FAIL:
                        type_str = "READ_SHM_FAIL";
@@ -15532,7 +15955,19 @@ write_dump_to_file(dhd_pub_t *dhd, uint8 *buf, int size, char *fname)
         * file instead of caching it. O_TRUNC flag ensures that file will be re-written
         * instead of appending.
         */
-       file_mode = O_CREAT | O_WRONLY | O_DIRECT | O_SYNC | O_TRUNC;
+       file_mode = O_CREAT | O_WRONLY | O_SYNC;
+       {
+               struct file *fp = filp_open(memdump_path, file_mode, 0664);
+               /* Check if it is live Brix image having /installmedia, else use /data */
+               if (IS_ERR(fp)) {
+                       DHD_ERROR(("open file %s, try /data/\n", memdump_path));
+                       snprintf(memdump_path, sizeof(memdump_path), "%s%s_%s_%ld.%ld",
+                               "/data/", fname, memdump_type,
+                               (unsigned long)curtime.tv_sec, (unsigned long)curtime.tv_usec);
+               } else {
+                       filp_close(fp, NULL);
+               }
+       }
 #endif /* CUSTOMER_HW4_DEBUG */
 
        /* print SOCRAM dump file path */
@@ -15541,6 +15976,12 @@ write_dump_to_file(dhd_pub_t *dhd, uint8 *buf, int size, char *fname)
        /* Write file */
        ret = write_file(memdump_path, file_mode, buf, size);
 
+#ifdef DHD_DUMP_MNGR
+       if (ret == BCME_OK) {
+               dhd_dump_file_manage_enqueue(dhd, memdump_path, fname);
+       }
+#endif /* DHD_DUMP_MNGR */
+
        return ret;
 }
 #endif /* DHD_DEBUG */
@@ -16076,11 +16517,12 @@ int dhd_os_wd_wake_lock(dhd_pub_t *pub)
 
        if (dhd) {
                spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+               if (dhd->wakelock_wd_counter == 0 && !dhd->waive_wakelock) {
 #ifdef CONFIG_HAS_WAKELOCK
-               /* if wakelock_wd_counter was never used : lock it at once */
-               if (!dhd->wakelock_wd_counter)
+                       /* if wakelock_wd_counter was never used : lock it at once */
                        wake_lock(&dhd->wl_wdwake);
 #endif
+               }
                dhd->wakelock_wd_counter++;
                ret = dhd->wakelock_wd_counter;
                spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
@@ -16096,11 +16538,13 @@ int dhd_os_wd_wake_unlock(dhd_pub_t *pub)
 
        if (dhd) {
                spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
-               if (dhd->wakelock_wd_counter) {
+               if (dhd->wakelock_wd_counter > 0) {
                        dhd->wakelock_wd_counter = 0;
+                       if (!dhd->waive_wakelock) {
 #ifdef CONFIG_HAS_WAKELOCK
-                       wake_unlock(&dhd->wl_wdwake);
+                               wake_unlock(&dhd->wl_wdwake);
 #endif
+                       }
                }
                spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
        }
@@ -16393,15 +16837,13 @@ int dhd_deepsleep(struct net_device *dev, int flag)
 #endif /* PKT_FILTER_SUPPORT */
                        /* Disable MPC */
                        powervar = 0;
-                       memset(iovbuf, 0, sizeof(iovbuf));
-                       bcm_mkiovar("mpc", (char *)&powervar, 4, iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                       dhd_iovar(dhdp, 0, "mpc", (char *)&powervar, sizeof(powervar), NULL, 0,
+                                       TRUE);
 
                        /* Enable Deepsleep */
                        powervar = 1;
-                       memset(iovbuf, 0, sizeof(iovbuf));
-                       bcm_mkiovar("deepsleep", (char *)&powervar, 4, iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                       dhd_iovar(dhdp, 0, "deepsleep", (char *)&powervar, sizeof(powervar), NULL,
+                                       0, TRUE);
                        break;
 
                case 0: /* Deepsleep Off */
@@ -16410,18 +16852,12 @@ int dhd_deepsleep(struct net_device *dev, int flag)
                        /* Disable Deepsleep */
                        for (cnt = 0; cnt < MAX_TRY_CNT; cnt++) {
                                powervar = 0;
-                               memset(iovbuf, 0, sizeof(iovbuf));
-                               bcm_mkiovar("deepsleep", (char *)&powervar, 4,
-                                       iovbuf, sizeof(iovbuf));
-                               dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf,
-                                       sizeof(iovbuf), TRUE, 0);
-
-
-                               memset(iovbuf, 0, sizeof(iovbuf));
-                               bcm_mkiovar("deepsleep", (char *)&powervar, 4,
-                                       iovbuf, sizeof(iovbuf));
-                               if ((ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, iovbuf,
-                                       sizeof(iovbuf), FALSE, 0)) < 0) {
+                               dhd_iovar(dhdp, 0, "deepsleep", (char *)&powervar, sizeof(powervar),
+                                               NULL, 0, TRUE);
+
+                               ret = dhd_iovar(dhdp, 0, "deepsleep", (char *)&powervar,
+                                               sizeof(powervar), iovbuf, sizeof(iovbuf), FALSE);
+                               if (ret < 0) {
                                        DHD_ERROR(("the error of dhd deepsleep status"
                                                " ret value :%d\n", ret));
                                } else {
@@ -16435,9 +16871,8 @@ int dhd_deepsleep(struct net_device *dev, int flag)
 
                        /* Enable MPC */
                        powervar = 1;
-                       memset(iovbuf, 0, sizeof(iovbuf));
-                       bcm_mkiovar("mpc", (char *)&powervar, 4, iovbuf, sizeof(iovbuf));
-                       dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+                       dhd_iovar(dhdp, 0, "mpc", (char *)&powervar, sizeof(powervar), NULL, 0,
+                                       TRUE);
                        break;
        }
 
@@ -16737,12 +17172,17 @@ int dhd_set_ap_isolate(dhd_pub_t *dhdp, uint32 idx, int val)
 }
 
 #ifdef DHD_FW_COREDUMP
+#if defined(CONFIG_X86)
+#define MEMDUMPINFO_LIVE "/installmedia/.memdump.info"
+#define MEMDUMPINFO_INST "/data/.memdump.info"
+#endif /* CONFIG_X86 && OEM_ANDROID */
+
 #ifdef CUSTOMER_HW4_DEBUG
 #define MEMDUMPINFO PLATFORM_PATH".memdump.info"
 #elif (defined(BOARD_PANDA) || defined(__ARM_ARCH_7A__))
 #define MEMDUMPINFO "/data/misc/wifi/.memdump.info"
 #else
-#define MEMDUMPINFO "/installmedia/.memdump.info"
+#define MEMDUMPINFO MEMDUMPINFO_LIVE
 #endif /* CUSTOMER_HW4_DEBUG */
 
 void dhd_get_memdump_info(dhd_pub_t *dhd)
@@ -16756,20 +17196,36 @@ void dhd_get_memdump_info(dhd_pub_t *dhd)
        fp = filp_open(filepath, O_RDONLY, 0);
        if (IS_ERR(fp)) {
                DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
-               goto done;
-       } else {
-               ret = kernel_read(fp, 0, (char *)&mem_val, 4);
-               if (ret < 0) {
-                       DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret));
-                       filp_close(fp, NULL);
+#if defined(CONFIG_X86)
+               /* Check if it is Live Brix Image */
+               if (strcmp(filepath, MEMDUMPINFO_LIVE) != 0) {
                        goto done;
                }
+               /* Try if it is Installed Brix Image */
+               filepath = MEMDUMPINFO_INST;
+               DHD_ERROR(("%s: Try File [%s]\n", __FUNCTION__, filepath));
+               fp = filp_open(filepath, O_RDONLY, 0);
+               if (IS_ERR(fp)) {
+                       DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
+                       goto done;
+               }
+#else /* Non Brix Android platform */
+               goto done;
+#endif /* CONFIG_X86 && OEM_ANDROID */
+       }
 
-               mem_val = bcm_atoi((char *)&mem_val);
-
+       /* Handle success case */
+       ret = kernel_read(fp, 0, (char *)&mem_val, 4);
+       if (ret < 0) {
+               DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret));
                filp_close(fp, NULL);
+               goto done;
        }
 
+       mem_val = bcm_atoi((char *)&mem_val);
+
+       filp_close(fp, NULL);
+
 #ifdef DHD_INIT_DEFAULT_MEMDUMP
        if (mem_val == 0 || mem_val == DUMP_MEMFILE_MAX)
                mem_val = DUMP_MEMFILE_BUGON;
@@ -16812,6 +17268,12 @@ void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size)
                dhd_schedule_log_dump(dhdp);
        }
 #endif /* DHD_LOG_DUMP */
+#ifdef DEBUG_DNGL_INIT_FAIL
+       if (dhdp->memdump_type == DUMP_TYPE_DONGLE_INIT_FAILURE) {
+               dhd_mem_dump((void *)dhdp->info, (void *)dump, 0);
+               return;
+       }
+#endif /* DEBUG_DNGL_INIT_FAIL */
        dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, (void *)dump,
                DHD_WQ_WORK_SOC_RAM_DUMP, dhd_mem_dump, DHD_WQ_WORK_PRIORITY_HIGH);
 }
@@ -16985,7 +17447,7 @@ do_dhd_log_dump(dhd_pub_t *dhdp)
        memset(dump_path, 0, sizeof(dump_path));
        do_gettimeofday(&curtime);
        snprintf(dump_path, sizeof(dump_path), "%s_%ld.%ld",
-               DHD_COMMON_DUMP_PATH "debug_dump",
+               DHD_COMMON_DUMP_PATH DHD_DEBUG_DUMP_TYPE,
                (unsigned long)curtime.tv_sec, (unsigned long)curtime.tv_usec);
        file_mode = O_CREAT | O_WRONLY | O_SYNC;
 
@@ -17044,11 +17506,23 @@ do_dhd_log_dump(dhd_pub_t *dhdp)
        } while (1);
 
 exit:
+#if defined(STAT_REPORT)
+       if (!IS_ERR(fp) && ret >= 0) {
+               wl_stat_report_file_save(dhdp, fp);
+       }
+#endif /* STAT_REPORT */
+
        if (!IS_ERR(fp)) {
                filp_close(fp, NULL);
        }
        set_fs(old_fs);
 
+#ifdef DHD_DUMP_MNGR
+       if (ret >= 0) {
+               dhd_dump_file_manage_enqueue(dhdp, dump_path, DHD_DEBUG_DUMP_TYPE);
+       }
+#endif /* DHD_DUMP_MNGR */
+
        return ret;
 }
 #endif /* DHD_LOG_DUMP */
@@ -17517,7 +17991,141 @@ void custom_rps_map_clear(struct netdev_rx_queue *queue)
 }
 #endif /* SET_RPS_CPUS || ARGOS_RPS_CPU_CTL */
 
-#if defined(ARGOS_CPU_SCHEDULER) && defined(ARGOS_RPS_CPU_CTL)
+#if defined(ARGOS_CPU_SCHEDULER)
+#ifdef DYNAMIC_MUMIMO_CONTROL
+#define MUMIMO_CONTROL_TIMER_INTERVAL_MS       5000
+
+void
+argos_config_mumimo_timer(unsigned long data)
+{
+       argos_mumimo_ctrl *ctrl_data = (argos_mumimo_ctrl *)data;
+
+       DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+       schedule_work(&ctrl_data->mumimo_ctrl_work);
+}
+
+void
+argos_config_mumimo_handler(struct work_struct *work)
+{
+       argos_mumimo_ctrl *ctrl_data;
+       struct net_device *dev;
+       int err;
+       int new_cap;
+
+       ctrl_data = container_of(work, argos_mumimo_ctrl, mumimo_ctrl_work);
+
+       dev = ctrl_data->dev;
+
+       if (!dev) {
+               return;
+       }
+
+       new_cap = ctrl_data->cur_murx_bfe_cap;
+       err = wl_set_murx_bfe_cap(dev, new_cap, TRUE);
+       if (err) {
+               DHD_ERROR(("%s: Failed to set murx_bfe_cap to %d, err=%d\n",
+                       __FUNCTION__, new_cap, err));
+       } else {
+               DHD_ERROR(("%s: Newly configured murx_bfe_cap = %d\n",
+                       __FUNCTION__, new_cap));
+       }
+}
+
+void
+argos_status_notifier_config_mumimo(struct notifier_block *notifier,
+       unsigned long speed, void *v)
+{
+       struct net_device *dev;
+       int prev_murx_bfe_cap;
+       int cap;
+       dhd_info_t *dhd;
+
+       dev = argos_mumimo_ctrl_data.dev;
+       if (!dev) {
+               return;
+       }
+
+       dhd = DHD_DEV_INFO(dev);
+       if (!dhd) {
+               return;
+       }
+
+       /* Check if STA reassociate with the AP after murx configuration */
+       if (dhd->pub.reassoc_mumimo_sw) {
+               /* Cancel the MU-MIMO control timer */
+               if (timer_pending(&argos_mumimo_ctrl_data.config_timer)) {
+                       del_timer_sync(&argos_mumimo_ctrl_data.config_timer);
+               }
+
+               DHD_ERROR(("%s: Reassociation is in progress...\n", __FUNCTION__));
+               return;
+       }
+
+       /* Check if current associated AP supports MU-MIMO capability
+        * or current Tput meets the condition for MU-MIMO configuration
+        */
+       if ((wl_check_bss_support_mumimo(dev) <= 0) ||
+               ((speed < MUMIMO_TO_SUMIMO_TPUT_THRESHOLD) &&
+               (speed >= SUMIMO_TO_MUMIMO_TPUT_THRESHOLD))) {
+               return;
+       }
+
+       prev_murx_bfe_cap = argos_mumimo_ctrl_data.cur_murx_bfe_cap;
+
+       /* Check the TPut condition */
+       if (speed >= MUMIMO_TO_SUMIMO_TPUT_THRESHOLD) {
+               cap = 0;
+       } else {
+               cap = 1;
+       }
+
+       if (prev_murx_bfe_cap != cap) {
+               /* Cancel the MU-MIMO control timer */
+               if (timer_pending(&argos_mumimo_ctrl_data.config_timer)) {
+                       del_timer_sync(&argos_mumimo_ctrl_data.config_timer);
+               }
+
+               /* Update the new value */
+               argos_mumimo_ctrl_data.cur_murx_bfe_cap = cap;
+
+               /* Arm the MU-MIMO control timer */
+               mod_timer(&argos_mumimo_ctrl_data.config_timer,
+                       jiffies + msecs_to_jiffies(MUMIMO_CONTROL_TIMER_INTERVAL_MS));
+
+               DHD_ERROR(("%s: Arm the MU-MIMO control timer, cur_murx_bfe_cap=%d\n",
+                       __FUNCTION__, cap));
+       }
+}
+
+void
+argos_config_mumimo_init(struct net_device *dev)
+{
+       init_timer(&argos_mumimo_ctrl_data.config_timer);
+       argos_mumimo_ctrl_data.config_timer.data = (unsigned long)&argos_mumimo_ctrl_data;
+       argos_mumimo_ctrl_data.config_timer.function = argos_config_mumimo_timer;
+       argos_mumimo_ctrl_data.dev = dev;
+       INIT_WORK(&argos_mumimo_ctrl_data.mumimo_ctrl_work, argos_config_mumimo_handler);
+       argos_mumimo_ctrl_data.cur_murx_bfe_cap = -1;
+}
+
+void
+argos_config_mumimo_deinit(void)
+{
+       argos_mumimo_ctrl_data.dev = NULL;
+       if (timer_pending(&argos_mumimo_ctrl_data.config_timer)) {
+               del_timer_sync(&argos_mumimo_ctrl_data.config_timer);
+       }
+
+       cancel_work_sync(&argos_mumimo_ctrl_data.mumimo_ctrl_work);
+}
+
+void
+argos_config_mumimo_reset(void)
+{
+       argos_mumimo_ctrl_data.cur_murx_bfe_cap = -1;
+}
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+
 int
 argos_register_notifier_init(struct net_device *net)
 {
@@ -17526,6 +18134,9 @@ argos_register_notifier_init(struct net_device *net)
        DHD_INFO(("DHD: %s: \n", __FUNCTION__));
        argos_rps_ctrl_data.wlan_primary_netdev = net;
        argos_rps_ctrl_data.argos_rps_cpus_enabled = 0;
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       argos_config_mumimo_init(net);
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 
        if (argos_wifi.notifier_call == NULL) {
                argos_wifi.notifier_call = argos_status_notifier_wifi_cb;
@@ -17536,12 +18147,27 @@ argos_register_notifier_init(struct net_device *net)
                }
        }
 
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+       if (argos_mimo.notifier_call == NULL) {
+               argos_mimo.notifier_call = argos_status_notifier_config_mumimo_cb;
+               ret = sec_argos_register_notifier(&argos_mimo, ARGOS_WIFI_TABLE_FOR_MIMO_LABEL);
+               if (ret < 0) {
+                       DHD_ERROR(("DHD:Failed to register WIFI for MIMO notifier, ret=%d\n", ret));
+                       sec_argos_unregister_notifier(&argos_wifi, ARGOS_WIFI_TABLE_LABEL);
+                       goto exit;
+               }
+       }
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
+
        if (argos_p2p.notifier_call == NULL) {
                argos_p2p.notifier_call = argos_status_notifier_p2p_cb;
                ret = sec_argos_register_notifier(&argos_p2p, ARGOS_P2P_TABLE_LABEL);
                if (ret < 0) {
                        DHD_ERROR(("DHD:Failed to register P2P notifier, ret=%d\n", ret));
                        sec_argos_unregister_notifier(&argos_wifi, ARGOS_WIFI_TABLE_LABEL);
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+                       sec_argos_unregister_notifier(&argos_mimo, ARGOS_WIFI_TABLE_FOR_MIMO_LABEL);
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
                        goto exit;
                }
        }
@@ -17553,6 +18179,12 @@ exit:
                argos_wifi.notifier_call = NULL;
        }
 
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+       if (argos_mimo.notifier_call) {
+               argos_mimo.notifier_call = NULL;
+       }
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
+
        if (argos_p2p.notifier_call) {
                argos_p2p.notifier_call = NULL;
        }
@@ -17569,15 +18201,27 @@ argos_register_notifier_deinit(void)
                DHD_ERROR(("DHD: primary_net_dev is null %s: \n", __FUNCTION__));
                return -1;
        }
-#ifndef DHD_LB
+
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       argos_config_mumimo_deinit();
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+
+#if !defined(DHD_LB) && defined(ARGOS_RPS_CPU_CTL)
        custom_rps_map_clear(argos_rps_ctrl_data.wlan_primary_netdev->_rx);
-#endif /* !DHD_LB */
+#endif /* !DHD_LB && ARGOS_RPS_CPU_CTL */
 
        if (argos_p2p.notifier_call) {
                sec_argos_unregister_notifier(&argos_p2p, ARGOS_P2P_TABLE_LABEL);
                argos_p2p.notifier_call = NULL;
        }
 
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+       if (argos_mimo.notifier_call) {
+               sec_argos_unregister_notifier(&argos_mimo, ARGOS_WIFI_TABLE_FOR_MIMO_LABEL);
+               argos_mimo.notifier_call = NULL;
+       }
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
+
        if (argos_wifi.notifier_call) {
                sec_argos_unregister_notifier(&argos_wifi, ARGOS_WIFI_TABLE_LABEL);
                argos_wifi.notifier_call = NULL;
@@ -17590,7 +18234,7 @@ argos_register_notifier_deinit(void)
 }
 
 int
-argos_status_notifier_wifi_cb(struct notifier_block *notifier,
+argos_status_notifier_cb(struct notifier_block *notifier,
        unsigned long speed, void *v)
 {
        dhd_info_t *dhd;
@@ -17618,7 +18262,7 @@ argos_status_notifier_wifi_cb(struct notifier_block *notifier,
                        /* It does not need to configre rps_cpus
                         * if Load Balance is enabled
                         */
-#ifndef DHD_LB
+#if !defined(DHD_LB) && defined(ARGOS_RPS_CPU_CTL)
                        int err = 0;
 
                        if (cpu_online(RPS_CPUS_WLAN_CORE_ID)) {
@@ -17637,38 +18281,38 @@ argos_status_notifier_wifi_cb(struct notifier_block *notifier,
                                        "speed=%ld, error=%d\n",
                                        __FUNCTION__, speed, err));
                        } else {
-#endif /* !DHD_LB */
-#if (defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE))
-                               DHD_TRACE(("%s : set ack suppress. TCPACK_SUP_HOLD\n",
-                                       __FUNCTION__));
-                               if (dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD) {
-                                       dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_HOLD);
+#endif /* !DHD_LB && ARGOS_RPS_CPU_CTL */
+#ifdef DHDTCPACK_SUPPRESS
+                               if (dhdp->tcpack_sup_mode != TCPACK_SUP_ON) {
+                                       DHD_ERROR(("%s : set ack suppress. TCPACK_SUP_ON(%d)\n",
+                                               __FUNCTION__, TCPACK_SUP_ON));
+                                       dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_ON);
                                }
-#endif /* DHDTCPACK_SUPPRESS && BCMPCIE */
+#endif /* DHDTCPACK_SUPPRESS */
                                argos_rps_ctrl_data.argos_rps_cpus_enabled = 1;
-#ifndef DHD_LB
+#if !defined(DHD_LB) && defined(ARGOS_RPS_CPU_CTL)
                                DHD_ERROR(("DHD: %s: Set RPS_CPUs, speed=%ld\n",
                                        __FUNCTION__, speed));
                        }
-#endif /* !DHD_LB */
+#endif /* !DHD_LB && ARGOS_RPS_CPU_CTL */
                }
        } else {
                if (argos_rps_ctrl_data.argos_rps_cpus_enabled == 1) {
-#if (defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE))
-                       DHD_TRACE(("%s : set ack suppress. TCPACK_SUP_OFF\n",
-                               __FUNCTION__));
+#ifdef DHDTCPACK_SUPPRESS
                        if (dhdp->tcpack_sup_mode != TCPACK_SUP_OFF) {
+                               DHD_ERROR(("%s : set ack suppress. TCPACK_SUP_OFF\n",
+                                       __FUNCTION__));
                                dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF);
                        }
-#endif /* DHDTCPACK_SUPPRESS && BCMPCIE */
-#ifndef DHD_LB
+#endif /* DHDTCPACK_SUPPRESS */
+#if !defined(DHD_LB) && defined(ARGOS_RPS_CPU_CTL)
                        /* It does not need to configre rps_cpus
                         * if Load Balance is enabled
                         */
                        custom_rps_map_clear(argos_rps_ctrl_data.wlan_primary_netdev->_rx);
                        DHD_ERROR(("DHD: %s: Clear RPS_CPUs, speed=%ld\n", __FUNCTION__, speed));
                        OSL_SLEEP(DELAY_TO_CLEAR_RPS_CPUS);
-#endif /* !DHD_LB */
+#endif /* !DHD_LB && ARGOS_RPS_CPU_CTL */
                        argos_rps_ctrl_data.argos_rps_cpus_enabled = 0;
                }
        }
@@ -17677,14 +18321,41 @@ exit:
        return NOTIFY_OK;
 }
 
+int
+argos_status_notifier_wifi_cb(struct notifier_block *notifier,
+       unsigned long speed, void *v)
+{
+       DHD_INFO(("DHD: %s: speed=%ld\n", __FUNCTION__, speed));
+       argos_status_notifier_cb(notifier, speed, v);
+#if !defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+       argos_status_notifier_config_mumimo(notifier, speed, v);
+#endif /* !CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
+
+       return NOTIFY_OK;
+}
+
+#if defined(CONFIG_SPLIT_ARGOS_SET) && defined(DYNAMIC_MUMIMO_CONTROL)
+int
+argos_status_notifier_config_mumimo_cb(struct notifier_block *notifier,
+       unsigned long speed, void *v)
+{
+       DHD_INFO(("DHD: %s: speed=%ld\n", __FUNCTION__, speed));
+       argos_status_notifier_config_mumimo(notifier, speed, v);
+
+       return NOTIFY_OK;
+}
+#endif /* CONFIG_SPLIT_ARGOS_SET && DYNAMIC_MUMIMO_CONTROL */
+
 int
 argos_status_notifier_p2p_cb(struct notifier_block *notifier,
        unsigned long speed, void *v)
 {
        DHD_INFO(("DHD: %s: speed=%ld\n", __FUNCTION__, speed));
-       return argos_status_notifier_wifi_cb(notifier, speed, v);
+       argos_status_notifier_cb(notifier, speed, v);
+
+       return NOTIFY_OK;
 }
-#endif /* ARGOS_CPU_SCHEDULER && ARGOS_RPS_CPU_CTL */
+#endif /* ARGOS_CPU_SCHEDULER */
 
 
 #ifdef DHD_DEBUG_PAGEALLOC
@@ -17814,13 +18485,13 @@ dhd_icmp_dump(char *ifname, uint8 *pktdata, bool tx)
 
        icmph = (struct icmphdr *)((uint8 *)pkt + sizeof(struct iphdr));
        if (icmph->type == ICMP_ECHO) {
-               DHD_ERROR(("PING REQUEST[%s] [%s] : SEQNUM=%d\n",
+               DHD_ERROR_MEM(("PING REQUEST[%s] [%s] : SEQNUM=%d\n",
                        ifname, tx ? "TX" : "RX", ntoh16(icmph->un.echo.sequence)));
        } else if (icmph->type == ICMP_ECHOREPLY) {
-               DHD_ERROR(("PING REPLY[%s] [%s] : SEQNUM=%d\n",
+               DHD_ERROR_MEM(("PING REPLY[%s] [%s] : SEQNUM=%d\n",
                        ifname, tx ? "TX" : "RX", ntoh16(icmph->un.echo.sequence)));
        } else {
-               DHD_ERROR(("ICMP [%s] [%s] : TYPE=%d, CODE=%d\n",
+               DHD_ERROR_MEM(("ICMP [%s] [%s] : TYPE=%d, CODE=%d\n",
                        ifname, tx ? "TX" : "RX", icmph->type, icmph->code));
        }
 }
@@ -18571,7 +19242,7 @@ void
 dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
 {
        struct file *fp;
-       char *filepath = CONFIG_BCMDHD_CLM_PATH;
+       char *filepath = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH;
 
        fp = filp_open(filepath, O_RDONLY, 0);
        if (IS_ERR(fp)) {
@@ -18766,3 +19437,196 @@ dhd_make_hang_with_reason(struct net_device *dev, const char *string_num)
        }
 }
 #endif /* DHD_HANG_SEND_UP_TEST */
+#ifdef DHD_WAKE_STATUS
+wake_counts_t*
+dhd_get_wakecount(dhd_pub_t *dhdp)
+{
+       return dhd_bus_get_wakecount(dhdp);
+}
+#endif /* DHD_WAKE_STATUS */
+
+#ifdef BCM_ASLR_HEAP
+uint32
+dhd_get_random_number(void)
+{
+       uint32 rand = 0;
+       get_random_bytes_arch(&rand, sizeof(rand));
+       return rand;
+}
+#endif /* BCM_ASLR_HEAP */
+
+#ifdef DHD_PKT_LOGGING
+void
+dhd_pktlog_dump(void *handle, void *event_info, u8 event)
+{
+       dhd_info_t *dhd = handle;
+
+       if (!dhd) {
+               DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+               return;
+       }
+
+       if (dhd_pktlog_write_file(&dhd->pub)) {
+               DHD_ERROR(("%s: writing pktlog dump to the file failed\n", __FUNCTION__));
+               return;
+       }
+}
+
+void
+dhd_schedule_pktlog_dump(dhd_pub_t *dhdp)
+{
+       dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq,
+                       (void*)NULL, DHD_WQ_WORK_PKTLOG_DUMP,
+                       dhd_pktlog_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+}
+#endif /* DHD_PKT_LOGGING */
+
+#ifdef DHD_DUMP_MNGR
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
+#define DHD_VFS_INODE(dir) (dir->d_inode)
+#else
+#define DHD_VFS_INODE(dir) d_inode(dir)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
+#define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b)
+#else
+#define DHD_VFS_UNLINK(dir, b, c) vfs_unlink(DHD_VFS_INODE(dir), b, c)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
+
+static int
+dhd_file_delete(char *path)
+{
+       struct path file_path;
+       int err;
+       struct dentry *dir;
+
+       err = kern_path(path, 0, &file_path);
+
+       if (err < 0) {
+               return err;
+       }
+       if (FALSE ||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+                       !d_is_file(file_path.dentry) ||
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(4, 0, 0))
+                       d_really_is_negative(file_path.dentry)
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(4, 0, 0) */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
+)
+       {
+               err = -EINVAL;
+       } else {
+               dir = dget_parent(file_path.dentry);
+
+               if (!IS_ERR(dir)) {
+                       err = DHD_VFS_UNLINK(dir, file_path.dentry, NULL);
+                       dput(dir);
+               } else {
+                       err = PTR_ERR(dir);
+               }
+       }
+
+       path_put(&file_path);
+
+       if (err < 0) {
+               DHD_ERROR(("Failed to delete file: %s error: %d\n", path, err));
+       }
+
+       return err;
+}
+
+static int
+dhd_dump_file_manage_idx(dhd_dump_file_manage_t *fm_ptr, char *fname)
+{
+       int i;
+       int fm_idx = -1;
+
+       for (i = 0; i < DHD_DUMP_TYPE_COUNT_MAX; i++) {
+               if (strlen(fm_ptr->elems[i].type_name) == 0) {
+                       fm_idx = i;
+                       break;
+               }
+               if (!(strncmp(fname, fm_ptr->elems[i].type_name, strlen(fname)))) {
+                       fm_idx = i;
+                       break;
+               }
+       }
+
+       if (fm_idx == -1) {
+               return fm_idx;
+       }
+
+       if (strlen(fm_ptr->elems[fm_idx].type_name) == 0) {
+               strncpy(fm_ptr->elems[fm_idx].type_name, fname, DHD_DUMP_TYPE_NAME_SIZE);
+               fm_ptr->elems[fm_idx].file_idx = 0;
+       }
+
+       return fm_idx;
+}
+
+/*
+ * dhd_dump_file_manage_enqueue - enqueue dump file path
+ * and delete odest file if file count is max.
+ */
+void
+dhd_dump_file_manage_enqueue(dhd_pub_t *dhd, char *dump_path, char *fname)
+{
+       int fm_idx;
+       int fp_idx;
+       dhd_dump_file_manage_t *fm_ptr;
+       DFM_elem_t *elem;
+
+       if (!dhd || !dhd->dump_file_manage) {
+               DHD_ERROR(("%s(): dhdp=%p dump_file_manage=%p\n",
+                       __FUNCTION__, dhd, (dhd ? dhd->dump_file_manage : NULL)));
+               return;
+       }
+
+       fm_ptr = dhd->dump_file_manage;
+
+       /* find file_manage idx */
+       DHD_INFO(("%s(): fname: %s dump_path: %s\n", __FUNCTION__, fname, dump_path));
+       if ((fm_idx = dhd_dump_file_manage_idx(fm_ptr, fname)) < 0) {
+               DHD_ERROR(("%s(): Out of file manager entries, fname: %s\n",
+                       __FUNCTION__, fname));
+               return;
+       }
+
+       elem = &fm_ptr->elems[fm_idx];
+       fp_idx = elem->file_idx;
+       DHD_INFO(("%s(): fm_idx: %d fp_idx: %d path: %s\n",
+               __FUNCTION__, fm_idx, fp_idx, elem->file_path[fp_idx]));
+
+       /* delete oldest file */
+       if (strlen(elem->file_path[fp_idx]) != 0) {
+               if (dhd_file_delete(elem->file_path[fp_idx]) < 0) {
+                       DHD_ERROR(("%s(): Failed to delete file: %s\n",
+                               __FUNCTION__, elem->file_path[fp_idx]));
+               } else {
+                       DHD_ERROR(("%s(): Successed to delete file: %s\n",
+                               __FUNCTION__, elem->file_path[fp_idx]));
+               }
+       }
+
+       /* save dump file path */
+       strncpy(elem->file_path[fp_idx], dump_path, DHD_DUMP_FILE_PATH_SIZE);
+
+       /* change file index to next file index */
+       elem->file_idx = (elem->file_idx + 1) % DHD_DUMP_FILE_COUNT_MAX;
+}
+#endif /* DHD_DUMP_MNGR */
+
+#if defined(BCMSDIO) || defined(BCMPCIE)
+uint
+dhd_get_chip_id(dhd_pub_t *dhdp)
+{
+       return dhd_bus_chip_id(dhdp);
+}
+
+uint
+dhd_get_chiprev_id(dhd_pub_t *dhdp)
+{
+       return dhd_bus_chiprev_id(dhdp);
+}
+#endif /* BCMSDIO || BCMPCIE */
index e3deafc0a9a35ceb32f6999e75f9182b10e19889..18774a14fb38c5312cb4366ec3949b1bafbb93d8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DHD Linux header file (dhd_linux exports for cfg80211 and other components)
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_linux.h 675385 2016-12-15 13:37:08Z $
+ * $Id: dhd_linux.h 733907 2017-11-30 12:20:38Z $
  */
 
 /* wifi platform functions for power, interrupt and pre-alloc, either
@@ -131,7 +131,7 @@ extern void dhd_free_module_memory(struct dhd_bus *bus, struct module_metadata *
 extern void* dhd_alloc_module_memory(struct dhd_bus *bus, uint32_t size,
        struct module_metadata *hmem);
 #endif /* HOFFLOAD_MODULES */
-#ifdef WLADPS
+#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD)
 #define ADPS_ENABLE    1
 #define ADPS_DISABLE   0
 typedef struct bcm_iov_buf {
@@ -142,5 +142,8 @@ typedef struct bcm_iov_buf {
 } bcm_iov_buf_t;
 
 int dhd_enable_adps(dhd_pub_t *dhd, uint8 on);
-#endif
+#endif /* WLADPS || WLADPS_PRIVATE_CMD */
+#ifdef DHD_DISABLE_VHTMODE
+void dhd_disable_vhtmode(dhd_pub_t *dhd);
+#endif /* DHD_DISABLE_VHTMODE */
 #endif /* __DHD_LINUX_H__ */
index f20bec0f56b8fc5d7242785adeb2ffe0c8899042..09ce269666ba275ef62bdc88591594179ee01280 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux platform device for DHD WLAN adapter
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 88c0cce635bd92d36b242524497733616dbc42df..63ed939995c2a43630c120ee1a5f8fcf83cb4170 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Expose some of the kernel scheduler routines
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 1cba8d1400c43739f840c05927eeca16d101e05f..cc351b2c297a685bf751b2aa6269fdd0d3faeaa0 100644 (file)
@@ -2,7 +2,7 @@
  * Broadcom Dongle Host Driver (DHD), Generic work queue framework
  * Generic interface to handle dhd deferred work events
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 0429ccc74cca13741ca8032eb3303f3321501e3e..f6996610cd90f256add7f9e30bea718e6d7811a1 100644 (file)
@@ -2,7 +2,7 @@
  * Broadcom Dongle Host Driver (DHD), Generic work queue framework
  * Generic interface to handle dhd deferred work events
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -25,7 +25,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_linux_wq.h 662453 2016-09-29 13:09:25Z $
+ * $Id: dhd_linux_wq.h 704361 2017-06-13 08:50:38Z $
  */
 #ifndef _dhd_linux_wq_h_
 #define _dhd_linux_wq_h_
@@ -46,6 +46,7 @@ enum _wq_event {
        DHD_WQ_WORK_DMA_LB_MEM_REL,
        DHD_WQ_WORK_DEBUG_UART_DUMP,
        DHD_WQ_WORK_SSSR_DUMP,
+       DHD_WQ_WORK_PKTLOG_DUMP,
        DHD_MAX_WQ_EVENTS
 };
 
index c1032f20376630548bdb9aea7db5a3e4162f56d0..7325967c2381499621c6f2f22bd9a49899b0c3e7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 749e1119f42175fdf9633f3485249d0104a43e14..e49e78a5f68c5e770c869aa707564cf21f97c40e 100644 (file)
@@ -3,7 +3,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index f5682d4728f457a9dea21b7e0ff2f7962ec725e8..1bbf166377bb2cc17ba320451d92058ad54dba38 100644 (file)
@@ -3,7 +3,7 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -26,7 +26,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_msgbuf.c 685101 2017-02-15 11:02:19Z $
+ * $Id: dhd_msgbuf.c 733632 2017-11-29 08:46:58Z $
  */
 
 
 #include <hnd_debug.h>
 #include <hnd_armtrap.h>
 
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+
 extern char dhd_version[];
 extern char fw_version[];
 
@@ -291,6 +295,7 @@ typedef struct dhd_dmaxfer {
        bool          in_progress;
        uint64        start_usec;
        uint32        d11_lpbk;
+       int           status;
 } dhd_dmaxfer_t;
 
 /**
@@ -643,6 +648,8 @@ static void BCMFASTPATH dhd_rxchain_commit(dhd_pub_t *dhd);
 
 #endif /* DHD_RX_CHAINING */
 
+#define DHD_LPBKDTDUMP_ON()    (dhd_msg_level & DHD_LPBKDTDUMP_VAL)
+
 static void dhd_prot_h2d_sync_init(dhd_pub_t *dhd);
 
 /**
@@ -2794,6 +2801,16 @@ dhd_prot_reset(dhd_pub_t *dhd)
 #ifdef IOCTLRESP_USE_CONSTMEM
        DHD_NATIVE_TO_PKTID_RESET_IOCTL(dhd, prot->pktid_map_handle_ioctl);
 #endif /* IOCTLRESP_USE_CONSTMEM */
+#ifdef DMAMAP_STATS
+       dhd->dma_stats.txdata = dhd->dma_stats.txdata_sz = 0;
+       dhd->dma_stats.rxdata = dhd->dma_stats.rxdata_sz = 0;
+#ifndef IOCTLRESP_USE_CONSTMEM
+       dhd->dma_stats.ioctl_rx = dhd->dma_stats.ioctl_rx_sz = 0;
+#endif /* IOCTLRESP_USE_CONSTMEM */
+       dhd->dma_stats.event_rx = dhd->dma_stats.event_rx_sz = 0;
+       dhd->dma_stats.info_rx = dhd->dma_stats.info_rx_sz = 0;
+       dhd->dma_stats.tsbuf_rx = dhd->dma_stats.tsbuf_rx_sz = 0;
+#endif /* DMAMAP_STATS */
 } /* dhd_prot_reset */
 
 #if defined(DHD_LB_RXP)
@@ -3252,6 +3269,28 @@ dhd_prot_packet_get(dhd_pub_t *dhd, uint32 pktid, uint8 pkttype, bool free_pktid
                                        secdma, 0);
                        else
                                DMA_UNMAP(dhd->osh, pa, (uint) len, DMA_RX, 0, dmah);
+#ifdef DMAMAP_STATS
+                       switch (pkttype) {
+#ifndef IOCTLRESP_USE_CONSTMEM
+                               case PKTTYPE_IOCTL_RX:
+                                       dhd->dma_stats.ioctl_rx--;
+                                       dhd->dma_stats.ioctl_rx_sz -= len;
+                                       break;
+#endif /* IOCTLRESP_USE_CONSTMEM */
+                               case PKTTYPE_EVENT_RX:
+                                       dhd->dma_stats.event_rx--;
+                                       dhd->dma_stats.event_rx_sz -= len;
+                                       break;
+                               case PKTTYPE_INFO_RX:
+                                       dhd->dma_stats.info_rx--;
+                                       dhd->dma_stats.info_rx_sz -= len;
+                                       break;
+                               case PKTTYPE_TSBUF_RX:
+                                       dhd->dma_stats.tsbuf_rx--;
+                                       dhd->dma_stats.tsbuf_rx_sz -= len;
+                                       break;
+                       }
+#endif /* DMAMAP_STATS */
                }
        }
 
@@ -3406,6 +3445,10 @@ dhd_prot_rxbuf_post(dhd_pub_t *dhd, uint16 count, bool use_rsv_pktid)
                        ASSERT(0);
                        break;
                }
+#ifdef DMAMAP_STATS
+               dhd->dma_stats.rxdata++;
+               dhd->dma_stats.rxdata_sz += pktlen[i];
+#endif /* DMAMAP_STATS */
 
                PKTPULL(dhd->osh, p, prot->rx_metadata_offset);
                pktlen[i] = PKTLEN(dhd->osh, p);
@@ -3645,7 +3688,10 @@ dhd_prot_infobufpost(dhd_pub_t *dhd)
                        ASSERT(0);
                        break;
                }
-
+#ifdef DMAMAP_STATS
+               dhd->dma_stats.info_rx++;
+               dhd->dma_stats.info_rx_sz += pktlen;
+#endif /* DMAMAP_STATS */
                pktlen = PKTLEN(dhd->osh, p);
 
                /* Common msg header */
@@ -3860,6 +3906,27 @@ dhd_prot_rxbufpost_ctrl(dhd_pub_t *dhd, uint8 msg_type)
                        goto free_pkt_return;
                }
 
+#ifdef DMAMAP_STATS
+               switch (buf_type) {
+#ifndef IOCTLRESP_USE_CONSTMEM
+                       case PKTTYPE_IOCTL_RX:
+                               dhd->dma_stats.ioctl_rx++;
+                               dhd->dma_stats.ioctl_rx_sz += pktlen;
+                               break;
+#endif /* !IOCTLRESP_USE_CONSTMEM */
+                       case PKTTYPE_EVENT_RX:
+                               dhd->dma_stats.event_rx++;
+                               dhd->dma_stats.event_rx_sz += pktlen;
+                               break;
+                       case PKTTYPE_TSBUF_RX:
+                               dhd->dma_stats.tsbuf_rx++;
+                               dhd->dma_stats.tsbuf_rx_sz += pktlen;
+                               break;
+                       default:
+                               break;
+               }
+#endif /* DMAMAP_STATS */
+
        }
 #ifdef PCIE_INB_DW
        if (dhd_prot_inc_hostactive_devwake_assert(dhd->bus) != BCME_OK)
@@ -4154,10 +4221,6 @@ dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd, uint bound)
        int i;
        uint8 sync;
 
-#ifdef DHD_WAKE_STATUS
-       int pkt_wake = bcmpcie_set_get_wake(dhd->bus, 0);
-#endif
-
        while (1) {
                if (dhd_is_device_removed(dhd))
                        break;
@@ -4222,6 +4285,10 @@ dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd, uint bound)
                        else
                                DMA_UNMAP(dhd->osh, pa, (uint) len, DMA_RX, 0, dmah);
 
+#ifdef DMAMAP_STATS
+                       dhd->dma_stats.rxdata--;
+                       dhd->dma_stats.rxdata_sz -= len;
+#endif /* DMAMAP_STATS */
                        DHD_INFO(("id 0x%04x, offset %d, len %d, idx %d, phase 0x%02x, "
                                "pktdata %p, metalen %d\n",
                                ltoh32(msg->cmn_hdr.request_id),
@@ -4309,12 +4376,8 @@ dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd, uint bound)
                        dhd_lb_rx_pkt_enqueue(dhd, pkt, ifidx);
 #elif defined(DHD_RX_CHAINING)
                        dhd_rxchain_frame(dhd, pkt, ifidx);
-#else
-#ifdef DHD_WAKE_STATUS
-                       dhd_bus_rx_frame(dhd->bus, pkt, ifidx, 1, pkt_wake);
 #else
                        dhd_bus_rx_frame(dhd->bus, pkt, ifidx, 1);
-#endif /* DHD_WAKE_STATUS */
 #endif /* DHD_LB_RXP */
                }
 
@@ -4323,12 +4386,8 @@ dhd_prot_process_msgbuf_rxcpl(dhd_pub_t *dhd, uint bound)
                        dhd_lb_rx_pkt_enqueue(dhd, pkt_newidx, if_newidx);
 #elif defined(DHD_RX_CHAINING)
                        dhd_rxchain_frame(dhd, pkt_newidx, if_newidx);
-#else
-#ifdef DHD_WAKE_STATUS
-                       dhd_bus_rx_frame(dhd->bus, pkt_newidx, if_newidx, 1, pkt_wake);
 #else
                        dhd_bus_rx_frame(dhd->bus, pkt_newidx, if_newidx, 1);
-#endif /* DHD_WAKE_STATUS */
 #endif /* DHD_LB_RXP */
                }
 
@@ -4942,7 +5001,11 @@ workq_ring_full:
                                secdma, offset);
                } else
                        DMA_UNMAP(dhd->osh, pa, (uint) len, DMA_RX, 0, dmah);
-#ifdef DBG_PKT_MON
+#ifdef DMAMAP_STATS
+               dhd->dma_stats.txdata--;
+               dhd->dma_stats.txdata_sz -= len;
+#endif /* DMAMAP_STATS */
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
                if (dhd->d11_tx_status) {
                        uint16 tx_status;
 
@@ -4951,9 +5014,11 @@ workq_ring_full:
                        pkt_fate = (tx_status == WLFC_CTL_PKTFLAG_DISCARD) ? TRUE : FALSE;
 
                        DHD_DBG_PKT_MON_TX_STATUS(dhd, pkt, pktid, tx_status);
+#ifdef DHD_PKT_LOGGING
+                       DHD_PKTLOG_TXS(dhd, pkt, pktid, tx_status);
+#endif /* DHD_PKT_LOGGING */
                }
-#endif /* DBG_PKT_MON */
-
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
 #if defined(BCMPCIE)
                dhd_txcomplete(dhd, pkt, pkt_fate);
 #endif 
@@ -5005,10 +5070,6 @@ dhd_prot_event_process(dhd_pub_t *dhd, void *msg)
        unsigned long flags;
        dhd_prot_t *prot = dhd->prot;
 
-#ifdef DHD_WAKE_STATUS
-       int pkt_wake = bcmpcie_set_get_wake(dhd->bus, 0);
-#endif
-
        /* Event complete header */
        evnt = (wlevent_req_msg_t *)msg;
        bufid = ltoh32(evnt->cmn_hdr.request_id);
@@ -5043,11 +5104,7 @@ dhd_prot_event_process(dhd_pub_t *dhd, void *msg)
 
        PKTSETLEN(dhd->osh, pkt, buflen);
 
-#ifdef DHD_WAKE_STATUS
-       dhd_bus_rx_frame(dhd->bus, pkt, ifidx, 1, pkt_wake);
-#else
        dhd_bus_rx_frame(dhd->bus, pkt, ifidx, 1);
-#endif /* DHD_WAKE_STATUS */
 }
 
 /** called on MSG_TYPE_INFO_BUF_CMPLT message received from dongle */
@@ -5060,9 +5117,6 @@ dhd_prot_process_infobuf_complete(dhd_pub_t *dhd, void* buf)
        void * pkt;
        unsigned long flags;
 
-#ifdef DHD_WAKE_STATUS
-       int pkt_wake = bcmpcie_set_get_wake(dhd->bus, 0);
-#endif
        resp = (info_buf_resp_t *)buf;
        pktid = ltoh32(resp->cmn_hdr.request_id);
        buflen = ltoh16(resp->info_data_len);
@@ -5101,11 +5155,7 @@ dhd_prot_process_infobuf_complete(dhd_pub_t *dhd, void* buf)
         * special ifidx of -1.  This is just internal to dhd to get the data to
         * dhd_linux.c:dhd_rx_frame() from here (dhd_prot_infobuf_cmplt_process).
         */
-#ifdef DHD_WAKE_STATUS
-       dhd_bus_rx_frame(dhd->bus, pkt, DHD_EVENT_IF /* ifidx HACK */, 1, pkt_wake);
-#else
        dhd_bus_rx_frame(dhd->bus, pkt, DHD_EVENT_IF /* ifidx HACK */, 1);
-#endif /* DHD_WAKE_STATUS */
 }
 
 /** Stop protocol: sync w/dongle state. */
@@ -5193,21 +5243,17 @@ dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx)
        txdesc = (host_txbuf_post_t *)
                dhd_prot_alloc_ring_space(dhd, ring, 1, &alloced, FALSE);
        if (txdesc == NULL) {
-#if defined(DHD_PCIE_PKTID)
-               void *dmah;
-               void *secdma;
-               /* Free up the PKTID. physaddr and pktlen will be garbage. */
-               DHD_PKTID_TO_NATIVE(dhd, dhd->prot->pktid_tx_map, pktid,
-                       pa, pktlen, dmah, secdma, PKTTYPE_NO_CHECK);
-#endif /* DHD_PCIE_PKTID */
                DHD_INFO(("%s:%d: HTOD Msgbuf Not available TxCount = %d\n",
                        __FUNCTION__, __LINE__, prot->active_tx_count));
-               goto err_no_res_pktfree;
+               goto err_free_pktid;
        }
 
 #ifdef DBG_PKT_MON
        DHD_DBG_PKT_MON_TX(dhd, PKTBUF, pktid);
 #endif /* DBG_PKT_MON */
+#ifdef DHD_PKT_LOGGING
+       DHD_PKTLOG_TX(dhd, PKTBUF, pktid);
+#endif /* DHD_PKT_LOGGING */
 
 
        /* Extract the data pointer and length information */
@@ -5238,10 +5284,16 @@ dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx)
 #endif /* #ifndef BCM_SECURE_DMA */
 
        if (PHYSADDRISZERO(pa)) {
-               DHD_ERROR(("Something really bad, unless 0 is a valid phyaddr\n"));
+               DHD_ERROR(("%s: Something really bad, unless 0 is "
+                       "a valid phyaddr for pa\n", __FUNCTION__));
                ASSERT(0);
+               goto err_rollback_idx;
        }
 
+#ifdef DMAMAP_STATS
+       dhd->dma_stats.txdata++;
+       dhd->dma_stats.txdata_sz += pktlen;
+#endif /* DMAMAP_STATS */
        /* No need to lock. Save the rest of the packet's metadata */
        DHD_NATIVE_TO_PKTID_SAVE(dhd, dhd->prot->pktid_tx_map, PKTBUF, pktid,
            pa, pktlen, DMA_TX, NULL, ring->dma_buf.secdma, PKTTYPE_DATA_TX);
@@ -5297,8 +5349,33 @@ dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx)
 #endif /* #ifndef BCM_SECURE_DMA */
 
                if (PHYSADDRISZERO(meta_pa)) {
-                       DHD_ERROR(("Something really bad, unless 0 is a valid phyaddr\n"));
+                       /* Unmap the data pointer to a DMA-able address */
+                       if (SECURE_DMA_ENAB(dhd->osh)) {
+
+                               int offset = 0;
+                               BCM_REFERENCE(offset);
+
+                               if (prot->tx_metadata_offset) {
+                                       offset = prot->tx_metadata_offset + ETHER_HDR_LEN;
+                               }
+
+                               SECURE_DMA_UNMAP(dhd->osh, pa, pktlen,
+                                       DMA_TX, 0, DHD_DMAH_NULL, ring->dma_buf.secdma, offset);
+                       }
+#ifndef BCM_SECURE_DMA
+                       else {
+                               DMA_UNMAP(dhd->osh, pa, pktlen, DMA_TX, 0, DHD_DMAH_NULL);
+                       }
+#endif /* #ifndef BCM_SECURE_DMA */
+#ifdef TXP_FLUSH_NITEMS
+                       /* update pend_items_count */
+                       ring->pend_items_count--;
+#endif /* TXP_FLUSH_NITEMS */
+
+                       DHD_ERROR(("%s: Something really bad, unless 0 is "
+                               "a valid phyaddr for meta_pa\n", __FUNCTION__));
                        ASSERT(0);
+                       goto err_rollback_idx;
                }
 
                /* Adjust the data pointer back to original value */
@@ -5352,7 +5429,31 @@ dhd_prot_txdata(dhd_pub_t *dhd, void *PKTBUF, uint8 ifidx)
 
        return BCME_OK;
 
+err_rollback_idx:
+       /* roll back write pointer for unprocessed message */
+       if (ring->wr == 0) {
+               ring->wr = ring->max_items - 1;
+       } else {
+               ring->wr--;
+               if (ring->wr == 0) {
+                       DHD_INFO(("%s: flipping the phase now\n", ring->name));
+                       ring->current_phase = ring->current_phase ?
+                               0 : BCMPCIE_CMNHDR_PHASE_BIT_INIT;
+               }
+       }
+
+err_free_pktid:
+#if defined(DHD_PCIE_PKTID)
+       {
+               void *dmah;
+               void *secdma;
+               /* Free up the PKTID. physaddr and pktlen will be garbage. */
+               DHD_PKTID_TO_NATIVE(dhd, dhd->prot->pktid_tx_map, pktid,
+                       pa, pktlen, dmah, secdma, PKTTYPE_NO_CHECK);
+       }
+
 err_no_res_pktfree:
+#endif /* DHD_PCIE_PKTID */
 
 
 
@@ -5674,7 +5775,7 @@ dmaxfer_free_prev_dmaaddr(dhd_pub_t *dhdp, dmaxref_mem_map_t *dmmap)
 int dmaxfer_prepare_dmaaddr(dhd_pub_t *dhd, uint len,
        uint srcdelay, uint destdelay, dhd_dmaxfer_t *dmaxfer)
 {
-       uint i;
+       uint i = 0, j = 0;
        if (!dmaxfer)
                return BCME_ERROR;
 
@@ -5692,10 +5793,24 @@ int dmaxfer_prepare_dmaaddr(dhd_pub_t *dhd, uint len,
 
        dmaxfer->len = len;
 
-       /* Populate source with a pattern */
-       for (i = 0; i < dmaxfer->len; i++) {
-               ((uint8*)dmaxfer->srcmem.va)[i] = i % 256;
+       /* Populate source with a pattern like below
+        * 0x00000000
+        * 0x01010101
+        * 0x02020202
+        * 0x03030303
+        * 0x04040404
+        * 0x05050505
+        * ...
+        * 0xFFFFFFFF
+        */
+       while (i < dmaxfer->len) {
+               ((uint8*)dmaxfer->srcmem.va)[i] = j % 256;
+               i++;
+               if (i % 4 == 0) {
+                       j++;
+               }
        }
+
        OSL_CACHE_FLUSH(dmaxfer->srcmem.va, dmaxfer->len);
 
        dmaxfer->srcdelay = srcdelay;
@@ -5712,32 +5827,67 @@ dhd_msgbuf_dmaxfer_process(dhd_pub_t *dhd, void *msg)
        pcie_dmaxfer_cmplt_t *cmplt = (pcie_dmaxfer_cmplt_t *)msg;
 
        BCM_REFERENCE(cmplt);
-       DHD_INFO(("DMA status: %d\n", cmplt->compl_hdr.status));
+       end_usec = OSL_SYSUPTIME_US();
+
+       DHD_ERROR(("DMA loopback status: %d\n", cmplt->compl_hdr.status));
+       prot->dmaxfer.status = cmplt->compl_hdr.status;
        OSL_CACHE_INV(prot->dmaxfer.dstmem.va, prot->dmaxfer.len);
        if (prot->dmaxfer.srcmem.va && prot->dmaxfer.dstmem.va) {
                if (memcmp(prot->dmaxfer.srcmem.va,
-                       prot->dmaxfer.dstmem.va, prot->dmaxfer.len)) {
+                       prot->dmaxfer.dstmem.va, prot->dmaxfer.len) ||
+                       cmplt->compl_hdr.status != BCME_OK) {
+                       DHD_ERROR(("DMA loopback failed\n"));
                        prhex("XFER SRC: ",
-                           prot->dmaxfer.srcmem.va, prot->dmaxfer.len);
+                               prot->dmaxfer.srcmem.va, prot->dmaxfer.len);
                        prhex("XFER DST: ",
-                           prot->dmaxfer.dstmem.va, prot->dmaxfer.len);
-                       DHD_ERROR(("DMA failed\n"));
+                               prot->dmaxfer.dstmem.va, prot->dmaxfer.len);
+                       prot->dmaxfer.status = BCME_ERROR;
                }
                else {
-                       if (prot->dmaxfer.d11_lpbk) {
+                       switch (prot->dmaxfer.d11_lpbk) {
+                       case M2M_DMA_LPBK: {
+                               DHD_ERROR(("DMA successful pcie m2m DMA loopback\n"));
+                               } break;
+                       case D11_LPBK: {
                                DHD_ERROR(("DMA successful with d11 loopback\n"));
-                       } else {
-                               DHD_ERROR(("DMA successful without d11 loopback\n"));
+                               } break;
+                       case BMC_LPBK: {
+                               DHD_ERROR(("DMA successful with bmc loopback\n"));
+                               } break;
+                       case M2M_NON_DMA_LPBK: {
+                               DHD_ERROR(("DMA successful pcie m2m NON DMA loopback\n"));
+                               } break;
+                       case D11_HOST_MEM_LPBK: {
+                               DHD_ERROR(("DMA successful d11 host mem loopback\n"));
+                               } break;
+                       case BMC_HOST_MEM_LPBK: {
+                               DHD_ERROR(("DMA successful bmc host mem loopback\n"));
+                               } break;
+                       default: {
+                               DHD_ERROR(("Invalid loopback option\n"));
+                               } break;
+                       }
+
+                       if (DHD_LPBKDTDUMP_ON()) {
+                               /* debug info print of the Tx and Rx buffers */
+                               dhd_prhex("XFER SRC: ", prot->dmaxfer.srcmem.va,
+                                       prot->dmaxfer.len, DHD_INFO_VAL);
+                               dhd_prhex("XFER DST: ", prot->dmaxfer.dstmem.va,
+                                       prot->dmaxfer.len, DHD_INFO_VAL);
                        }
                }
        }
-       end_usec = OSL_SYSUPTIME_US();
+
        dhd_prepare_schedule_dmaxfer_free(dhd);
        end_usec -= prot->dmaxfer.start_usec;
-       DHD_ERROR(("DMA loopback %d bytes in %llu usec, %u kBps\n",
-               prot->dmaxfer.len, end_usec,
-               (prot->dmaxfer.len * (1000 * 1000 / 1024) / (uint32)(end_usec + 1))));
+       if (end_usec)
+               DHD_ERROR(("DMA loopback %d bytes in %lu usec, %u kBps\n",
+                       prot->dmaxfer.len, (unsigned long)end_usec,
+                       (prot->dmaxfer.len * (1000 * 1000 / 1024) / (uint32)end_usec)));
        dhd->prot->dmaxfer.in_progress = FALSE;
+
+       dhd->bus->dmaxfer_complete = TRUE;
+       dhd_os_dmaxfer_wake(dhd);
 }
 
 /** Test functionality.
@@ -5746,7 +5896,8 @@ dhd_msgbuf_dmaxfer_process(dhd_pub_t *dhd, void *msg)
  * by a spinlock.
  */
 int
-dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd, uint len, uint srcdelay, uint destdelay, uint d11_lpbk)
+dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd, uint len, uint srcdelay, uint destdelay,
+       uint d11_lpbk, uint core_num)
 {
        unsigned long flags;
        int ret = BCME_OK;
@@ -5758,23 +5909,25 @@ dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd, uint len, uint srcdelay, uint destdelay, u
 
        if (prot->dmaxfer.in_progress) {
                DHD_ERROR(("DMA is in progress...\n"));
-               return ret;
+               return BCME_ERROR;
+       }
+
+       if (d11_lpbk >= MAX_LPBK) {
+               DHD_ERROR(("loopback mode should be either"
+                       " 0-PCIE_M2M_DMA, 1-D11, 2-BMC or 3-PCIE_M2M_NonDMA\n"));
+               return BCME_ERROR;
        }
 
+       DHD_GENERAL_LOCK(dhd, flags);
+
        prot->dmaxfer.in_progress = TRUE;
        if ((ret = dmaxfer_prepare_dmaaddr(dhd, xferlen, srcdelay, destdelay,
-               &prot->dmaxfer)) != BCME_OK) {
+               &prot->dmaxfer)) != BCME_OK) {
                prot->dmaxfer.in_progress = FALSE;
+               DHD_GENERAL_UNLOCK(dhd, flags);
                return ret;
        }
 
-#ifdef PCIE_INB_DW
-       if (dhd_prot_inc_hostactive_devwake_assert(dhd->bus) != BCME_OK)
-               return BCME_ERROR;
-#endif /* PCIE_INB_DW */
-
-       DHD_GENERAL_LOCK(dhd, flags);
-
        dmap = (pcie_dma_xfer_params_t *)
                dhd_prot_alloc_ring_space(dhd, ring, 1, &alloced, FALSE);
 
@@ -5782,9 +5935,6 @@ dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd, uint len, uint srcdelay, uint destdelay, u
                dmaxfer_free_dmaaddr(dhd, &prot->dmaxfer);
                prot->dmaxfer.in_progress = FALSE;
                DHD_GENERAL_UNLOCK(dhd, flags);
-#ifdef PCIE_INB_DW
-               dhd_prot_dec_hostactive_ack_pending_dsreq(dhd->bus);
-#endif
                return BCME_NOMEM;
        }
 
@@ -5802,23 +5952,36 @@ dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd, uint len, uint srcdelay, uint destdelay, u
        dmap->xfer_len = htol32(prot->dmaxfer.len);
        dmap->srcdelay = htol32(prot->dmaxfer.srcdelay);
        dmap->destdelay = htol32(prot->dmaxfer.destdelay);
-       prot->dmaxfer.d11_lpbk = d11_lpbk ? 1 : 0;
-       dmap->flags = (prot->dmaxfer.d11_lpbk << PCIE_DMA_XFER_FLG_D11_LPBK_SHIFT)
-                       & PCIE_DMA_XFER_FLG_D11_LPBK_MASK;
+       prot->dmaxfer.d11_lpbk = d11_lpbk;
+       dmap->flags = (((core_num & PCIE_DMA_XFER_FLG_CORE_NUMBER_MASK)
+                       << PCIE_DMA_XFER_FLG_CORE_NUMBER_SHIFT) |
+                       ((prot->dmaxfer.d11_lpbk & PCIE_DMA_XFER_FLG_D11_LPBK_MASK)
+                       << PCIE_DMA_XFER_FLG_D11_LPBK_SHIFT));
+       prot->dmaxfer.start_usec = OSL_SYSUPTIME_US();
 
        /* update ring's WR index and ring doorbell to dongle */
-       prot->dmaxfer.start_usec = OSL_SYSUPTIME_US();
        dhd_prot_ring_write_complete(dhd, ring, dmap, 1);
+
        DHD_GENERAL_UNLOCK(dhd, flags);
-#ifdef PCIE_INB_DW
-       dhd_prot_dec_hostactive_ack_pending_dsreq(dhd->bus);
-#endif
 
-       DHD_INFO(("DMA Started...\n"));
+       DHD_ERROR(("DMA loopback Started...\n"));
 
        return BCME_OK;
 } /* dhdmsgbuf_dmaxfer_req */
 
+dma_xfer_status_t
+dhdmsgbuf_dmaxfer_status(dhd_pub_t *dhd)
+{
+       dhd_prot_t *prot = dhd->prot;
+
+       if (prot->dmaxfer.in_progress)
+               return DMA_XFER_IN_PROGRESS;
+       else if (prot->dmaxfer.status == BCME_OK)
+               return DMA_XFER_SUCCESS;
+       else
+               return DMA_XFER_FAILED;
+}
+
 /** Called in the process of submitting an ioctl to the dongle */
 static int
 dhd_msgbuf_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
@@ -8410,19 +8573,11 @@ dhd_rxchain_commit(dhd_pub_t *dhd)
        dhd_prot_t *prot = dhd->prot;
        rxchain_info_t *rxchain = &prot->rxchain;
 
-#ifdef DHD_WAKE_STATUS
-       int pkt_wake = bcmpcie_set_get_wake(dhd->bus, 0);
-#endif /* DHD_WAKE_STATUS */
-
        if (rxchain->pkt_count == 0)
                return;
 
        /* Release the packets to dhd_linux */
-#ifdef DHD_WAKE_STATUS
-       dhd_bus_rx_frame(dhd->bus, rxchain->pkthead, rxchain->ifidx, rxchain->pkt_count, pkt_wake);
-#else
        dhd_bus_rx_frame(dhd->bus, rxchain->pkthead, rxchain->ifidx, rxchain->pkt_count);
-#endif /* DHD_WAKE_STATUS */
 
        /* Reset the chain */
        dhd_rxchain_reset(rxchain);
index f5ba5d28bd4d98582693b9fa182cd36e8392382e..4501f8160a9b56ba0d2e211fb0704b687cdde8a9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DHD Bus Module for PCIE
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_pcie.c 688368 2017-03-06 07:11:43Z $
+ * $Id: dhd_pcie.c 748759 2018-02-26 02:26:08Z $
  */
 
 
@@ -102,8 +102,9 @@ static int dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 act
        const char *name, void *params,
        int plen, void *arg, int len, int val_size);
 static int dhdpcie_bus_lpback_req(struct  dhd_bus *bus, uint32 intval);
-static int dhdpcie_bus_dmaxfer_req(struct  dhd_bus *bus,
-       uint32 len, uint32 srcdelay, uint32 destdelay, uint32 d11_lpbk);
+static int dhdpcie_bus_dmaxfer_req(struct dhd_bus *bus,
+       uint32 len, uint32 srcdelay, uint32 destdelay,
+       uint32 d11_lpbk, uint32 core_num, uint32 wait);
 static int dhdpcie_bus_download_state(dhd_bus_t *bus, bool enter);
 static int _dhdpcie_download_firmware(struct dhd_bus *bus);
 static int dhdpcie_download_firmware(dhd_bus_t *bus, osl_t *osh);
@@ -159,13 +160,16 @@ static uint dhd_doorbell_timeout = DHD_DEFAULT_DOORBELL_TIMEOUT;
 static bool dhdpcie_check_firmware_compatible(uint32 f_api_version, uint32 h_api_version);
 static void dhdpcie_cto_error_recovery(struct dhd_bus *bus);
 
+#ifdef BCM_ASLR_HEAP
+static void dhdpcie_wrt_rnd(struct dhd_bus *bus);
+#endif /* BCM_ASLR_HEAP */
+
 extern uint16 dhd_prot_get_h2d_max_txpost(dhd_pub_t *dhd);
 extern void dhd_prot_set_h2d_max_txpost(dhd_pub_t *dhd, uint16 max_txpost);
 
 /* IOVar table */
 enum {
        IOV_INTR = 1,
-       IOV_MEMBYTES,
        IOV_MEMSIZE,
        IOV_SET_DOWNLOAD_STATE,
        IOV_DEVRESET,
@@ -232,7 +236,6 @@ enum {
 
 const bcm_iovar_t dhdpcie_iovars[] = {
        {"intr",        IOV_INTR,       0,      0, IOVT_BOOL,   0 },
-       {"membytes",    IOV_MEMBYTES,   0,      0, IOVT_BUFFER, 2 * sizeof(int) },
        {"memsize",     IOV_MEMSIZE,    0,      0, IOVT_UINT32, 0 },
        {"dwnldstate",  IOV_SET_DOWNLOAD_STATE, 0,      0, IOVT_BOOL,   0 },
        {"vars",        IOV_VARS,       0,      0, IOVT_BUFFER, 0 },
@@ -576,10 +579,12 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
                }
 
                if (bus->dhd->dongle_reset) {
+                       DHD_ERROR(("%s : dongle is reset\n", __FUNCTION__));
                        break;
                }
 
                if (bus->dhd->busstate == DHD_BUS_DOWN) {
+                       DHD_ERROR(("%s : bus is down \n", __FUNCTION__));
                        break;
                }
 
@@ -601,6 +606,7 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
 
                /* Check if the interrupt is ours or not */
                if (intstatus == 0) {
+                       DHD_TRACE(("%s : this interrupt is not ours\n", __FUNCTION__));
                        break;
                }
 
@@ -610,9 +616,11 @@ dhdpcie_bus_isr(dhd_bus_t *bus)
 
                /* return error for 0xFFFFFFFF */
                if (intstatus == (uint32)-1) {
+                       DHD_ERROR(("%s : wrong interrupt status val : 0x%x\n",
+                               __FUNCTION__, intstatus));
                        dhdpcie_disable_irq_nosync(bus);
                        bus->is_linkdown = TRUE;
-                       return BCME_ERROR;
+                       break;
                }
 
                /*  Overall operation:
@@ -889,10 +897,10 @@ dhdpcie_dongle_attach(dhd_bus_t *bus)
                goto fail;
        }
 
+#ifndef DONGLE_ENABLE_ISOLATION
        /* Enable CLKREQ# */
        dhdpcie_clkreq(bus->osh, 1, 1);
 
-#ifndef DONGLE_ENABLE_ISOLATION
        /*
         * Issue CC watchdog to reset all the cores on the chip - similar to rmmod dhd
         * This is required to avoid spurious interrupts to the Host and bring back
@@ -995,6 +1003,12 @@ dhdpcie_dongle_attach(dhd_bus_t *bus)
        if (dhd_dongle_memsize)
                dhdpcie_bus_dongle_setmemsize(bus, dhd_dongle_memsize);
 
+       if (bus->ramsize > DONGLE_TCM_MAP_SIZE) {
+               DHD_ERROR(("%s : invalid ramsize %d(0x%x) is returned from dongle\n",
+                               __FUNCTION__, bus->ramsize, bus->ramsize));
+               goto fail;
+       }
+
        DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d) at 0x%x\n",
                   bus->ramsize, bus->orig_ramsize, bus->dongle_ram_base));
 
@@ -1241,8 +1255,10 @@ dhdpcie_bus_release_dongle(dhd_bus_t *bus, osl_t *osh, bool dongle_isolation, bo
                         pcie_serdes_iddqdisable(bus->osh, bus->sih,
                                                 (sbpcieregs_t *) bus->regs);
 
+#ifndef DONGLE_ENABLE_ISOLATION
                /* Disable CLKREQ# */
                dhdpcie_clkreq(bus->osh, 1, 0);
+#endif /* !DONGLE_ENABLE_ISOLATION */
 
                if (bus->sih != NULL) {
                        si_detach(bus->sih);
@@ -1548,112 +1564,14 @@ bool dhd_bus_watchdog(dhd_pub_t *dhd)
 } /* dhd_bus_watchdog */
 
 #if defined(SUPPORT_MULTIPLE_REVISION)
-static int concate_revision_bcm4358(dhd_bus_t *bus, char *fw_path, char *nv_path)
-{
-       uint32 chiprev;
-#if defined(SUPPORT_MULTIPLE_CHIPS)
-       char chipver_tag[20] = "_4358";
-#else
-       char chipver_tag[10] = {0, };
-#endif /* SUPPORT_MULTIPLE_CHIPS */
-
-       chiprev = dhd_bus_chiprev(bus);
-       if (chiprev == 0) {
-               DHD_ERROR(("----- CHIP 4358 A0 -----\n"));
-               strcat(chipver_tag, "_a0");
-       } else if (chiprev == 1) {
-               DHD_ERROR(("----- CHIP 4358 A1 -----\n"));
-#if defined(SUPPORT_MULTIPLE_CHIPS) || defined(SUPPORT_MULTIPLE_MODULE_CIS)
-               strcat(chipver_tag, "_a1");
-#endif /* defined(SUPPORT_MULTIPLE_CHIPS) || defined(SUPPORT_MULTIPLE_MODULE_CIS) */
-       } else if (chiprev == 3) {
-               DHD_ERROR(("----- CHIP 4358 A3 -----\n"));
-#if defined(SUPPORT_MULTIPLE_CHIPS)
-               strcat(chipver_tag, "_a3");
-#endif /* SUPPORT_MULTIPLE_CHIPS */
-       } else {
-               DHD_ERROR(("----- Unknown chip version, ver=%x -----\n", chiprev));
-       }
-
-       strcat(fw_path, chipver_tag);
-
-#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK)
-       if (chiprev == 1 || chiprev == 3) {
-               int ret = dhd_check_module_b85a();
-               if ((chiprev == 1) && (ret < 0)) {
-                       memset(chipver_tag, 0x00, sizeof(chipver_tag));
-                       strcat(chipver_tag, "_b85");
-                       strcat(chipver_tag, "_a1");
-               }
-       }
-
-       DHD_ERROR(("%s: chipver_tag %s \n", __FUNCTION__, chipver_tag));
-#endif /* defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) */
-
-#if defined(SUPPORT_MULTIPLE_BOARD_REV)
-       if (system_rev >= 10) {
-               DHD_ERROR(("----- Board Rev  [%d]-----\n", system_rev));
-               strcat(chipver_tag, "_r10");
-       }
-#endif /* SUPPORT_MULTIPLE_BOARD_REV */
-       strcat(nv_path, chipver_tag);
 
-       return 0;
-}
-
-static int concate_revision_bcm4359(dhd_bus_t *bus, char *fw_path, char *nv_path)
-{
-       uint32 chip_ver;
-       char chipver_tag[10] = {0, };
 #if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) && \
        defined(SUPPORT_BCM4359_MIXED_MODULES)
-       int module_type = -1;
+#define VENDOR_MURATA "murata"
+#define VENDOR_WISOL "wisol"
+#define VNAME_DELIM "_"
 #endif /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
 
-       chip_ver = bus->sih->chiprev;
-       if (chip_ver == 4) {
-               DHD_ERROR(("----- CHIP 4359 B0 -----\n"));
-               strncat(chipver_tag, "_b0", strlen("_b0"));
-       } else if (chip_ver == 5) {
-               DHD_ERROR(("----- CHIP 4359 B1 -----\n"));
-               strncat(chipver_tag, "_b1", strlen("_b1"));
-       } else if (chip_ver == 9) {
-               DHD_ERROR(("----- CHIP 4359 C0 -----\n"));
-               strncat(chipver_tag, "_c0", strlen("_c0"));
-       } else {
-               DHD_ERROR(("----- Unknown chip version, ver=%x -----\n", chip_ver));
-               return -1;
-       }
-
-#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) && \
-       defined(SUPPORT_BCM4359_MIXED_MODULES)
-       module_type =  dhd_check_module_b90();
-
-       switch (module_type) {
-               case BCM4359_MODULE_TYPE_B90B:
-                       strcat(fw_path, chipver_tag);
-                       break;
-               case BCM4359_MODULE_TYPE_B90S:
-               default:
-                       /*
-                        * .cid.info file not exist case,
-                        * loading B90S FW force for initial MFG boot up.
-                       */
-                       if (chip_ver == 5) {
-                               strncat(fw_path, "_b90s", strlen("_b90s"));
-                       }
-                       strcat(fw_path, chipver_tag);
-                       strcat(nv_path, chipver_tag);
-                       break;
-       }
-#else /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
-       strcat(fw_path, chipver_tag);
-       strcat(nv_path, chipver_tag);
-#endif /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
-
-       return 0;
-}
-
 #if defined(SUPPORT_BCM4361_MIXED_MODULES) && defined(USE_CID_CHECK)
 
 #define MAX_EXTENSION 20
@@ -1905,6 +1823,139 @@ dhd_find_naming_info_by_chip_rev(naming_info_t table[], int table_size,
 }
 #endif /* SUPPORT_BCM4361_MIXED_MODULES && USE_CID_CHECK */
 
+static int concate_revision_bcm4358(dhd_bus_t *bus, char *fw_path, char *nv_path)
+{
+       uint32 chiprev;
+#if defined(SUPPORT_MULTIPLE_CHIPS)
+       char chipver_tag[20] = "_4358";
+#else
+       char chipver_tag[10] = {0, };
+#endif /* SUPPORT_MULTIPLE_CHIPS */
+
+       chiprev = dhd_bus_chiprev(bus);
+       if (chiprev == 0) {
+               DHD_ERROR(("----- CHIP 4358 A0 -----\n"));
+               strcat(chipver_tag, "_a0");
+       } else if (chiprev == 1) {
+               DHD_ERROR(("----- CHIP 4358 A1 -----\n"));
+#if defined(SUPPORT_MULTIPLE_CHIPS) || defined(SUPPORT_MULTIPLE_MODULE_CIS)
+               strcat(chipver_tag, "_a1");
+#endif /* defined(SUPPORT_MULTIPLE_CHIPS) || defined(SUPPORT_MULTIPLE_MODULE_CIS) */
+       } else if (chiprev == 3) {
+               DHD_ERROR(("----- CHIP 4358 A3 -----\n"));
+#if defined(SUPPORT_MULTIPLE_CHIPS)
+               strcat(chipver_tag, "_a3");
+#endif /* SUPPORT_MULTIPLE_CHIPS */
+       } else {
+               DHD_ERROR(("----- Unknown chip version, ver=%x -----\n", chiprev));
+       }
+
+       strcat(fw_path, chipver_tag);
+
+#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK)
+       if (chiprev == 1 || chiprev == 3) {
+               int ret = dhd_check_module_b85a();
+               if ((chiprev == 1) && (ret < 0)) {
+                       memset(chipver_tag, 0x00, sizeof(chipver_tag));
+                       strcat(chipver_tag, "_b85");
+                       strcat(chipver_tag, "_a1");
+               }
+       }
+
+       DHD_ERROR(("%s: chipver_tag %s \n", __FUNCTION__, chipver_tag));
+#endif /* defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) */
+
+#if defined(SUPPORT_MULTIPLE_BOARD_REV)
+       if (system_rev >= 10) {
+               DHD_ERROR(("----- Board Rev  [%d]-----\n", system_rev));
+               strcat(chipver_tag, "_r10");
+       }
+#endif /* SUPPORT_MULTIPLE_BOARD_REV */
+       strcat(nv_path, chipver_tag);
+
+       return BCME_OK;
+}
+
+static int concate_revision_bcm4359(dhd_bus_t *bus, char *fw_path, char *nv_path)
+{
+       uint32 chip_ver;
+       char chipver_tag[10] = {0, };
+#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) && \
+       defined(SUPPORT_BCM4359_MIXED_MODULES)
+       char chipver_tag_nv[10] = {0, };
+       int module_type = -1;
+#endif /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
+
+       chip_ver = bus->sih->chiprev;
+       if (chip_ver == 4) {
+               DHD_ERROR(("----- CHIP 4359 B0 -----\n"));
+               strncat(chipver_tag, "_b0", strlen("_b0"));
+       } else if (chip_ver == 5) {
+               DHD_ERROR(("----- CHIP 4359 B1 -----\n"));
+               strncat(chipver_tag, "_b1", strlen("_b1"));
+       } else if (chip_ver == 9) {
+               DHD_ERROR(("----- CHIP 4359 C0 -----\n"));
+#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) && \
+       defined(SUPPORT_BCM4359_MIXED_MODULES)
+               if (dhd_check_module(VENDOR_MURATA)) {
+                       strncat(chipver_tag_nv, VNAME_DELIM, strlen(VNAME_DELIM));
+                       strncat(chipver_tag_nv, VENDOR_MURATA, strlen(VENDOR_MURATA));
+               } else if (dhd_check_module(VENDOR_WISOL)) {
+                       strncat(chipver_tag_nv, VNAME_DELIM, strlen(VNAME_DELIM));
+                       strncat(chipver_tag_nv, VENDOR_WISOL, strlen(VENDOR_WISOL));
+               }
+               /* In case of SEMCO module, extra vendor string doen not need to add */
+               strncat(chipver_tag_nv, "_c0", strlen("_c0"));
+#endif /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
+               strncat(chipver_tag, "_c0", strlen("_c0"));
+#if defined(CONFIG_WLAN_GRACE) || defined(CONFIG_SEC_GRACEQLTE_PROJECT)
+               DHD_ERROR(("----- Adding _plus string -----\n"));
+               strncat(chipver_tag, "_plus", strlen("_plus"));
+#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) && \
+       defined(SUPPORT_BCM4359_MIXED_MODULES)
+               strncat(chipver_tag_nv, "_plus", strlen("_plus"));
+#endif /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
+#endif /* CONFIG_WLAN_GRACE || CONFIG_SEC_GRACEQLTE_PROJECT */
+       } else {
+               DHD_ERROR(("----- Unknown chip version, ver=%x -----\n", chip_ver));
+               return BCME_ERROR;
+       }
+
+#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) && \
+       defined(SUPPORT_BCM4359_MIXED_MODULES)
+       module_type = dhd_check_module_b90();
+
+       switch (module_type) {
+               case BCM4359_MODULE_TYPE_B90B:
+                       strcat(fw_path, chipver_tag);
+                       break;
+               case BCM4359_MODULE_TYPE_B90S:
+                       strcat(fw_path, chipver_tag);
+                       if (!(strstr(nv_path, VENDOR_MURATA) || strstr(nv_path, VENDOR_WISOL))) {
+                               strcat(nv_path, chipver_tag_nv);
+                       } else {
+                               strcat(nv_path, chipver_tag);
+                       }
+                       break;
+               default:
+                       /*
+                        * .cid.info file not exist case,
+                        * loading B90S FW force for initial MFG boot up.
+                       */
+                       if (chip_ver == 5) {
+                               strncat(fw_path, "_b90s", strlen("_b90s"));
+                       }
+                       strcat(fw_path, chipver_tag);
+                       strcat(nv_path, chipver_tag);
+                       break;
+       }
+#else /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
+       strcat(fw_path, chipver_tag);
+       strcat(nv_path, chipver_tag);
+#endif /* SUPPORT_MULTIPLE_MODULE_CIS && USE_CID_CHECK && SUPPORT_BCM4359_MIXED_MODULES */
+
+       return BCME_OK;
+}
 static int
 concate_revision_bcm4361(dhd_bus_t *bus, char *fw_path, char *nv_path)
 {
@@ -2075,11 +2126,18 @@ dhdpcie_download_firmware(struct dhd_bus *bus, osl_t *osh)
        return ret;
 }
 
+#define DHD_MEMORY_SET_PATTERN 0xAA
+
 static int
 dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path)
 {
        int bcmerror = BCME_ERROR;
        int offset = 0;
+#if defined(DHD_FW_MEM_CORRUPTION)
+       uint8 *p_org_fw  = NULL;
+       uint32 org_fw_size = 0;
+       uint32 fw_write_offset = 0;
+#endif /* DHD_FW_MEM_CORRUPTION */
        int len = 0;
        bool store_reset;
        char *imgbuf = NULL;
@@ -2102,12 +2160,32 @@ dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path)
        memptr = memblock = MALLOC(bus->dhd->osh, MEMBLOCK + DHD_SDALIGN);
        if (memblock == NULL) {
                DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__, MEMBLOCK));
+               bcmerror = BCME_NOMEM;
                goto err;
        }
        if ((uint32)(uintptr)memblock % DHD_SDALIGN) {
                memptr += (DHD_SDALIGN - ((uint32)(uintptr)memblock % DHD_SDALIGN));
        }
 
+#if defined(DHD_FW_MEM_CORRUPTION)
+       if (dhd_bus_get_fw_mode(bus->dhd) == DHD_FLAG_MFG_MODE) {
+               org_fw_size = dhd_os_get_image_size(imgbuf);
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+               p_org_fw = (uint8*)DHD_OS_PREALLOC(bus->dhd,
+                       DHD_PREALLOC_MEMDUMP_RAM, org_fw_size);
+#else
+               p_org_fw = (uint8*)VMALLOC(bus->dhd->osh, org_fw_size);
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
+               if (p_org_fw == NULL) {
+                       DHD_ERROR(("%s: Failed to allocate memory %d bytes for download check\n",
+                               __FUNCTION__, org_fw_size));
+                       bcmerror = BCME_NOMEM;
+                       goto err;
+               } else {
+                       memset(p_org_fw, 0, org_fw_size);
+               }
+       }
+#endif /* DHD_FW_MEM_CORRUPTION */
 
        /* check if CR4/CA7 */
        store_reset = (si_setcore(bus->sih, ARMCR4_CORE_ID, 0) ||
@@ -2137,6 +2215,12 @@ dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path)
                        goto err;
                }
                offset += MEMBLOCK;
+#if defined(DHD_FW_MEM_CORRUPTION)
+               if (dhd_bus_get_fw_mode(bus->dhd) == DHD_FLAG_MFG_MODE) {
+                       memcpy((p_org_fw + fw_write_offset), memptr, len);
+                       fw_write_offset += len;
+               }
+#endif /* DHD_FW_MEM_CORRUPTION */
 
                if (offset >= offset_end) {
                        DHD_ERROR(("%s: invalid address access to %x (offset end: %x)\n",
@@ -2145,8 +2229,70 @@ dhdpcie_download_code_file(struct dhd_bus *bus, char *pfw_path)
                        goto err;
                }
        }
+#ifdef DHD_FW_MEM_CORRUPTION
+       /* Read and compare the downloaded code */
+       if (dhd_bus_get_fw_mode(bus->dhd) == DHD_FLAG_MFG_MODE) {
+               unsigned char *p_readback_buf = NULL;
+               uint32 compared_len;
+               uint32 remaining_len = 0;
+
+               compared_len = 0;
+               p_readback_buf = MALLOC(bus->dhd->osh, MEMBLOCK);
+               if (p_readback_buf == NULL) {
+                       DHD_ERROR(("%s: Failed to allocate memory %d bytes for readback buffer\n",
+                               __FUNCTION__, MEMBLOCK));
+                       bcmerror = BCME_NOMEM;
+                       goto compare_err;
+               }
+               /* Read image to verify downloaded contents. */
+               offset = bus->dongle_ram_base;
+
+               while (compared_len  < org_fw_size) {
+                       memset(p_readback_buf, DHD_MEMORY_SET_PATTERN, MEMBLOCK);
+                       remaining_len = org_fw_size - compared_len;
+
+                       if (remaining_len >= MEMBLOCK) {
+                               len = MEMBLOCK;
+                       } else {
+                               len = remaining_len;
+                       }
+                       bcmerror = dhdpcie_bus_membytes(bus, FALSE, offset,
+                               (uint8 *)p_readback_buf, len);
+                       if (bcmerror) {
+                               DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n",
+                                       __FUNCTION__, bcmerror, MEMBLOCK, offset));
+                               goto compare_err;
+                       }
+
+                       if (memcmp((p_org_fw + compared_len), p_readback_buf, len) != 0) {
+                               DHD_ERROR(("%s: Downloaded image is corrupted. offset %d\n",
+                                       __FUNCTION__, compared_len));
+                               bcmerror = BCME_ERROR;
+                               goto compare_err;
+                       }
+
+                       compared_len += len;
+                       offset += len;
+               }
+               DHD_ERROR(("%s: Download, Upload and compare succeeded.\n", __FUNCTION__));
+
+compare_err:
+               if (p_readback_buf) {
+                       MFREE(bus->dhd->osh, p_readback_buf, MEMBLOCK);
+               }
+       }
+#endif /* DHD_FW_MEM_CORRUPTION */
 
 err:
+#if defined(DHD_FW_MEM_CORRUPTION)
+       if (p_org_fw) {
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+               DHD_OS_PREFREE(bus->dhd, p_org_fw, org_fw_size);
+#else
+               VMFREE(bus->dhd->osh, p_org_fw, org_fw_size);
+#endif
+       }
+#endif /* DHD_FW_MEM_CORRUPTION */
        if (memblock) {
                MFREE(bus->dhd->osh, memblock, MEMBLOCK + DHD_SDALIGN);
        }
@@ -2789,6 +2935,7 @@ dhdpcie_checkdied(dhd_bus_t *bus, char *data, uint size)
        char *str = NULL;
        pciedev_shared_t *local_pciedev_shared = bus->pcie_sh;
        struct bcmstrbuf strbuf;
+       unsigned long flags;
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -2816,6 +2963,9 @@ dhdpcie_checkdied(dhd_bus_t *bus, char *data, uint size)
                bcmerror = BCME_NOMEM;
                goto done;
        }
+       DHD_GENERAL_LOCK(bus->dhd, flags);
+       DHD_BUS_BUSY_SET_IN_CHECKDIED(bus->dhd);
+       DHD_GENERAL_UNLOCK(bus->dhd, flags);
 
        if ((bcmerror = dhdpcie_readshared(bus)) < 0) {
                goto done;
@@ -2908,9 +3058,6 @@ dhdpcie_checkdied(dhd_bus_t *bus, char *data, uint size)
                }
 #endif /* REPORT_FATAL_TIMEOUTS */
 
-               /* wake up IOCTL wait event */
-               dhd_wakeup_ioctl_event(bus->dhd, IOCTL_RETURN_ON_TRAP);
-
                dhd_prot_debug_info_print(bus->dhd);
 
 #if defined(DHD_FW_COREDUMP)
@@ -2921,11 +3068,19 @@ dhdpcie_checkdied(dhd_bus_t *bus, char *data, uint size)
                }
 #endif /* DHD_FW_COREDUMP */
 
+               /* wake up IOCTL wait event */
+               dhd_wakeup_ioctl_event(bus->dhd, IOCTL_RETURN_ON_TRAP);
+
                dhd_schedule_reset(bus->dhd);
 
 
        }
 
+       DHD_GENERAL_LOCK(bus->dhd, flags);
+       DHD_BUS_BUSY_CLEAR_IN_CHECKDIED(bus->dhd);
+       dhd_os_busbusy_wake(bus->dhd);
+       DHD_GENERAL_UNLOCK(bus->dhd, flags);
+
 done:
        if (mbuffer)
                MFREE(bus->dhd->osh, mbuffer, msize);
@@ -3481,19 +3636,11 @@ done:
  * Called on frame reception, the frame was received from the dongle on interface 'ifidx' and is
  * contained in 'pkt'. Processes rx frame, forwards up the layer to netif.
  */
-#ifdef DHD_WAKE_STATUS
-void BCMFASTPATH
-dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count, int pkt_wake)
-{
-       dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, 0, pkt_wake, &bus->wake_counts);
-}
-#else
 void BCMFASTPATH
 dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count)
 {
        dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, 0);
 }
-#endif /* DHD_WAKE_STATUS */
 
 /** 'offset' is a backplane address */
 void
@@ -4363,11 +4510,35 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons
 
        case IOV_SVAL(IOV_PCIE_DMAXFER): {
                int int_val4 = 0;
+               int wait = 0;
+               int core_num = 0;
                if (plen >= (int)sizeof(int_val) * 4) {
                        bcopy((void*)((uintptr)params + 3 * sizeof(int_val)),
-                               &int_val4, sizeof(int_val4));
+                       &int_val4, sizeof(int_val4));
+               }
+               if (plen >= (int)sizeof(int_val) * 5) {
+                       bcopy((void*)((uintptr)params + 4 * sizeof(int_val)),
+                       &wait, sizeof(wait));
+               }
+               if (plen >= (int)sizeof(core_num) * 6) {
+                       bcopy((void*)((uintptr)params + 5 * sizeof(core_num)),
+                       &core_num, sizeof(core_num));
                }
-               bcmerror = dhdpcie_bus_dmaxfer_req(bus, int_val, int_val2, int_val3, int_val4);
+               bcmerror = dhdpcie_bus_dmaxfer_req(bus, int_val, int_val2, int_val3,
+                       int_val4, core_num, wait);
+               if (wait && bcmerror >= 0) {
+                       /* get the status of the dma transfer */
+                       int_val4 = dhdmsgbuf_dmaxfer_status(bus->dhd);
+                       bcopy(&int_val4, params, sizeof(int_val));
+               }
+               break;
+       }
+
+       case IOV_GVAL(IOV_PCIE_DMAXFER): {
+               int dma_status = 0;
+               dma_status = dhdmsgbuf_dmaxfer_status(bus->dhd);
+               bcopy(&dma_status, arg, val_size);
+               bcmerror = BCME_OK;
                break;
        }
 
@@ -4431,92 +4602,6 @@ dhdpcie_bus_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, cons
                int_val = (int32)bus->ramsize;
                bcopy(&int_val, arg, val_size);
                break;
-       case IOV_SVAL(IOV_MEMBYTES):
-       case IOV_GVAL(IOV_MEMBYTES):
-       {
-               uint32 address;         /* absolute backplane address */
-               uint size, dsize;
-               uint8 *data;
-
-               bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
-
-               ASSERT(plen >= 2*sizeof(int));
-
-               address = (uint32)int_val;
-               bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val));
-               size = (uint)int_val;
-
-               /* Do some validation */
-               dsize = set ? plen - (2 * sizeof(int)) : len;
-               if (dsize < size) {
-                       DHD_ERROR(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n",
-                                  __FUNCTION__, (set ? "set" : "get"), address, size, dsize));
-                       bcmerror = BCME_BADARG;
-                       break;
-               }
-
-               DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n dsize %d ", __FUNCTION__,
-                         (set ? "write" : "read"), size, address, dsize));
-
-               /* check if CR4 */
-               if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0) ||
-                   si_setcore(bus->sih, SYSMEM_CORE_ID, 0)) {
-                       /* if address is 0, store the reset instruction to be written in 0 */
-                       if (set && address == bus->dongle_ram_base) {
-                               bus->resetinstr = *(((uint32*)params) + 2);
-                       }
-               } else {
-               /* If we know about SOCRAM, check for a fit */
-               if ((bus->orig_ramsize) &&
-                   ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize)))
-               {
-                       uint8 enable, protect, remap;
-                       si_socdevram(bus->sih, FALSE, &enable, &protect, &remap);
-                       if (!enable || protect) {
-                               DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n",
-                                       __FUNCTION__, bus->orig_ramsize, size, address));
-                               DHD_ERROR(("%s: socram enable %d, protect %d\n",
-                                       __FUNCTION__, enable, protect));
-                               bcmerror = BCME_BADARG;
-                               break;
-                       }
-
-                       if (!REMAP_ENAB(bus) && (address >= SOCDEVRAM_ARM_ADDR)) {
-                               uint32 devramsize = si_socdevram_size(bus->sih);
-                               if ((address < SOCDEVRAM_ARM_ADDR) ||
-                                       (address + size > (SOCDEVRAM_ARM_ADDR + devramsize))) {
-                                       DHD_ERROR(("%s: bad address 0x%08x, size 0x%08x\n",
-                                               __FUNCTION__, address, size));
-                                       DHD_ERROR(("%s: socram range 0x%08x,size 0x%08x\n",
-                                               __FUNCTION__, SOCDEVRAM_ARM_ADDR, devramsize));
-                                       bcmerror = BCME_BADARG;
-                                       break;
-                               }
-                               /* move it such that address is real now */
-                               address -= SOCDEVRAM_ARM_ADDR;
-                               address += SOCDEVRAM_BP_ADDR;
-                               DHD_INFO(("%s: Request to %s %d bytes @ Mapped address 0x%08x\n",
-                                       __FUNCTION__, (set ? "write" : "read"), size, address));
-                       } else if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address) && remap) {
-                               /* Can not access remap region while devram remap bit is set
-                                * ROM content would be returned in this case
-                                */
-                               DHD_ERROR(("%s: Need to disable remap for address 0x%08x\n",
-                                       __FUNCTION__, address));
-                               bcmerror = BCME_ERROR;
-                               break;
-                       }
-               }
-               }
-
-               /* Generate the actual data pointer */
-               data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg;
-
-               /* Call to do the transfer */
-               bcmerror = dhdpcie_bus_membytes(bus, set, address, data, size);
-
-               break;
-       }
 
 #ifdef BCM_BUZZZ
        /* Dump dongle side buzzz trace to console */
@@ -5286,6 +5371,16 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state)
                        dhd_bus_start_queue(bus);
                        DHD_GENERAL_UNLOCK(bus->dhd, flags);
                        if (!bus->dhd->dongle_trap_occured) {
+                               uint32 intstatus = 0;
+
+                               /* Check if PCIe bus status is valid */
+                               intstatus = si_corereg(bus->sih,
+                                       bus->sih->buscoreidx, PCIMailBoxInt, 0, 0);
+                               if (intstatus == (uint32)-1) {
+                                       /* Invalidate PCIe bus status */
+                                       bus->is_linkdown = 1;
+                               }
+
                                dhd_bus_dump_console_buffer(bus);
                                dhd_prot_debug_info_print(bus->dhd);
 #ifdef DHD_FW_COREDUMP
@@ -5295,8 +5390,8 @@ dhdpcie_bus_suspend(struct dhd_bus *bus, bool state)
                                        dhdpcie_mem_dump(bus);
                                }
 #endif /* DHD_FW_COREDUMP */
-                               DHD_ERROR(("%s: Event HANG send up "
-                                                       "due to PCIe linkdown\n", __FUNCTION__));
+                               DHD_ERROR(("%s: Event HANG send up due to D3_ACK timeout\n",
+                                       __FUNCTION__));
 #ifdef SUPPORT_LINKDOWN_RECOVERY
 #ifdef CONFIG_ARCH_MSM
                                bus->no_cfg_restore = 1;
@@ -5442,9 +5537,12 @@ dhdpcie_set_l1_entry_time(struct dhd_bus *bus, int l1_entry_time)
 
 /** Transfers bytes from host to dongle and to host again using DMA */
 static int
-dhdpcie_bus_dmaxfer_req(
-       struct  dhd_bus *bus, uint32 len, uint32 srcdelay, uint32 destdelay, uint32 d11_lpbk)
+dhdpcie_bus_dmaxfer_req(struct dhd_bus *bus,
+       uint32 len, uint32 srcdelay, uint32 destdelay,
+       uint32 d11_lpbk, uint32 core_num, uint32 wait)
 {
+       int ret = 0;
+
        if (bus->dhd == NULL) {
                DHD_ERROR(("bus not inited\n"));
                return BCME_ERROR;
@@ -5462,7 +5560,18 @@ dhdpcie_bus_dmaxfer_req(
                DHD_ERROR(("len is too small or too large\n"));
                return BCME_ERROR;
        }
-       return dhdmsgbuf_dmaxfer_req(bus->dhd, len, srcdelay, destdelay, d11_lpbk);
+
+       bus->dmaxfer_complete = FALSE;
+       ret = dhdmsgbuf_dmaxfer_req(bus->dhd, len, srcdelay, destdelay,
+               d11_lpbk, core_num);
+       if (ret != BCME_OK || !wait)
+               return ret;
+
+       ret = dhd_os_dmaxfer_wait(bus->dhd, &bus->dmaxfer_complete);
+       if (ret < 0)
+               ret = BCME_NOTREADY;
+
+       return ret;
 }
 
 
@@ -5613,6 +5722,13 @@ dhdpcie_bus_download_state(dhd_bus_t *bus, bool enter)
                                goto fail;
                        }
 
+#ifdef BCM_ASLR_HEAP
+                       /* write a random number to TCM for the purpose of
+                        * randomizing heap address space.
+                        */
+                       dhdpcie_wrt_rnd(bus);
+#endif /* BCM_ASLR_HEAP */
+
                        /* switch back to arm core again */
                        if (!(si_setcore(bus->sih, ARMCR4_CORE_ID, 0))) {
                                DHD_ERROR(("%s: Failed to find ARM CR4 core!\n", __FUNCTION__));
@@ -5692,8 +5808,10 @@ dhdpcie_bus_write_vars(dhd_bus_t *bus)
                /* Verify NVRAM bytes */
                DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize));
                nvram_ularray = (uint8*)MALLOC(bus->dhd->osh, varsize);
-               if (!nvram_ularray)
+               if (!nvram_ularray) {
+                       MFREE(bus->dhd->osh, vbuffer, varsize);
                        return BCME_NOMEM;
+               }
 
                /* Upload image to verify downloaded contents. */
                memset(nvram_ularray, 0xaa, varsize);
@@ -5756,10 +5874,10 @@ int
 dhdpcie_downloadvars(dhd_bus_t *bus, void *arg, int len)
 {
        int bcmerror = BCME_OK;
-#ifdef KEEP_JP_REGREV
+#if defined(KEEP_KR_REGREV) || defined(KEEP_JP_REGREV)
        char *tmpbuf;
        uint tmpidx;
-#endif /* KEEP_JP_REGREV */
+#endif /* KEEP_KR_REGREV || KEEP_JP_REGREV */
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -5787,8 +5905,49 @@ dhdpcie_downloadvars(dhd_bus_t *bus, void *arg, int len)
        /* Copy the passed variables, which should include the terminating double-null */
        bcopy(arg, bus->vars, bus->varsz);
 
-#ifdef KEEP_JP_REGREV
-       if (bus->vars != NULL && bus->varsz > 0) {
+#ifdef DHD_USE_SINGLE_NVRAM_FILE
+       if (dhd_bus_get_fw_mode(bus->dhd) == DHD_FLAG_MFG_MODE) {
+               char *sp = NULL;
+               char *ep = NULL;
+               int i;
+               char tag[2][8] = {"ccode=", "regrev="};
+
+               /* Find ccode and regrev info */
+               for (i = 0; i < 2; i++) {
+                       sp = strnstr(bus->vars, tag[i], bus->varsz);
+                       if (!sp) {
+                               DHD_ERROR(("%s: Could not find ccode info from the nvram %s\n",
+                                       __FUNCTION__, bus->nv_path));
+                               bcmerror = BCME_ERROR;
+                               goto err;
+                       }
+                       sp = strchr(sp, '=');
+                       ep = strchr(sp, '\0');
+                       /* We assumed that string length of both ccode and
+                        * regrev values should not exceed WLC_CNTRY_BUF_SZ
+                        */
+                       if (sp && ep && ((ep - sp) <= WLC_CNTRY_BUF_SZ)) {
+                               sp++;
+                               while (*sp != '\0') {
+                                       DHD_INFO(("%s: parse '%s', current sp = '%c'\n",
+                                               __FUNCTION__, tag[i], *sp));
+                                       *sp++ = '0';
+                               }
+                       } else {
+                               DHD_ERROR(("%s: Invalid parameter format when parsing for %s\n",
+                                       __FUNCTION__, tag[i]));
+                               bcmerror = BCME_ERROR;
+                               goto err;
+                       }
+               }
+       }
+#endif /* DHD_USE_SINGLE_NVRAM_FILE */
+
+#if defined(KEEP_KR_REGREV) || defined(KEEP_JP_REGREV)
+#ifdef DHD_USE_SINGLE_NVRAM_FILE
+       if (dhd_bus_get_fw_mode(bus->dhd) != DHD_FLAG_MFG_MODE)
+#endif /* DHD_USE_SINGLE_NVRAM_FILE */
+       {
                char *pos = NULL;
                tmpbuf = MALLOCZ(bus->dhd->osh, bus->varsz + 1);
                if (tmpbuf == NULL) {
@@ -5810,7 +5969,7 @@ dhdpcie_downloadvars(dhd_bus_t *bus, void *arg, int len)
                }
                MFREE(bus->dhd->osh, tmpbuf, bus->varsz + 1);
        }
-#endif /* KEEP_JP_REGREV */
+#endif /* KEEP_KR_REGREV || KEEP_JP_REGREV */
 
 err:
        return bcmerror;
@@ -6004,7 +6163,6 @@ void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
        int ix = 0;
        flow_ring_node_t *flow_ring_node;
        flow_info_t *flow_info;
-       char eabuf[ETHER_ADDR_STR_LEN];
 
        if (dhdp->busstate != DHD_BUS_DATA)
                return;
@@ -6051,9 +6209,9 @@ void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
 
                flow_info = &flow_ring_node->flow_info;
                bcm_bprintf(strbuf,
-                       "%3d. %4d %2d %4d %17s %4d %4d %6d %10u ", ix++,
+                       "%3d. %4d %2d %4d "MACDBG" %4d %4d %6d %10u ", ix++,
                        flow_ring_node->flowid, flow_info->ifindex, flow_info->tid,
-                       bcm_ether_ntoa((struct ether_addr *)&flow_info->da, eabuf),
+                       MAC2STRDBG(flow_info->da),
                        DHD_FLOW_QUEUE_LEN(&flow_ring_node->queue),
                        DHD_CUMM_CTR_READ(DHD_FLOW_QUEUE_CLEN_PTR(&flow_ring_node->queue)),
                        DHD_CUMM_CTR_READ(DHD_FLOW_QUEUE_L2CLEN_PTR(&flow_ring_node->queue)),
@@ -6781,7 +6939,10 @@ dhdpcie_bus_process_mailbox_intr(dhd_bus_t *bus, uint32 intstatus)
                if (intstatus & (PCIE_MB_TOPCIE_FN0_0 | PCIE_MB_TOPCIE_FN0_1))
                        bus->api.handle_mb_data(bus);
 
-               if (bus->dhd->busstate == DHD_BUS_SUSPEND) {
+               if ((bus->dhd->busstate == DHD_BUS_SUSPEND) ||
+                       (bus->use_mailbox && bus->d3_suspend_pending)) {
+                       DHD_ERROR(("%s: Bus is in power save state. "
+                               "Skip processing rest of ring buffers.\n", __FUNCTION__));
                        goto exit;
                }
 
@@ -6813,6 +6974,13 @@ dhdpci_bus_read_frames(dhd_bus_t *bus)
        /* Unlock to give chance for resp to be handled */
        DHD_PERIM_UNLOCK_ALL((bus->dhd->fwder_unit % FWDER_MAX_UNIT));
 
+       /* Do not process rest of ring buf once bus enters low power state */
+       if (!bus->use_mailbox && bus->d3_suspend_pending) {
+               DHD_ERROR(("%s: Bus is in power save state. "
+                       "Skip processing rest of ring buffers.\n", __FUNCTION__));
+               return FALSE;
+       }
+
        DHD_PERIM_LOCK_ALL((bus->dhd->fwder_unit % FWDER_MAX_UNIT));
        /* update the flow ring cpls */
        dhd_update_txflowrings(bus->dhd);
@@ -6961,6 +7129,11 @@ dhdpcie_readshared(dhd_bus_t *bus)
                DHD_ERROR(("%s: address (0x%08x) of pciedev_shared invalid\n",
                        __FUNCTION__, addr));
                DHD_ERROR(("Waited %u usec, dongle is not ready\n", tmo.elapsed));
+#ifdef DEBUG_DNGL_INIT_FAIL
+               bus->dhd->memdump_enabled = DUMP_MEMFILE_BUGON;
+               bus->dhd->memdump_type = DUMP_TYPE_DONGLE_INIT_FAILURE;
+               dhdpcie_mem_dump(bus);
+#endif /* DEBUG_DNGL_INIT_FAIL */
                return BCME_ERROR;
        } else {
                bus->shared_addr = (ulong)addr;
@@ -7080,6 +7253,7 @@ dhdpcie_readshared(dhd_bus_t *bus)
                        bus->max_completion_rings = BCMPCIE_D2H_COMMON_MSGRINGS;
                        bus->max_cmn_rings = BCMPCIE_H2D_COMMON_MSGRINGS;
                        bus->api.handle_mb_data = dhdpcie_handle_mb_data;
+                       bus->use_mailbox = TRUE;
                }
                if (bus->max_completion_rings == 0) {
                        DHD_ERROR(("dongle completion rings are invalid %d\n",
@@ -7312,7 +7486,7 @@ int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
        dhdp->busstate = DHD_BUS_DATA;
        bus->d3_suspend_pending = FALSE;
 
-#ifdef DBG_PKT_MON
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
        if (bus->pcie_sh->flags2 & PCIE_SHARED_D2H_D11_TX_STATUS) {
                uint32 flags2 = bus->pcie_sh->flags2;
                uint32 addr;
@@ -7329,7 +7503,7 @@ int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
                bus->pcie_sh->flags2 = flags2;
                bus->dhd->d11_tx_status = TRUE;
        }
-#endif /* DBG_PKT_MON */
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
 
        if (!dhd_download_fw_on_driverload)
                dhd_dpc_enable(bus->dhd);
@@ -7781,6 +7955,12 @@ dhd_bus_flow_ring_delete_request(dhd_bus_t *bus, void *arg)
 
        flow_ring_node = (flow_ring_node_t *)arg;
 
+#ifdef DHDTCPACK_SUPPRESS
+       /* Clean tcp_ack_info_tbl in order to prevent access to flushed pkt,
+        * when there is a newly coming packet from network stack.
+        */
+       dhd_tcpack_info_tbl_clean(bus->dhd);
+#endif /* DHDTCPACK_SUPPRESS */
        DHD_FLOWRING_LOCK(flow_ring_node->lock, flags);
        if (flow_ring_node->status == FLOW_RING_STATUS_DELETE_PENDING) {
                DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags);
@@ -7791,12 +7971,6 @@ dhd_bus_flow_ring_delete_request(dhd_bus_t *bus, void *arg)
 
        queue = &flow_ring_node->queue; /* queue associated with flow ring */
 
-#ifdef DHDTCPACK_SUPPRESS
-       /* Clean tcp_ack_info_tbl in order to prevent access to flushed pkt,
-        * when there is a newly coming packet from network stack.
-        */
-       dhd_tcpack_info_tbl_clean(bus->dhd);
-#endif /* DHDTCPACK_SUPPRESS */
        /* Flush all pending packets in the queue, if any */
        while ((pkt = dhd_flow_queue_dequeue(bus->dhd, queue)) != NULL) {
                PKTFREE(bus->dhd->osh, pkt, TRUE);
@@ -8839,3 +9013,44 @@ dhdpcie_sssr_dump(dhd_pub_t *dhd)
        return BCME_OK;
 }
 #endif /* DHD_SSSR_DUMP */
+
+#ifdef DHD_WAKE_STATUS
+wake_counts_t*
+dhd_bus_get_wakecount(dhd_pub_t *dhd)
+{
+       if (!dhd->bus) {
+               return NULL;
+       }
+       return &dhd->bus->wake_counts;
+}
+int
+dhd_bus_get_bus_wake(dhd_pub_t *dhd)
+{
+       return bcmpcie_set_get_wake(dhd->bus, 0);
+}
+#endif /* DHD_WAKE_STATUS */
+
+#ifdef BCM_ASLR_HEAP
+/* Writes random number(s) to the TCM. FW upon initialization reads the metadata
+ * of the random number and then based on metadata, reads the random number from the TCM.
+ */
+static void
+dhdpcie_wrt_rnd(struct dhd_bus *bus)
+{
+       bcm_rand_metadata_t rnd_data;
+       uint32 rand_no;
+       uint32 count = 1;       /* start with 1 random number */
+
+       uint32 addr = bus->dongle_ram_base + (bus->ramsize - BCM_NVRAM_OFFSET_TCM) -
+               ((bus->nvram_csm & 0xffff)* BCM_NVRAM_IMG_COMPRS_FACTOR + sizeof(rnd_data));
+       rnd_data.signature = htol32(BCM_RNG_SIGNATURE);
+       rnd_data.count = htol32(count);
+       /* write the metadata about random number */
+       dhdpcie_bus_membytes(bus, TRUE, addr, (uint8 *)&rnd_data, sizeof(rnd_data));
+       /* scale back by number of random number counts */
+       addr -= sizeof(count) * count;
+       /* Now write the random number(s) */
+       rand_no = htol32(dhd_get_random_number());
+       dhdpcie_bus_membytes(bus, TRUE, addr, (uint8 *)&rand_no, sizeof(rand_no));
+}
+#endif /* BCM_ASLR_HEAP */
index b9385b9b830d54ddc2230429f9bd470271bbd12d..912055c51dc37ba43fab044cb12257b0a6d853a9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux DHD Bus Module for PCIE
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_pcie.h 680277 2017-01-19 08:21:55Z $
+ * $Id: dhd_pcie.h 727682 2017-10-23 04:45:57Z $
  */
 
 
@@ -385,9 +385,13 @@ typedef struct dhd_bus {
        ulong dpc_return_busdown_count;
        bool  idma_enabled;
        bool  ifrm_enabled;
+       uint32 dmaxfer_complete;
 #if defined(PCIE_OOB) || defined(PCIE_INB_DW)
        bool  ds_enabled;
 #endif
+#ifdef DHD_PCIE_RUNTIMEPM
+       bool chk_pm;    /* To avoid counting of wake up from Runtime PM */
+#endif /* DHD_PCIE_RUNTIMEPM */
 } dhd_bus_t;
 
 /* function declarations */
index ae586c7613caed85b50185e4a07b87f37f508628..22030cb661b4615b2e84f228227a8c94fe4fe21c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux DHD Bus Module for PCIE
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_pcie_linux.c 688366 2017-03-06 06:58:55Z $
+ * $Id: dhd_pcie_linux.c 737516 2017-12-21 08:20:40Z $
  */
 
 
@@ -272,6 +272,15 @@ static int dhdpcie_smmu_init(struct pci_dev *pdev, void *smmu_cxt)
        }
 
        DHD_ERROR(("%s : SMMU init start\n", __FUNCTION__));
+
+#ifdef SET_DMA_MASK_64BIT
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) ||
+               pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
+               DHD_ERROR(("%s: DMA set 64bit mask failed.\n", __FUNCTION__));
+               return -EINVAL;
+       }
+#endif /* SET_DMA_MASK_64BIT */
+
        mapping = arm_iommu_create_mapping(&platform_bus_type,
                smmu_info->smmu_iova_start, smmu_info->smmu_iova_len);
        if (IS_ERR(mapping)) {
@@ -381,6 +390,7 @@ static int dhdpcie_pm_prepare(struct device *dev)
                DHD_DISABLE_RUNTIME_PM(bus->dhd);
        }
 
+       bus->chk_pm = TRUE;
        return 0;
 }
 
@@ -403,8 +413,10 @@ static int dhdpcie_pm_resume(struct device *dev)
        DHD_BUS_BUSY_SET_RESUME_IN_PROGRESS(bus->dhd);
        DHD_GENERAL_UNLOCK(bus->dhd, flags);
 
-       if (!bus->dhd->dongle_reset)
+       if (!bus->dhd->dongle_reset) {
                ret = dhdpcie_set_suspend_resume(bus, FALSE);
+               bus->chk_pm = FALSE;
+       }
 
        DHD_GENERAL_LOCK(bus->dhd, flags);
        DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(bus->dhd);
@@ -1024,6 +1036,12 @@ dhdpcie_get_pcieirq(struct dhd_bus *bus, unsigned int *irq)
 #define PRINTF_RESOURCE        "0x%08x"
 #endif
 
+#ifdef EXYNOS_PCIE_MODULE_PATCH
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+extern struct pci_saved_state *bcm_pcie_default_state;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
+#endif /* EXYNOS_MODULE_PATCH */
+
 /*
 
 Name:  osl_pci_get_resource
@@ -1049,7 +1067,12 @@ int dhdpcie_get_resource(dhdpcie_info_t *dhdpcie_info)
        struct pci_dev *pdev = NULL;
        pdev = dhdpcie_info->dev;
 #ifdef EXYNOS_PCIE_MODULE_PATCH
-       pci_restore_state(pdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+       if (bcm_pcie_default_state) {
+               pci_load_saved_state(pdev, bcm_pcie_default_state);
+               pci_restore_state(pdev);
+       }
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
 #endif /* EXYNOS_MODULE_PATCH */
        do {
                if (pci_enable_device(pdev)) {
@@ -1079,6 +1102,14 @@ int dhdpcie_get_resource(dhdpcie_info_t *dhdpcie_info)
                        DHD_ERROR(("%s:ioremap() failed\n", __FUNCTION__));
                        break;
                }
+#ifdef EXYNOS_PCIE_MODULE_PATCH
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+               if (bcm_pcie_default_state == NULL) {
+                       pci_save_state(pdev);
+                       bcm_pcie_default_state = pci_store_saved_state(pdev);
+               }
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
+#endif /* EXYNOS_MODULE_PATCH */
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
                if (!dhd_download_fw_on_driverload) {
@@ -1099,10 +1130,6 @@ int dhdpcie_get_resource(dhdpcie_info_t *dhdpcie_info)
                }
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
 
-#ifdef EXYNOS_PCIE_MODULE_PATCH
-               pci_save_state(pdev);
-#endif /* EXYNOS_MODULE_PATCH */
-
                DHD_TRACE(("%s:Phys addr : reg space = %p base addr 0x"PRINTF_RESOURCE" \n",
                        __FUNCTION__, dhdpcie_info->regs, bar0_addr));
                DHD_TRACE(("%s:Phys addr : tcm_space = %p base addr 0x"PRINTF_RESOURCE" \n",
@@ -1257,6 +1284,11 @@ int dhdpcie_init(struct pci_dev *pdev)
                }
 #endif /* USE_SMMU_ARCH_MSM */
 
+#ifdef DHD_WAKE_STATUS
+               /* Initialize pcie_lock */
+               spin_lock_init(&dhdpcie_info->pcie_lock);
+#endif /* DHD_WAKE_STATUS */
+
                /* Find the PCI resources, verify the  */
                /* vendor and device ID, map BAR regions and irq,  update in structures */
                if (dhdpcie_scan_resource(dhdpcie_info)) {
@@ -1432,10 +1464,11 @@ irqreturn_t
 dhdpcie_isr(int irq, void *arg)
 {
        dhd_bus_t *bus = (dhd_bus_t*)arg;
-       if (dhdpcie_bus_isr(bus))
-               return TRUE;
-       else
-               return FALSE;
+
+       if (!dhdpcie_bus_isr(bus)) {
+               DHD_TRACE(("%s: dhdpcie_bus_isr returns with FALSE\n", __FUNCTION__));
+       }
+       return IRQ_HANDLED;
 }
 
 int
@@ -1828,6 +1861,15 @@ static irqreturn_t wlan_oob_irq(int irq, void *data)
        DHD_TRACE(("%s: IRQ Triggered\n", __FUNCTION__));
        bus = (dhd_bus_t *)data;
        dhdpcie_oob_intr_set(bus, FALSE);
+#ifdef DHD_WAKE_STATUS
+#ifdef DHD_PCIE_RUNTIMEPM
+       /* This condition is for avoiding counting of wake up from Runtime PM */
+       if (bus->chk_pm)
+#endif /* DHD_PCIE_RUNTIMPM */
+       {
+               bcmpcie_set_get_wake(bus, 1);
+       }
+#endif /* DHD_WAKE_STATUS */
 #ifdef DHD_PCIE_RUNTIMEPM
        dhdpcie_runtime_bus_wake(bus->dhd, FALSE, wlan_oob_irq);
 #endif /* DHD_PCIE_RUNTIMPM */
diff --git a/drivers/net/wireless/bcmdhd_1_77/dhd_pktlog.c b/drivers/net/wireless/bcmdhd_1_77/dhd_pktlog.c
new file mode 100644 (file)
index 0000000..6883b26
--- /dev/null
@@ -0,0 +1,1260 @@
+/*
+ * DHD debugability packet logging support
+ *
+ * Copyright (C) 1999-2018, Broadcom Corporation
+ * 
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ * 
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ * 
+ *      Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: dhd_pktlog.c 742382 2018-01-22 01:56:53Z $
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_pktlog.h>
+
+#ifdef DHD_PKT_LOGGING
+#ifndef strtoul
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#endif
+extern int wl_pattern_atoh(char *src, char *dst);
+extern uint32 __dhd_dbg_pkt_hash(uintptr_t pkt, uint32 pktid);
+extern wifi_tx_packet_fate __dhd_dbg_map_tx_status_to_pkt_fate(uint16 status);
+
+int
+dhd_os_attach_pktlog(dhd_pub_t *dhdp)
+{
+       gfp_t kflags;
+       uint32 alloc_len;
+       dhd_pktlog_t *pktlog;
+
+       if (!dhdp) {
+               DHD_ERROR(("%s(): dhdp is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+
+       alloc_len = sizeof(dhd_pktlog_t);
+       pktlog = (dhd_pktlog_t *)kzalloc(alloc_len, kflags);
+       if (unlikely(!pktlog)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "dhd_pktlog_t\n", __FUNCTION__));
+               goto fail;
+       }
+
+       dhdp->pktlog = pktlog;
+
+       dhdp->pktlog->tx_pktlog_ring = dhd_pktlog_ring_init(dhdp, MIN_PKTLOG_LEN);
+       dhdp->pktlog->rx_pktlog_ring = dhd_pktlog_ring_init(dhdp, MIN_PKTLOG_LEN);
+       dhdp->pktlog->pktlog_filter = dhd_pktlog_filter_init(MAX_DHD_PKTLOG_FILTER_LEN);
+
+       DHD_ERROR(("%s(): dhd_os_attach_pktlog attach\n", __FUNCTION__));
+
+       return BCME_OK;
+fail:
+       if (pktlog) {
+               kfree(pktlog);
+       }
+
+       return BCME_ERROR;
+}
+
+int
+dhd_os_detach_pktlog(dhd_pub_t *dhdp)
+{
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       dhd_pktlog_ring_deinit(dhdp->pktlog->tx_pktlog_ring);
+       dhd_pktlog_ring_deinit(dhdp->pktlog->rx_pktlog_ring);
+       dhd_pktlog_filter_deinit(dhdp->pktlog->pktlog_filter);
+
+       DHD_ERROR(("%s(): dhd_os_attach_pktlog detach\n", __FUNCTION__));
+
+       kfree(dhdp->pktlog);
+
+       return BCME_OK;
+}
+
+dhd_pktlog_ring_t*
+dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size)
+{
+       gfp_t kflags;
+       uint32 alloc_len;
+       dhd_pktlog_ring_t *ring;
+       dhd_pktlog_ring_info_t *ring_info = NULL;
+
+       if (!dhdp) {
+               DHD_ERROR(("%s(): dhdp is NULL\n", __FUNCTION__));
+               return NULL;
+       }
+
+       kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+
+       alloc_len = sizeof(dhd_pktlog_ring_t);
+       ring = (dhd_pktlog_ring_t *)kzalloc(alloc_len, kflags);
+       if (unlikely(!ring)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "dhd_pktlog_ring_t\n", __FUNCTION__));
+               goto fail;
+       }
+
+       alloc_len = (sizeof(dhd_pktlog_ring_info_t) * size);
+       ring_info = (dhd_pktlog_ring_info_t *)kzalloc(alloc_len, kflags);
+       if (unlikely(!ring_info)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "dhd_pktlog_ring_info_t\n", __FUNCTION__));
+               goto fail;
+       }
+
+       ring->pktlog_ring_info = ring_info;
+
+       ring->front = 0;
+       ring->rear = 0;
+       ring->prev_pos = 0;
+       ring->next_pos = 0;
+
+       ring->start = TRUE;
+       ring->pktlog_minmize = FALSE;
+       ring->pktlog_len = size;
+       ring->dhdp = dhdp;
+
+       DHD_ERROR(("%s(): pktlog ring init success\n", __FUNCTION__));
+
+       return ring;
+fail:
+       if (ring_info) {
+               kfree(ring_info);
+       }
+
+       if (ring) {
+               kfree(ring);
+       }
+
+       return NULL;
+}
+
+int
+dhd_pktlog_ring_deinit(dhd_pktlog_ring_t *ring)
+{
+       int ret = BCME_OK;
+       void *data = NULL;
+       dhd_pktlog_ring_info_t *ring_info;
+
+       if (!ring) {
+               DHD_ERROR(("%s(): ring is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       if (!ring->dhdp) {
+               DHD_ERROR(("%s(): dhdp is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       /* stop pkt log */
+       ring->start = FALSE;
+
+       /* free ring_info->info.pkt */
+       if (dhd_pktlog_ring_set_nextpos(ring) == BCME_OK) {
+               while (dhd_pktlog_ring_get_nextbuf(ring, &data) == BCME_OK) {
+                       ring_info = (dhd_pktlog_ring_info_t *)data;
+
+                       if (ring_info && ring_info->info.pkt) {
+                               PKTFREE(ring->dhdp->osh, ring_info->info.pkt, TRUE);
+                               DHD_PKT_LOG(("%s(): pkt free pos %d\n",
+                                       __FUNCTION__, ring->next_pos));
+                               ring_info->info.pkt = NULL;
+                       }
+               }
+       }
+
+       if (ring->pktlog_ring_info) {
+               kfree(ring->pktlog_ring_info);
+       }
+       kfree(ring);
+
+       DHD_ERROR(("%s(): pktlog ring deinit\n", __FUNCTION__));
+
+       return ret;
+}
+
+int
+dhd_pktlog_ring_set_nextpos(dhd_pktlog_ring_t *ringbuf)
+{
+       if  (!ringbuf) {
+               DHD_ERROR(("%s(): ringbuf is  NULL\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       /* ring buffer is empty */
+       if (ringbuf->front ==  ringbuf->rear) {
+               DHD_ERROR(("%s(): ringbuf empty\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       ringbuf->next_pos = ringbuf->front;
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_get_nextbuf(dhd_pktlog_ring_t *ringbuf, void **data)
+{
+       dhd_pktlog_ring_info_t *ring_info;
+
+       if  (!ringbuf || !data) {
+               DHD_PKT_LOG(("%s(): ringbuf=%p data=%p\n",
+                       __FUNCTION__, ringbuf, data));
+               return BCME_ERROR;
+       }
+
+       /* ring buffer is empty */
+       if (ringbuf->front ==  ringbuf->rear) {
+               DHD_PKT_LOG(("%s(): ringbuf empty\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       if (ringbuf->next_pos == ringbuf->rear) {
+               DHD_PKT_LOG(("%s(): ringbuf next pos %d is rear\n",
+                       __FUNCTION__, ringbuf->next_pos));
+               return BCME_ERROR;
+       }
+
+       DHD_PKT_LOG(("%s(): ringbuf next pos %d\n", __FUNCTION__, ringbuf->next_pos));
+
+       *data = ((dhd_pktlog_ring_info_t *)ringbuf->pktlog_ring_info) + ringbuf->next_pos;
+       ring_info = (dhd_pktlog_ring_info_t *)*data;
+
+       if (*data == NULL) {
+               DHD_PKT_LOG(("%s(): next_pos %d data NULL\n",
+                       __FUNCTION__, ringbuf->next_pos));
+               return BCME_ERROR;
+       }
+
+       if (!ring_info->info.pkt) {
+               DHD_ERROR(("%s(): next_pos %d info.pkt NULL\n",
+                       __FUNCTION__, ringbuf->next_pos));
+               return BCME_ERROR;
+       }
+
+       ringbuf->next_pos = (ringbuf->next_pos + 1) % ringbuf->pktlog_len;
+
+       DHD_PKT_LOG(("%s(): ringbuf next next pos %d\n",
+               __FUNCTION__, ringbuf->next_pos));
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_set_prevpos(dhd_pktlog_ring_t *ringbuf)
+{
+       if  (!ringbuf) {
+               DHD_PKT_LOG(("%s(): ringbuf is NULL\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       /* ring buffer is empty */
+       if (ringbuf->front ==  ringbuf->rear) {
+               DHD_PKT_LOG(("%s(): ringbuf empty\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       ringbuf->prev_pos = (ringbuf->rear + ringbuf->pktlog_len - 1) % ringbuf->pktlog_len;
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_get_prevbuf(dhd_pktlog_ring_t *ringbuf, void **data)
+{
+       if  (!ringbuf || !data) {
+               DHD_PKT_LOG(("%s(): ringbuf=%p data=%p\n",
+                       __FUNCTION__, ringbuf, data));
+               return BCME_ERROR;
+       }
+
+       /* ring buffer is empty */
+       if (ringbuf->front ==  ringbuf->rear) {
+               DHD_PKT_LOG(("%s(): ringbuf empty\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       if (ringbuf->prev_pos == ringbuf->front) {
+               DHD_PKT_LOG(("%s(): ringbuf prev pos %d is front\n",
+                       __FUNCTION__, ringbuf->prev_pos));
+               if (ringbuf->front == 0 && ringbuf->rear == 1) {
+                       *data = ((dhd_pktlog_ring_info_t *)ringbuf->pktlog_ring_info)
+                               + ringbuf->front;
+                       if (*data == NULL) {
+                               DHD_PKT_LOG(("%s(): front %d data NULL\n",
+                                       __FUNCTION__, ringbuf->prev_pos));
+                               return BCME_ERROR;
+                       } else {
+                               DHD_PKT_LOG(("%s(): ringbuf front data\n", __FUNCTION__));
+                               return BCME_OK;
+                       }
+               } else {
+                       return BCME_ERROR;
+               }
+       }
+
+       DHD_PKT_LOG(("%s(): ringbuf prev pos %d\n", __FUNCTION__, ringbuf->prev_pos));
+
+       *data = ((dhd_pktlog_ring_info_t *)ringbuf->pktlog_ring_info) + ringbuf->prev_pos;
+
+       if (*data == NULL) {
+               DHD_PKT_LOG(("%s(): prev_pos %d data NULL\n",
+                       __FUNCTION__, ringbuf->prev_pos));
+               return BCME_ERROR;
+       }
+
+       ringbuf->prev_pos  = (ringbuf->prev_pos + ringbuf->pktlog_len - 1) % ringbuf->pktlog_len;
+
+       DHD_PKT_LOG(("%s(): ringbuf next prev pos %d\n", __FUNCTION__, ringbuf->prev_pos));
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_get_writebuf(dhd_pktlog_ring_t *ringbuf, void **data)
+{
+       dhd_pktlog_ring_info_t *ring_info;
+       uint16 write_pos = 0;
+       uint16 next_write_pos = 0;
+
+       if  (!ringbuf || !data) {
+               DHD_PKT_LOG(("%s(): ringbuf=%p data=%p\n",
+                       __FUNCTION__, ringbuf, data));
+               return BCME_ERROR;
+       }
+
+       write_pos = ringbuf->rear;
+       next_write_pos = (ringbuf->rear + 1) % ringbuf->pktlog_len;
+       *data = ((dhd_pktlog_ring_info_t *)ringbuf->pktlog_ring_info) + write_pos;
+       if (*data == NULL) {
+               DHD_PKT_LOG(("%s(): write_pos %d data NULL\n", __FUNCTION__, write_pos));
+               return BCME_ERROR;
+       }
+
+       /* ringbuf is Full */
+       if (ringbuf->front == next_write_pos) {
+               DHD_PKT_LOG(("%s(): ringbuf full next write %d front %d\n",
+                       __FUNCTION__, next_write_pos, ringbuf->front));
+               /* Free next write buffer */
+               ring_info = ((dhd_pktlog_ring_info_t *)ringbuf->pktlog_ring_info) + next_write_pos;
+               if (ring_info && ring_info->info.pkt) {
+                       PKTFREE(ringbuf->dhdp->osh, ring_info->info.pkt, TRUE);
+                       DHD_PKT_LOG(("%s(): ringbuf full next write %d pkt free\n",
+                               __FUNCTION__, next_write_pos));
+               }
+               ringbuf->front = (ringbuf->front + 1) % ringbuf->pktlog_len;
+       }
+
+       ringbuf->rear = next_write_pos;
+
+       DHD_PKT_LOG(("%s(): next write pos %d front %d \n",
+               __FUNCTION__, next_write_pos, ringbuf->front));
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid)
+{
+       dhd_pktlog_ring_info_t *tx_pkts;
+       uint32 pkt_hash;
+       void *data = NULL;
+       uint8 *pktdata = NULL;
+       dhd_pktlog_ring_t *tx_pktlog_ring;
+       dhd_pktlog_filter_t *pktlog_filter;
+       u64 ts_nsec;
+       unsigned long rem_nsec;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       tx_pktlog_ring = dhdp->pktlog->tx_pktlog_ring;
+
+       if (!tx_pktlog_ring->start) {
+               return BCME_OK;
+       }
+
+       pktlog_filter = dhdp->pktlog->pktlog_filter;
+
+       pktdata = (uint8 *)PKTDATA(dhdp->osh, pkt);
+       if (dhd_pktlog_filter_matched(pktlog_filter, pktdata, PKTLOG_TXPKT_CASE)
+                       == FALSE) {
+               return BCME_OK;
+       }
+
+       tx_pktlog_ring->dhdp = dhdp;
+       if (dhd_pktlog_ring_get_writebuf(tx_pktlog_ring, &data)
+                       == BCME_OK) {
+               tx_pkts = (dhd_pktlog_ring_info_t *)data;
+               DHD_PKT_LOG(("%s(): write buf %p\n", __FUNCTION__, tx_pkts));
+               pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
+               ts_nsec = local_clock();
+               rem_nsec = do_div(ts_nsec, NSEC_PER_SEC);
+
+               tx_pkts->info.pkt = PKTDUP(dhdp->osh, pkt);
+               tx_pkts->info.pkt_len = PKTLEN(dhdp->osh, pkt);
+               tx_pkts->info.pkt_hash = pkt_hash;
+               tx_pkts->info.driver_ts_sec = (uint32)ts_nsec;
+               tx_pkts->info.driver_ts_usec = (uint32)(rem_nsec / NSEC_PER_USEC);
+               tx_pkts->info.firmware_ts = 0U;
+               tx_pkts->info.payload_type = FRAME_TYPE_ETHERNET_II;
+               tx_pkts->tx_fate = TX_PKT_FATE_DRV_QUEUED;
+               DHD_PKT_LOG(("%s(): pkt hash %d\n", __FUNCTION__, tx_pkts->info.pkt_hash));
+               DHD_PKT_LOG(("%s(): sec %d usec %d\n", __FUNCTION__,
+                       tx_pkts->info.driver_ts_sec, tx_pkts->info.driver_ts_usec));
+       } else {
+               DHD_PKT_LOG(("%s(): Can't get write pos\n", __FUNCTION__));
+       }
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+               uint16 status)
+{
+       dhd_pktlog_ring_info_t *tx_pkt;
+       wifi_tx_packet_fate pkt_fate;
+       uint32 pkt_hash, temp_hash;
+       void *data = NULL;
+       uint8 *pktdata = NULL;
+       dhd_pktlog_ring_t *tx_pktlog_ring;
+       dhd_pktlog_filter_t *pktlog_filter;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       tx_pktlog_ring = dhdp->pktlog->tx_pktlog_ring;
+
+       if (!tx_pktlog_ring->start) {
+               return BCME_OK;
+       }
+
+       pktlog_filter = dhdp->pktlog->pktlog_filter;
+
+       pktdata = (uint8 *)PKTDATA(dhdp->osh, pkt);
+       if (dhd_pktlog_filter_matched(pktlog_filter, pktdata,
+               PKTLOG_TXSTATUS_CASE) == FALSE) {
+               return BCME_OK;
+       }
+
+       pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
+       pkt_fate = __dhd_dbg_map_tx_status_to_pkt_fate(status);
+
+       if (dhd_pktlog_ring_set_prevpos(tx_pktlog_ring) != BCME_OK) {
+               DHD_PKT_LOG(("%s(): fail set prev pos\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       while (dhd_pktlog_ring_get_prevbuf(tx_pktlog_ring, &data)
+                       == BCME_OK) {
+               DHD_PKT_LOG(("%s(): prev status_pos %p\n", __FUNCTION__, data));
+               tx_pkt = (dhd_pktlog_ring_info_t *)data;
+               temp_hash = tx_pkt->info.pkt_hash;
+               if (temp_hash == pkt_hash) {
+                       tx_pkt->tx_fate = pkt_fate;
+                       DHD_PKT_LOG(("%s(): Found pkt hash in prev pos\n", __FUNCTION__));
+                       break;
+               }
+       }
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_ring_rx_pkts(dhd_pub_t *dhdp, void *pkt)
+{
+       dhd_pktlog_ring_info_t *rx_pkts;
+       void *data = NULL;
+       uint8 *pktdata = NULL;
+       dhd_pktlog_ring_t *rx_pktlog_ring;
+       dhd_pktlog_filter_t *pktlog_filter;
+       u64 ts_nsec;
+       unsigned long rem_nsec;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->rx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): rx_pktlog_ring is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       rx_pktlog_ring = dhdp->pktlog->rx_pktlog_ring;
+
+       if (!rx_pktlog_ring->start) {
+               return BCME_OK;
+       }
+
+       pktlog_filter = dhdp->pktlog->pktlog_filter;
+
+       pktdata = (uint8 *)PKTDATA(dhdp->osh, pkt);
+       if (dhd_pktlog_filter_matched(pktlog_filter, pktdata, PKTLOG_RXPKT_CASE)
+                       == FALSE) {
+               return BCME_OK;
+       }
+
+       rx_pktlog_ring->dhdp = dhdp;
+       if (dhd_pktlog_ring_get_writebuf(rx_pktlog_ring, &data)
+                       == BCME_OK) {
+               rx_pkts = (dhd_pktlog_ring_info_t *)data;
+               DHD_PKT_LOG(("%s(): write buf %p\n", __FUNCTION__, rx_pkts));
+               ts_nsec = local_clock();
+               rem_nsec = do_div(ts_nsec, NSEC_PER_SEC);
+
+               rx_pkts->info.pkt = PKTDUP(dhdp->osh, pkt);
+               rx_pkts->info.pkt_len = PKTLEN(dhdp->osh, pkt);
+               rx_pkts->info.pkt_hash = 0U;
+               rx_pkts->info.driver_ts_sec = (uint32)ts_nsec;
+               rx_pkts->info.driver_ts_usec = (uint32)(rem_nsec / NSEC_PER_USEC);
+               rx_pkts->info.firmware_ts = 0U;
+               rx_pkts->info.payload_type = FRAME_TYPE_ETHERNET_II;
+               rx_pkts->rx_fate = RX_PKT_FATE_SUCCESS;
+               DHD_PKT_LOG(("%s(): sec %d usec %d\n", __FUNCTION__,
+                       rx_pkts->info.driver_ts_sec, rx_pkts->info.driver_ts_usec));
+       } else {
+               DHD_PKT_LOG(("%s(): Can't get write pos\n", __FUNCTION__));
+       }
+
+       return BCME_OK;
+}
+
+dhd_pktlog_filter_t*
+dhd_pktlog_filter_init(int size)
+{
+       int i;
+       gfp_t kflags;
+       uint32 alloc_len;
+       dhd_pktlog_filter_t *filter;
+       dhd_pktlog_filter_info_t *filter_info = NULL;
+
+       kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+
+       /* allocate and initialze pktmon filter */
+       alloc_len = sizeof(dhd_pktlog_filter_t);
+       filter = (dhd_pktlog_filter_t *)kzalloc(alloc_len, kflags);
+       if (unlikely(!filter)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "dhd_pktlog_filter_t\n", __FUNCTION__));
+               goto fail;
+       }
+
+       alloc_len = (sizeof(dhd_pktlog_filter_info_t) * size);
+       filter_info = (dhd_pktlog_filter_info_t *)kzalloc(alloc_len, kflags);
+       if (unlikely(!filter_info)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "dhd_pktlog_filter_info_t\n", __FUNCTION__));
+               goto fail;
+       }
+
+       filter->info = filter_info;
+       filter->list_cnt = 0;
+
+       for (i = 0; i < MAX_DHD_PKTLOG_FILTER_LEN; i++) {
+               filter->info[i].id = 0;
+       }
+
+       filter->enable = PKTLOG_TXPKT_CASE | PKTLOG_TXSTATUS_CASE | PKTLOG_RXPKT_CASE;
+
+       DHD_ERROR(("%s(): pktlog filter init success\n", __FUNCTION__));
+
+       return filter;
+fail:
+       if (filter_info) {
+               kfree(filter_info);
+       }
+
+       if (filter) {
+               kfree(filter);
+       }
+
+       return NULL;
+}
+
+int
+dhd_pktlog_filter_deinit(dhd_pktlog_filter_t *filter)
+{
+       int ret = BCME_OK;
+
+       if (!filter) {
+               DHD_ERROR(("%s(): filter is NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
+
+       if (filter->info) {
+               kfree(filter->info);
+       }
+       kfree(filter);
+
+       DHD_ERROR(("%s(): pktlog filter deinit\n", __FUNCTION__));
+
+       return ret;
+}
+
+bool
+dhd_pktlog_filter_existed(dhd_pktlog_filter_t *filter, char *arg, uint32 *id)
+{
+       char filter_pattern[MAX_FILTER_PATTERN_LEN];
+       char *p;
+       int i, j;
+       int nchar;
+       int len;
+
+       if  (!filter || !arg) {
+               DHD_ERROR(("%s(): filter=%p arg=%p\n", __FUNCTION__, filter, arg));
+               return TRUE;
+       }
+
+       for (i = 0; i < filter->list_cnt; i++) {
+               p = filter_pattern;
+               len = sizeof(filter_pattern);
+
+               nchar = snprintf(p, len, "%d ", filter->info[i].offset);
+               p += nchar;
+               len -= nchar;
+
+               nchar = snprintf(p, len, "0x");
+               p += nchar;
+               len -= nchar;
+
+               for (j = 0; j < filter->info[i].size_bytes; j++) {
+                       nchar = snprintf(p, len, "%02x", filter->info[i].mask[j]);
+                       p += nchar;
+                       len -= nchar;
+               }
+
+               nchar = snprintf(p, len, " 0x");
+               p += nchar;
+               len -= nchar;
+
+               for (j = 0; j < filter->info[i].size_bytes; j++) {
+                       nchar = snprintf(p, len, "%02x", filter->info[i].pattern[j]);
+                       p += nchar;
+                       len -= nchar;
+               }
+
+               DHD_PKT_LOG(("%s(): Pattern %s\n", __FUNCTION__, filter_pattern));
+
+               if (strncmp(filter_pattern, arg, strlen(filter_pattern)) == 0) {
+                       *id = filter->info[i].id;
+                       DHD_ERROR(("%s(): This pattern is existed\n", __FUNCTION__));
+                       DHD_ERROR(("%s(): arg %s\n", __FUNCTION__, arg));
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+int
+dhd_pktlog_filter_add(dhd_pktlog_filter_t *filter, char *arg)
+{
+       int32 mask_size, pattern_size;
+       char *offset, *bitmask, *pattern;
+       uint32 id = 0;
+
+       if  (!filter || !arg) {
+               DHD_ERROR(("%s(): pktlog_filter =%p arg =%p\n", __FUNCTION__, filter, arg));
+               return BCME_ERROR;
+       }
+
+       DHD_PKT_LOG(("%s(): arg %s\n", __FUNCTION__, arg));
+
+       if (dhd_pktlog_filter_existed(filter, arg, &id) == TRUE) {
+               DHD_PKT_LOG(("%s(): This pattern id %d is existed\n", __FUNCTION__, id));
+               return BCME_OK;
+       }
+
+       if (filter->list_cnt >= MAX_DHD_PKTLOG_FILTER_LEN) {
+               DHD_ERROR(("%s(): pktlog filter full\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       if ((offset = bcmstrtok(&arg, " ", 0)) == NULL) {
+               DHD_ERROR(("%s(): offset not found\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       if ((bitmask = bcmstrtok(&arg, " ", 0)) == NULL) {
+               DHD_ERROR(("%s(): bitmask not found\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       if ((pattern = bcmstrtok(&arg, " ", 0)) == NULL) {
+               DHD_ERROR(("%s(): pattern not found\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       /* parse filter bitmask */
+       mask_size = wl_pattern_atoh(bitmask,
+                       (char *) &filter->info[filter->list_cnt].mask[0]);
+       if (mask_size == -1) {
+               DHD_ERROR(("Rejecting: %s\n", bitmask));
+               return BCME_ERROR;
+       }
+
+       /* parse filter pattern */
+       pattern_size = wl_pattern_atoh(pattern,
+                       (char *) &filter->info[filter->list_cnt].pattern[0]);
+       if (pattern_size == -1) {
+               DHD_ERROR(("Rejecting: %s\n", pattern));
+               return BCME_ERROR;
+       }
+
+       prhex("mask", (char *)&filter->info[filter->list_cnt].mask[0],
+                       mask_size);
+       prhex("pattern", (char *)&filter->info[filter->list_cnt].pattern[0],
+                       pattern_size);
+
+       if (mask_size != pattern_size) {
+               DHD_ERROR(("%s(): Mask and pattern not the same size\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       filter->info[filter->list_cnt].offset = strtoul(offset, NULL, 0);
+       filter->info[filter->list_cnt].size_bytes = mask_size;
+       filter->info[filter->list_cnt].id = filter->list_cnt + 1;
+       filter->info[filter->list_cnt].enable = TRUE;
+
+       filter->list_cnt++;
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_filter_enable(dhd_pktlog_filter_t *filter, uint32 pktmon_case, uint32 enable)
+{
+       if  (!filter) {
+               DHD_ERROR(("%s(): filter is NULL\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       DHD_PKT_LOG(("%s(): pktlog_case %d enable %d\n", __FUNCTION__, pktmon_case, enable));
+
+       if (enable) {
+               filter->enable |=  pktmon_case;
+       } else {
+               filter->enable &= ~pktmon_case;
+       }
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_filter_pattern_enable(dhd_pktlog_filter_t *filter, char *arg, uint32 enable)
+{
+       uint32 id = 0;
+
+       if  (!filter || !arg) {
+               DHD_ERROR(("%s(): pktlog_filter =%p arg =%p\n", __FUNCTION__, filter, arg));
+               return BCME_ERROR;
+       }
+
+       if (dhd_pktlog_filter_existed(filter, arg, &id) == TRUE) {
+               if (id > 0) {
+                       filter->info[id-1].enable = enable;
+                       DHD_ERROR(("%s(): This pattern id %d is %s\n",
+                               __FUNCTION__, id, (enable ? "enabled" : "disabled")));
+               }
+       } else {
+               DHD_ERROR(("%s(): This pattern is not existed\n", __FUNCTION__));
+               DHD_ERROR(("%s(): arg %s\n", __FUNCTION__, arg));
+       }
+
+       return BCME_OK;
+}
+
+int
+dhd_pktlog_filter_info(dhd_pktlog_filter_t *filter)
+{
+       char filter_pattern[MAX_FILTER_PATTERN_LEN];
+       char *p;
+       int i, j;
+       int nchar;
+       int len;
+
+       if  (!filter) {
+               DHD_ERROR(("%s(): pktlog_filter is NULL\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       DHD_ERROR(("---- PKTLOG FILTER INFO ----\n\n"));
+
+       DHD_ERROR(("Filter list cnt %d Filter is %s\n",
+               filter->list_cnt, (filter->enable ? "enabled" : "disabled")));
+
+       for (i = 0; i < filter->list_cnt; i++) {
+               p = filter_pattern;
+               len = sizeof(filter_pattern);
+
+               nchar = snprintf(p, len, "%d ", filter->info[i].offset);
+               p += nchar;
+               len -= nchar;
+
+               nchar = snprintf(p, len, "0x");
+               p += nchar;
+               len -= nchar;
+
+               for (j = 0; j < filter->info[i].size_bytes; j++) {
+                       nchar = snprintf(p, len, "%02x", filter->info[i].mask[j]);
+                       p += nchar;
+                       len -= nchar;
+               }
+
+               nchar = snprintf(p, len, " 0x");
+               p += nchar;
+               len -= nchar;
+
+               for (j = 0; j < filter->info[i].size_bytes; j++) {
+                       nchar = snprintf(p, len, "%02x", filter->info[i].pattern[j]);
+                       p += nchar;
+                       len -= nchar;
+               }
+
+               DHD_ERROR(("ID:%d is %s\n",
+                       filter->info[i].id, (filter->info[i].enable ? "enabled" : "disabled")));
+               DHD_ERROR(("Pattern %s\n", filter_pattern));
+       }
+
+       DHD_ERROR(("---- PKTLOG FILTER END ----\n"));
+
+       return BCME_OK;
+}
+bool
+dhd_pktlog_filter_matched(dhd_pktlog_filter_t *filter, char *data, uint32 pktlog_case)
+{
+       uint16 szbts;   /* pattern size */
+       uint16 offset;  /* pattern offset */
+       int i, j;
+       uint8 *mask = NULL;             /* bitmask */
+       uint8 *pattern = NULL;
+       uint8 *pkt_offset = NULL;       /* packet offset */
+       bool matched;
+
+       if  (!filter || !data) {
+               DHD_PKT_LOG(("%s(): filter=%p data=%p\n",
+                       __FUNCTION__, filter, data));
+               return TRUE;
+       }
+
+       if (!(pktlog_case & filter->enable)) {
+               DHD_PKT_LOG(("%s(): pktlog_case %d return TRUE filter is disabled\n",
+                       __FUNCTION__, pktlog_case));
+               return TRUE;
+       }
+
+       for (i = 0; i < filter->list_cnt; i++) {
+               if (&filter->info[i] && filter->info[i].id && filter->info[i].enable) {
+                       szbts = filter->info[i].size_bytes;
+                       offset = filter->info[i].offset;
+                       mask = &filter->info[i].mask[0];
+                       pkt_offset = &data[offset];
+                       pattern = &filter->info[i].pattern[0];
+
+                       matched = TRUE;
+                       for (j = 0; j < szbts; j++) {
+                               if ((mask[j] & pkt_offset[j]) != pattern[j]) {
+                                       matched = FALSE;
+                                       break;
+                               }
+                       }
+
+                       if (matched) {
+                               DHD_PKT_LOG(("%s(): pktlog_filter return TRUE id %d\n",
+                                       __FUNCTION__, filter->info[i].id));
+                               return TRUE;
+                       }
+               } else {
+                       DHD_PKT_LOG(("%s(): filter ino is null %p\n",
+                               __FUNCTION__, &filter->info[i]));
+               }
+       }
+
+       return FALSE;
+}
+
+/* Ethernet Type MAC Header 12 bytes + Frame payload 10 bytes */
+#define PKTLOG_MINIMIZE_REPORT_LEN 22
+
+static char pktlog_minmize_mask_table[] = {
+       0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, /* Ethernet Type MAC Header - Destination MAC Address */
+       0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, /* Ethernet Type MAC Header - Source MAC Address */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Ethernet Type MAC Header - Ether Type - 2 bytes */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Frame payload */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* UDP port number offset - bytes as 0xff */
+       0xff, 0xff,
+};
+
+static inline void
+dhd_pktlog_minimize_report(char *pkt, uint32 frame_len)
+{
+       int i;
+       int table_len;
+       int report_len;
+       int remain_len;
+       char *p_table;
+
+       table_len = sizeof(pktlog_minmize_mask_table);
+       report_len =  table_len;
+       p_table = &pktlog_minmize_mask_table[0];
+
+       if (frame_len < PKTLOG_MINIMIZE_REPORT_LEN) {
+               return;
+       }
+
+       if (frame_len < table_len) {
+               report_len = PKTLOG_MINIMIZE_REPORT_LEN;
+       }
+
+       remain_len = frame_len - report_len;
+
+       for (i = 0; i < report_len; i++) {
+               pkt[i] = pkt[i] & p_table[i];
+       }
+
+       if (remain_len) {
+               memset(&pkt[report_len], 0x00, remain_len);
+       }
+}
+
+static int
+dhd_pktlog_pkts_write_file(dhd_pktlog_ring_t *ringbuf, struct file *w_pcap_fp, int *total_cnt)
+{
+       dhd_pktlog_ring_info_t *report_ptr;
+       void *data = NULL;
+       int count = 0;
+       uint32 frame_len;
+       uint32 write_frame_len;
+       int ret = BCME_OK;
+       uint32 len, alloc_len, remain_len;
+       char *report_buf = NULL;
+       char *p = NULL;
+       int bytes_user_data = 0;
+       char buf[DHD_PKTLOG_FATE_INFO_STR_LEN];
+
+       if (!ringbuf || !w_pcap_fp) {
+               DHD_PKT_LOG(("%s(): pktlog_ring=%p w_pcap_fp=%p NULL\n",
+                       __FUNCTION__, ringbuf, w_pcap_fp));
+               return BCME_ERROR;
+       }
+
+       if (dhd_pktlog_ring_set_nextpos(ringbuf) != BCME_OK) {
+               return BCME_ERROR;
+       }
+
+       if (!ringbuf->dhdp) {
+               DHD_ERROR(("%s(): dhdp is NULL\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       DHD_PKT_LOG(("%s(): BEGIN\n", __FUNCTION__));
+
+       alloc_len = PKTLOG_DUMP_BUF_SIZE;
+
+       report_buf =
+               DHD_OS_PREALLOC(ringbuf->dhdp, DHD_PREALLOC_DHD_PKTLOG_DUMP_BUF, alloc_len);
+       if (unlikely(!report_buf)) {
+               DHD_ERROR(("%s(): could not allocate memory for - "
+                                       "report_buf size %d\n", __FUNCTION__, alloc_len));
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       p = report_buf;
+       len = 0;
+       remain_len = 0;
+
+       while (dhd_pktlog_ring_get_nextbuf(ringbuf, &data) == BCME_OK) {
+               report_ptr = (dhd_pktlog_ring_info_t *)data;
+
+               memcpy(p, (char*)&report_ptr->info.driver_ts_sec,
+                               sizeof(report_ptr->info.driver_ts_sec));
+               p += sizeof(report_ptr->info.driver_ts_sec);
+               len += sizeof(report_ptr->info.driver_ts_sec);
+
+               memcpy(p, (char*)&report_ptr->info.driver_ts_usec,
+                               sizeof(report_ptr->info.driver_ts_usec));
+               p += sizeof(report_ptr->info.driver_ts_usec);
+               len += sizeof(report_ptr->info.driver_ts_usec);
+
+               if (report_ptr->info.payload_type == FRAME_TYPE_ETHERNET_II) {
+                       frame_len = min(report_ptr->info.pkt_len, (size_t)MAX_FRAME_LEN_ETHERNET);
+               } else {
+                       frame_len = min(report_ptr->info.pkt_len, (size_t)MAX_FRAME_LEN_80211_MGMT);
+               }
+
+               bytes_user_data = sprintf(buf, "%s:%s:%02d\n", DHD_PKTLOG_FATE_INFO_FORMAT,
+                               (report_ptr->tx_fate ? "Failure" : "Succeed"), report_ptr->tx_fate);
+               write_frame_len = frame_len + bytes_user_data;
+
+               /* pcap pkt head has incl_len and orig_len */
+               memcpy(p, (char*)&write_frame_len, sizeof(write_frame_len));
+               p += sizeof(write_frame_len);
+               len += sizeof(write_frame_len);
+               memcpy(p, (char*)&write_frame_len, sizeof(write_frame_len));
+               p += sizeof(write_frame_len);
+               len += sizeof(write_frame_len);
+
+               memcpy(p, PKTDATA(ringbuf->dhdp->osh, report_ptr->info.pkt), frame_len);
+               if (ringbuf->pktlog_minmize) {
+                       dhd_pktlog_minimize_report(p, frame_len);
+               }
+               p += frame_len;
+               len += frame_len;
+
+               memcpy(p, buf, bytes_user_data);
+               p += bytes_user_data;
+               len += bytes_user_data;
+
+               count++;
+
+               DHD_PKT_LOG(("%s(): write cnt %d frame_len %d\n", __FUNCTION__, count, frame_len));
+
+               remain_len = len;
+               remain_len += (MAX_FRAME_LEN_80211_MGMT + DHD_PKTLOG_FATE_INFO_STR_LEN);
+
+               if (remain_len > alloc_len) {
+                       ret = vfs_write(w_pcap_fp, report_buf, len, &w_pcap_fp->f_pos);
+                       if (ret < 0) {
+                               DHD_ERROR(("%s(): write pkt data error, err = %d\n",
+                                       __FUNCTION__, ret));
+                               goto fail;
+                       }
+
+                       p = report_buf;
+                       len = 0;
+                       remain_len = 0;
+               }
+       }
+
+       if (len) {
+               ret = vfs_write(w_pcap_fp, report_buf, len, &w_pcap_fp->f_pos);
+               if (ret < 0) {
+                       DHD_ERROR(("%s(): write pkt data error, err = %d\n", __FUNCTION__, ret));
+                       goto fail;
+               }
+       }
+
+       if (ret < 0) {
+               DHD_ERROR(("%s(): write pkt fate error, err = %d\n", __FUNCTION__, ret));
+       }
+
+fail:
+       *total_cnt = *total_cnt + count;
+
+       if (report_buf) {
+               DHD_OS_PREFREE(ringbuf->dhdp, report_buf, alloc_len);
+       }
+
+       return ret;
+}
+
+int
+dhd_pktlog_write_file(dhd_pub_t *dhdp)
+{
+       struct file *w_pcap_fp = NULL;
+       mm_segment_t old_fs;
+       uint32 file_mode;
+       char dump_path[128];
+       struct timeval curtime;
+       int ret = BCME_OK;
+       dhd_pktlog_ring_t *tx_pktlog_ring;
+       dhd_pktlog_ring_t *rx_pktlog_ring;
+       dhd_pktlog_pcap_hdr_t pcap_h;
+       int total_cnt = 0;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring || !dhdp->pktlog->rx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring =%p rx_pktlog_ring=%p\n",
+                       __FUNCTION__, dhdp->pktlog->tx_pktlog_ring,
+                       dhdp->pktlog->rx_pktlog_ring));
+               return -EINVAL;
+       }
+
+       pcap_h.magic_number = PKTLOG_PCAP_MAGIC_NUM;
+       pcap_h.version_major = PKTLOG_PCAP_MAJOR_VER;
+       pcap_h.version_minor = PKTLOG_PCAP_MINOR_VER;
+       pcap_h.thiszone = 0x0;
+       pcap_h.sigfigs = 0x0;
+       pcap_h.snaplen = PKTLOG_PCAP_SNAP_LEN;
+       pcap_h.network = PKTLOG_PCAP_NETWORK_TYPE;
+
+       tx_pktlog_ring = dhdp->pktlog->tx_pktlog_ring;
+       rx_pktlog_ring = dhdp->pktlog->rx_pktlog_ring;
+
+       tx_pktlog_ring->start = FALSE;
+       rx_pktlog_ring->start = FALSE;
+
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+
+       memset(dump_path, 0, sizeof(dump_path));
+       do_gettimeofday(&curtime);
+       snprintf(dump_path, sizeof(dump_path), "%s_%ld.%ld.pcap",
+                       DHD_PKTLOG_DUMP_PATH DHD_PKTLOG_DUMP_TYPE,
+                       (unsigned long)curtime.tv_sec, (unsigned long)curtime.tv_usec);
+
+       file_mode = O_CREAT | O_WRONLY;
+
+       DHD_ERROR(("pktlog_dump_pcap = %s\n", dump_path));
+
+       w_pcap_fp = filp_open(dump_path, file_mode, 0664);
+       if (IS_ERR(w_pcap_fp)) {
+               DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n",
+                       __FUNCTION__, dump_path, PTR_ERR(w_pcap_fp)));
+               ret = BCME_ERROR;
+               goto fail;
+       }
+
+       ret = vfs_write(w_pcap_fp, (char*)&pcap_h, sizeof(pcap_h), &w_pcap_fp->f_pos);
+
+       if (ret < 0) {
+               DHD_ERROR(("%s(): write pcap head error, err = %d\n", __FUNCTION__, ret));
+               goto fail;
+       }
+
+       tx_pktlog_ring->dhdp = dhdp;
+       ret = dhd_pktlog_pkts_write_file(tx_pktlog_ring, w_pcap_fp, &total_cnt);
+
+       if (ret < 0) {
+               DHD_ERROR(("%s(): write tx pkts error, err = %d\n", __FUNCTION__, ret));
+               goto fail;
+       }
+       DHD_ERROR(("pktlog tx pkts write is end, err = %d\n", ret));
+
+       rx_pktlog_ring->dhdp = dhdp;
+       ret = dhd_pktlog_pkts_write_file(rx_pktlog_ring, w_pcap_fp, &total_cnt);
+
+       if (ret < 0) {
+               DHD_ERROR(("%s(): write rx pkts error, err = %d\n", __FUNCTION__, ret));
+               goto fail;
+       }
+       DHD_ERROR(("pktlog rx pkts write is end, err = %d\n", ret));
+
+       /* Sync file from filesystem to physical media */
+       ret = vfs_fsync(w_pcap_fp, 0);
+       if (ret < 0) {
+               DHD_ERROR(("%s(): sync pcap file error, err = %d\n", __FUNCTION__, ret));
+               goto fail;
+       }
+
+fail:
+       tx_pktlog_ring->start = TRUE;
+       rx_pktlog_ring->start = TRUE;
+
+       if (!IS_ERR(w_pcap_fp)) {
+               filp_close(w_pcap_fp, NULL);
+       }
+
+       set_fs(old_fs);
+
+       DHD_ERROR(("pktlog write file is end, err = %d\n", ret));
+
+#ifdef DHD_DUMP_MNGR
+       if (ret >= 0) {
+               dhd_dump_file_manage_enqueue(dhdp, dump_path, DHD_PKTLOG_DUMP_TYPE);
+       }
+#endif /* DHD_DUMP_MNGR */
+
+       return ret;
+}
+
+dhd_pktlog_ring_t*
+dhd_pktlog_ring_change_size(dhd_pktlog_ring_t *ringbuf, int size)
+{
+       uint32 alloc_len;
+       uint32 pktlog_start;
+       uint32 pktlog_minmize;
+       dhd_pktlog_ring_t *pktlog_ring;
+       dhd_pub_t *dhdp;
+
+       if  (!ringbuf) {
+               DHD_ERROR(("%s(): ringbuf is NULL\n", __FUNCTION__));
+               return NULL;
+       }
+
+       alloc_len = size;
+       if (alloc_len < MIN_PKTLOG_LEN) {
+               alloc_len = MIN_PKTLOG_LEN;
+       }
+       if (alloc_len > MAX_PKTLOG_LEN) {
+               alloc_len = MAX_PKTLOG_LEN;
+       }
+       DHD_ERROR(("ring size requested: %d alloc: %d\n", size, alloc_len));
+
+       /* backup variable */
+       pktlog_start = ringbuf->start;
+       pktlog_minmize = ringbuf->pktlog_minmize;
+       dhdp = ringbuf->dhdp;
+
+       /* free ring_info */
+       dhd_pktlog_ring_deinit(ringbuf);
+
+       /* alloc ring_info */
+       pktlog_ring = dhd_pktlog_ring_init(dhdp, alloc_len);
+
+       /* restore variable */
+       if (pktlog_ring) {
+               pktlog_ring->start = pktlog_start;
+               pktlog_ring->pktlog_minmize = pktlog_minmize;
+       }
+
+       return pktlog_ring;
+}
+#endif /* DHD_PKT_LOGGING */
diff --git a/drivers/net/wireless/bcmdhd_1_77/dhd_pktlog.h b/drivers/net/wireless/bcmdhd_1_77/dhd_pktlog.h
new file mode 100644 (file)
index 0000000..81aa589
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * DHD debugability packet logging header file
+ *
+ * Copyright (C) 1999-2018, Broadcom Corporation
+ * 
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ * 
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ * 
+ *      Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: dhd_pktlog.h 742382 2018-01-22 01:56:53Z $
+ */
+
+#ifndef __DHD_PKTLOG_H_
+#define __DHD_PKTLOG_H_
+
+#include <dhd_debug.h>
+#include <dhd.h>
+
+#ifdef DHD_PKT_LOGGING
+#define DHD_PKT_LOG(args)      DHD_INFO(args)
+#define MIN_PKTLOG_LEN                 (32 * 10)
+#define MAX_PKTLOG_LEN                 (32 * 100)
+#define MAX_DHD_PKTLOG_FILTER_LEN      10
+#define MAX_MASK_PATTERN_FILTER_LEN    64
+#define PKTLOG_TXPKT_CASE                      0x0001
+#define PKTLOG_TXSTATUS_CASE           0x0002
+#define PKTLOG_RXPKT_CASE                      0x0004
+#define MAX_FILTER_PATTERN_LEN         256
+#define PKTLOG_DUMP_BUF_SIZE           (64 * 1024)
+
+typedef struct dhd_dbg_pktlog_info {
+       frame_type payload_type;
+       size_t pkt_len;
+       uint32 driver_ts_sec;
+       uint32 driver_ts_usec;
+       uint32 firmware_ts;
+       uint32 pkt_hash;
+       void *pkt;
+} dhd_dbg_pktlog_info_t;
+
+typedef struct dhd_pktlog_ring_info
+{
+       union {
+               wifi_tx_packet_fate tx_fate;
+               wifi_rx_packet_fate rx_fate;
+       };
+       dhd_dbg_pktlog_info_t info;
+} dhd_pktlog_ring_info_t;
+
+typedef struct dhd_pktlog_ring
+{
+       uint16 front;
+       uint16 rear;
+       uint16 prev_pos;
+       uint16 next_pos;
+       uint32 start;
+       uint32 pktlog_minmize;
+       uint32 pktlog_len;
+       dhd_pktlog_ring_info_t *pktlog_ring_info;
+       dhd_pub_t *dhdp;
+} dhd_pktlog_ring_t;
+
+typedef struct dhd_pktlog_filter_info
+{
+       uint32 id;
+       uint32 offset;
+       uint32 size_bytes; /* Size of pattern. */
+       uint32 enable;
+       uint8 mask[MAX_MASK_PATTERN_FILTER_LEN];
+       uint8 pattern[MAX_MASK_PATTERN_FILTER_LEN];
+} dhd_pktlog_filter_info_t;
+
+typedef struct dhd_pktlog_filter
+{
+       dhd_pktlog_filter_info_t *info;
+       uint32 list_cnt;
+       uint32 enable;
+} dhd_pktlog_filter_t;
+
+typedef struct dhd_pktlog
+{
+       struct dhd_pktlog_ring *tx_pktlog_ring;
+       struct dhd_pktlog_ring *rx_pktlog_ring;
+       struct dhd_pktlog_filter *pktlog_filter;
+} dhd_pktlog_t;
+
+typedef struct dhd_pktlog_pcap_hdr
+{
+       uint32 magic_number;
+       uint16 version_major;
+       uint16 version_minor;
+       uint16 thiszone;
+       uint32 sigfigs;
+       uint32 snaplen;
+       uint32 network;
+} dhd_pktlog_pcap_hdr_t;
+
+#define PKTLOG_PCAP_MAGIC_NUM 0xa1b2c3d4
+#define PKTLOG_PCAP_MAJOR_VER 0x02
+#define PKTLOG_PCAP_MINOR_VER 0x04
+#define PKTLOG_PCAP_SNAP_LEN 0x40000
+#define PKTLOG_PCAP_NETWORK_TYPE 147
+
+extern int dhd_os_attach_pktlog(dhd_pub_t *dhdp);
+extern int dhd_os_detach_pktlog(dhd_pub_t *dhdp);
+extern dhd_pktlog_ring_t* dhd_pktlog_ring_init(dhd_pub_t *dhdp, int size);
+extern int dhd_pktlog_ring_deinit(dhd_pktlog_ring_t *ring);
+extern int dhd_pktlog_ring_set_nextpos(dhd_pktlog_ring_t *ringbuf);
+extern int dhd_pktlog_ring_get_nextbuf(dhd_pktlog_ring_t *ringbuf, void **data);
+extern int dhd_pktlog_ring_set_prevpos(dhd_pktlog_ring_t *ringbuf);
+extern int dhd_pktlog_ring_get_prevbuf(dhd_pktlog_ring_t *ringbuf, void **data);
+extern int dhd_pktlog_ring_get_writebuf(dhd_pktlog_ring_t *ringbuf, void **data);
+extern int dhd_pktlog_ring_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid);
+extern int dhd_pktlog_ring_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+               uint16 status);
+extern int dhd_pktlog_ring_rx_pkts(dhd_pub_t *dhdp, void *pkt);
+extern dhd_pktlog_ring_t* dhd_pktlog_ring_change_size(dhd_pktlog_ring_t *ringbuf, int size);
+
+#define DHD_PKTLOG_TX(dhdp, pkt, pktid) \
+{ \
+       do { \
+               if ((dhdp) && (dhdp)->pktlog && (dhdp)->pktlog->tx_pktlog_ring && (pkt)) { \
+                       if ((dhdp)->pktlog->tx_pktlog_ring->start) { \
+                                dhd_pktlog_ring_tx_pkts(dhdp, pkt, pktid); \
+                       } \
+               } \
+       } while (0); \
+}
+
+#define DHD_PKTLOG_TXS(dhdp, pkt, pktid, status) \
+{ \
+       do { \
+               if ((dhdp) && (dhdp)->pktlog && (dhdp)->pktlog->tx_pktlog_ring && (pkt)) { \
+                       if ((dhdp)->pktlog->tx_pktlog_ring->start) { \
+                                dhd_pktlog_ring_tx_status(dhdp, pkt, pktid, status); \
+                       } \
+               } \
+       } while (0); \
+}
+
+#define DHD_PKTLOG_RX(dhdp, pkt) \
+{ \
+       do { \
+               if ((dhdp) && (dhdp)->pktlog && (dhdp)->pktlog->rx_pktlog_ring && (pkt)) { \
+                       if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \
+                               if ((dhdp)->pktlog->rx_pktlog_ring->start) { \
+                                       dhd_pktlog_ring_rx_pkts(dhdp, pkt); \
+                               } \
+                       } \
+               } \
+       } while (0); \
+}
+
+extern dhd_pktlog_filter_t* dhd_pktlog_filter_init(int size);
+extern int dhd_pktlog_filter_deinit(dhd_pktlog_filter_t *filter);
+extern int dhd_pktlog_filter_add(dhd_pktlog_filter_t *filter, char *arg);
+extern int dhd_pktlog_filter_enable(dhd_pktlog_filter_t *filter, uint32 pktlog_case, uint32 enable);
+extern int dhd_pktlog_filter_pattern_enable(dhd_pktlog_filter_t *filter, char *arg, uint32 enable);
+extern int dhd_pktlog_filter_info(dhd_pktlog_filter_t *filter);
+extern bool dhd_pktlog_filter_matched(dhd_pktlog_filter_t *filter, char *data, uint32 pktlog_case);
+extern bool dhd_pktlog_filter_existed(dhd_pktlog_filter_t *filter, char *arg, uint32 *id);
+
+#define DHD_PKTLOG_FILTER_ADD(pattern, filter_pattern, dhdp)   \
+{      \
+       do {    \
+               if ((strlen(pattern) + 1) < sizeof(filter_pattern)) {   \
+                       strncpy(filter_pattern, pattern, sizeof(filter_pattern));       \
+                       dhd_pktlog_filter_add(dhdp->pktlog->pktlog_filter, filter_pattern);     \
+               }       \
+       } while (0);    \
+}
+
+#define DHD_PKTLOG_DUMP_PATH   DHD_COMMON_DUMP_PATH
+extern void dhd_pktlog_dump(void *handle, void *event_info, u8 event);
+extern void dhd_schedule_pktlog_dump(dhd_pub_t *dhdp);
+extern int dhd_pktlog_write_file(dhd_pub_t *dhdp);
+
+#define DHD_PKTLOG_FATE_INFO_STR_LEN 256
+#define DHD_PKTLOG_FATE_INFO_FORMAT    "BRCM_Packet_Fate"
+#define DHD_PKTLOG_DUMP_TYPE "pktlog_dump"
+
+#endif /* DHD_PKT_LOGGING */
+#endif /* __DHD_PKTLOG_H_ */
index 0254391778ec3b5c313aacf2b70f92ced2366039..309deec67914c3495c12872f9603470d942bbe32 100644 (file)
@@ -2,7 +2,7 @@
  * Broadcom Dongle Host Driver (DHD)
  * Prefered Network Offload and Wi-Fi Location Service(WLS) code.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -25,7 +25,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_pno.c 680464 2017-01-20 02:26:10Z $
+ * $Id: dhd_pno.c 735359 2017-12-08 10:56:04Z $
  */
 
 #if defined(GSCAN_SUPPORT) && !defined(PNO_SUPPORT)
@@ -55,6 +55,9 @@
 #ifdef GSCAN_SUPPORT
 #include <linux/gcd.h>
 #endif /* GSCAN_SUPPORT */
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif /* WL_CFG80211 */
 
 #ifdef __BIG_ENDIAN
 #include <bcmendian.h>
 
 #define ENTRY_OVERHEAD strlen("bssid=\nssid=\nfreq=\nlevel=\nage=\ndist=\ndistSd=\n====")
 #define TIME_MIN_DIFF 5
+
+#define EVENT_DATABUF_MAXLEN   (512 - sizeof(bcm_event_t))
+#define EVENT_MAX_NETCNT_V1 \
+       ((EVENT_DATABUF_MAXLEN - sizeof(wl_pfn_scanresults_v1_t)) \
+       / sizeof(wl_pfn_net_info_v1_t) + 1)
+#define EVENT_MAX_NETCNT_V2 \
+       ((EVENT_DATABUF_MAXLEN - sizeof(wl_pfn_scanresults_v2_t)) \
+       / sizeof(wl_pfn_net_info_v2_t) + 1)
+
 #ifdef GSCAN_SUPPORT
 static int _dhd_pno_flush_ssid(dhd_pub_t *dhd);
 static wl_pfn_gscan_ch_bucket_cfg_t *
@@ -128,14 +140,14 @@ dhd_pno_clean(dhd_pub_t *dhd)
        _pno_state = PNO_GET_PNOSTATE(dhd);
        DHD_PNO(("%s enter\n", __FUNCTION__));
        /* Disable PNO */
-       err = dhd_iovar(dhd, 0, "pfn", (char *)&pfn, sizeof(pfn), 1);
+       err = dhd_iovar(dhd, 0, "pfn", (char *)&pfn, sizeof(pfn), NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn(error : %d)\n",
                        __FUNCTION__, err));
                goto exit;
        }
        _pno_state->pno_status = DHD_PNO_DISABLED;
-       err = dhd_iovar(dhd, 0, "pfnclear", NULL, 0, 1);
+       err = dhd_iovar(dhd, 0, "pfnclear", NULL, 0, NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfnclear(error : %d)\n",
                        __FUNCTION__, err));
@@ -294,7 +306,7 @@ _dhd_pno_gscan_cfg(dhd_pub_t *dhd, wl_pfn_gscan_cfg_t *pfncfg_gscan_param, int s
 
        DHD_PNO(("%s enter\n", __FUNCTION__));
 
-       err = dhd_iovar(dhd, 0, "pfn_gscan_cfg", (char *)pfncfg_gscan_param, size, 1);
+       err = dhd_iovar(dhd, 0, "pfn_gscan_cfg", (char *)pfncfg_gscan_param, size, NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfncfg_gscan_param\n", __FUNCTION__));
                goto exit;
@@ -311,8 +323,7 @@ _dhd_pno_flush_ssid(dhd_pub_t *dhd)
        wl_pfn_t pfn_elem;
        memset(&pfn_elem, 0, sizeof(wl_pfn_t));
        pfn_elem.flags = htod32(WL_PFN_FLUSH_ALL_SSIDS);
-       err = dhd_iovar(dhd, 0, "pfn_add", (char *)&pfn_elem,
-               sizeof(wl_pfn_t), 1);
+       err = dhd_iovar(dhd, 0, "pfn_add", (char *)&pfn_elem, sizeof(wl_pfn_t), NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_add\n", __FUNCTION__));
        }
@@ -339,7 +350,7 @@ _dhd_pno_suspend(dhd_pub_t *dhd)
 
        DHD_PNO(("%s enter\n", __FUNCTION__));
        _pno_state = PNO_GET_PNOSTATE(dhd);
-       err = dhd_iovar(dhd, 0, "pfn_suspend", (char *)&suspend, sizeof(suspend), 1);
+       err = dhd_iovar(dhd, 0, "pfn_suspend", (char *)&suspend, sizeof(suspend), NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to suspend pfn(error :%d)\n", __FUNCTION__, err));
                goto exit;
@@ -379,7 +390,7 @@ _dhd_pno_enable(dhd_pub_t *dhd, int enable)
                }
        }
        /* Enable/Disable PNO */
-       err = dhd_iovar(dhd, 0, "pfn", (char *)&enable, sizeof(enable), 1);
+       err = dhd_iovar(dhd, 0, "pfn", (char *)&enable, sizeof(enable), NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_set - %d\n", __FUNCTION__, err));
                goto exit;
@@ -574,13 +585,13 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t
 
                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);
+               err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), NULL, 0, TRUE);
                if (err < 0) {
                        DHD_ERROR(("%s : failed to set pfnmem\n", __FUNCTION__));
                        goto exit;
                }
                /* get max mscan which the firmware supports */
-               err = dhd_iovar(dhd, 0, "pfnmem", (char *)&_tmp, sizeof(_tmp), 0);
+               err = dhd_iovar(dhd, 0, "pfnmem", NULL, 0, (char *)&_tmp, sizeof(_tmp), FALSE);
                if (err < 0) {
                        DHD_ERROR(("%s : failed to get pfnmem\n", __FUNCTION__));
                        goto exit;
@@ -589,7 +600,7 @@ _dhd_pno_set(dhd_pub_t *dhd, const dhd_pno_params_t *pno_params, dhd_pno_mode_t
                DHD_PNO((" returned mscan : %d, set bestn : %d mscan %d\n", _tmp, pfn_param.bestn,
                        pfn_param.mscan));
        }
-       err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param), 1);
+       err = dhd_iovar(dhd, 0, "pfn_set", (char *)&pfn_param, sizeof(pfn_param), NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_set %d\n", __FUNCTION__, err));
                goto exit;
@@ -648,8 +659,7 @@ _dhd_pno_add_ssid(dhd_pub_t *dhd, struct list_head *ssid_list, int nssid)
                        break;
                }
        }
-       err = dhd_iovar(dhd, 0, "pfn_add", (char *)pfn_elem_buf,
-               mem_needed, 1);
+       err = dhd_iovar(dhd, 0, "pfn_add", (char *)pfn_elem_buf, mem_needed, NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_add\n", __FUNCTION__));
        }
@@ -709,6 +719,7 @@ _dhd_pno_get_channels(dhd_pub_t *dhd, uint16 *d_chan_list,
        if (*nchan) {
                NULL_CHECK(d_chan_list, "d_chan_list is NULL", err);
        }
+       memset(&chan_buf, 0, sizeof(chan_buf));
        list = (wl_uint32_list_t *) (void *)chan_buf;
        list->count = htod32(WL_NUMCHANNELS);
        err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, chan_buf, sizeof(chan_buf), FALSE, 0);
@@ -968,7 +979,8 @@ _dhd_pno_cfg(dhd_pub_t *dhd, uint16 *channel_list, int nchan)
                pfncfg_param.channel_list[i] = channel_list[i];
 
        pfncfg_param.channel_num = htod32(nchan);
-       err = dhd_iovar(dhd, 0, "pfn_cfg", (char *)&pfncfg_param, sizeof(pfncfg_param), 1);
+       err = dhd_iovar(dhd, 0, "pfn_cfg", (char *)&pfncfg_param, sizeof(pfncfg_param), NULL, 0,
+                       TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_cfg\n", __FUNCTION__));
                goto exit;
@@ -1077,7 +1089,7 @@ _dhd_pno_add_bssid(dhd_pub_t *dhd, wl_pfn_bssid_t *p_pfn_bssid, int nbssid)
                NULL_CHECK(p_pfn_bssid, "bssid list is NULL", err);
        }
        err = dhd_iovar(dhd, 0, "pfn_add_bssid", (char *)p_pfn_bssid,
-               sizeof(wl_pfn_bssid_t) * nbssid, 1);
+                       sizeof(wl_pfn_bssid_t) * nbssid, NULL, 0, TRUE);
        if (err < 0) {
                DHD_ERROR(("%s : failed to execute pfn_cfg\n", __FUNCTION__));
                goto exit;
@@ -1086,32 +1098,6 @@ exit:
        return err;
 }
 
-#ifdef GSCAN_SUPPORT
-static int
-_dhd_pno_add_significant_bssid(dhd_pub_t *dhd,
-   wl_pfn_significant_bssid_t *p_pfn_significant_bssid, int nbssid)
-{
-       int err = BCME_OK;
-       NULL_CHECK(dhd, "dhd is NULL", err);
-
-       if (!nbssid) {
-               err = BCME_ERROR;
-               goto exit;
-       }
-
-       NULL_CHECK(p_pfn_significant_bssid, "bssid list is NULL", err);
-
-       err = dhd_iovar(dhd, 0, "pfn_add_swc_bssid", (char *)p_pfn_significant_bssid,
-               sizeof(wl_pfn_significant_bssid_t) * nbssid, 1);
-       if (err < 0) {
-               DHD_ERROR(("%s : failed to execute pfn_significant_bssid %d\n", __FUNCTION__, err));
-               goto exit;
-       }
-exit:
-       return err;
-}
-#endif /* GSCAN_SUPPORT */
-
 int
 dhd_pno_stop_for_ssid(dhd_pub_t *dhd)
 {
@@ -1128,7 +1114,11 @@ dhd_pno_stop_for_ssid(dhd_pub_t *dhd)
                goto exit;
        }
        DHD_PNO(("%s enter\n", __FUNCTION__));
+       /* If pno mode is PNO_LEGACY_MODE clear the pno values and unset the DHD_PNO_LEGACY_MODE */
+       _params = &_pno_state->pno_params_arr[INDEX_OF_LEGACY_PARAMS];
+       _dhd_pno_reinitialize_prof(dhd, _params, DHD_PNO_LEGACY_MODE);
        _pno_state->pno_mode &= ~DHD_PNO_LEGACY_MODE;
+
 #ifdef GSCAN_SUPPORT
        if (_pno_state->pno_mode & DHD_PNO_GSCAN_MODE) {
                struct dhd_pno_gscan_params *gscan_params;
@@ -1654,7 +1644,7 @@ dhd_set_epno_params(dhd_pub_t *dhd, wl_pfn_ssid_params_t *params, bool set)
        else if (params)
                memcpy(&cfg.params, params, sizeof(wl_pfn_ssid_params_t));
        err = dhd_iovar(dhd, 0, "pfn_ssid_cfg", (char *)&cfg,
-              sizeof(wl_pfn_ssid_cfg_t), 1);
+                       sizeof(wl_pfn_ssid_cfg_t), NULL, 0, TRUE);
        if (err != BCME_OK) {
                DHD_ERROR(("%s : Failed to execute pfn_ssid_cfg %d\n", __FUNCTION__, err));
        }
@@ -1745,26 +1735,6 @@ dhd_pno_reset_cfg_gscan(dhd_pno_params_t *_params,
                _params->params_gscan.nbssid_hotlist = 0;
                DHD_PNO(("Flush Hotlist Config\n"));
        }
-       if (flags & GSCAN_FLUSH_SIGNIFICANT_CFG) {
-               dhd_pno_significant_bssid_t *iter, *next;
-
-               if (_params->params_gscan.nbssid_significant_change > 0) {
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-                       list_for_each_entry_safe(iter, next,
-                               &_params->params_gscan.significant_bssid_list, list) {
-                               list_del(&iter->list);
-                               kfree(iter);
-                       }
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-               }
-               _params->params_gscan.nbssid_significant_change = 0;
-               DHD_PNO(("Flush Significant Change Config\n"));
-       }
        if (flags & GSCAN_FLUSH_EPNO_CFG) {
                dhd_pno_ssid_t *iter, *next;
                dhd_epno_ssid_cfg_t *epno_cfg = &_params->params_gscan.epno_cfg;
@@ -1926,14 +1896,6 @@ dhd_pno_set_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type,
                        if (!_params->params_gscan.nbssid_hotlist) {
                                INIT_LIST_HEAD(&_params->params_gscan.hotlist_bssid_list);
                        }
-                       if ((_params->params_gscan.nbssid_hotlist +
-                                 ptr->nbssid) > PFN_SWC_MAX_NUM_APS) {
-                               DHD_ERROR(("Excessive number of hotlist APs programmed %d\n",
-                                    (_params->params_gscan.nbssid_hotlist +
-                                     ptr->nbssid)));
-                               err = BCME_RANGE;
-                               goto exit;
-                       }
 
                        for (i = 0, bssid_ptr = ptr->bssid; i < ptr->nbssid; i++, bssid_ptr++) {
                                _pno_bssid = kzalloc(sizeof(struct dhd_pno_bssid), GFP_KERNEL);
@@ -1956,62 +1918,6 @@ dhd_pno_set_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type,
                        _params->params_gscan.lost_ap_window = ptr->lost_ap_window;
                }
                break;
-               case DHD_PNO_SIGNIFICANT_SCAN_CFG_ID:
-               {
-                       gscan_swc_params_t *ptr = (gscan_swc_params_t *)buf;
-                       dhd_pno_significant_bssid_t *_pno_significant_change_bssid;
-                       wl_pfn_significant_bssid_t *significant_bssid_ptr;
-
-                       if (flush) {
-                               dhd_pno_reset_cfg_gscan(_params, _pno_state,
-                                  GSCAN_FLUSH_SIGNIFICANT_CFG);
-                       }
-
-                       if (!ptr->nbssid) {
-                               break;
-                       }
-
-                       if (!_params->params_gscan.nbssid_significant_change) {
-                               INIT_LIST_HEAD(&_params->params_gscan.significant_bssid_list);
-                       }
-                       if ((_params->params_gscan.nbssid_significant_change +
-                                 ptr->nbssid) > PFN_SWC_MAX_NUM_APS) {
-                               DHD_ERROR(("Excessive number of SWC APs programmed %d\n",
-                                    (_params->params_gscan.nbssid_significant_change +
-                                     ptr->nbssid)));
-                               err = BCME_RANGE;
-                               goto exit;
-                       }
-
-                       for (i = 0, significant_bssid_ptr = ptr->bssid_elem_list;
-                            i < ptr->nbssid; i++, significant_bssid_ptr++) {
-                               _pno_significant_change_bssid =
-                                     kzalloc(sizeof(dhd_pno_significant_bssid_t),
-                                     GFP_KERNEL);
-
-                               if (!_pno_significant_change_bssid) {
-                                       DHD_ERROR(("SWC bssidptr is NULL, cannot kalloc %zd bytes",
-                                       sizeof(dhd_pno_significant_bssid_t)));
-                                       err = BCME_NOMEM;
-                                       goto exit;
-                               }
-                               memcpy(&_pno_significant_change_bssid->BSSID,
-                                   &significant_bssid_ptr->macaddr, ETHER_ADDR_LEN);
-                               _pno_significant_change_bssid->rssi_low_threshold =
-                                   significant_bssid_ptr->rssi_low_threshold;
-                               _pno_significant_change_bssid->rssi_high_threshold =
-                                   significant_bssid_ptr->rssi_high_threshold;
-                               list_add_tail(&_pno_significant_change_bssid->list,
-                                   &_params->params_gscan.significant_bssid_list);
-                       }
-
-                       _params->params_gscan.swc_nbssid_threshold = ptr->swc_threshold;
-                       _params->params_gscan.swc_rssi_window_size = ptr->rssi_window;
-                       _params->params_gscan.lost_ap_window = ptr->lost_ap_window;
-                       _params->params_gscan.nbssid_significant_change += ptr->nbssid;
-
-               }
-               break;
        case DHD_PNO_SCAN_CFG_ID:
                {
                        int k;
@@ -2207,7 +2113,7 @@ dhd_pno_set_for_gscan(dhd_pub_t *dhd, struct dhd_pno_gscan_params *gscan_params)
 
        gscan_param_size = sizeof(wl_pfn_gscan_cfg_t) +
                  (num_buckets_to_fw - 1) * sizeof(wl_pfn_gscan_ch_bucket_cfg_t);
-       pfn_gscan_cfg_t = (wl_pfn_gscan_cfg_t *) MALLOC(dhd->osh, gscan_param_size);
+       pfn_gscan_cfg_t = (wl_pfn_gscan_cfg_t *) MALLOCZ(dhd->osh, gscan_param_size);
 
        if (!pfn_gscan_cfg_t) {
                DHD_ERROR(("%s: failed to malloc memory of size %d\n",
@@ -2222,15 +2128,6 @@ dhd_pno_set_for_gscan(dhd_pub_t *dhd, struct dhd_pno_gscan_params *gscan_params)
        else
                pfn_gscan_cfg_t->buffer_threshold = GSCAN_BATCH_NO_THR_SET;
 
-       if (gscan_params->nbssid_significant_change) {
-               pfn_gscan_cfg_t->swc_nbssid_threshold = gscan_params->swc_nbssid_threshold;
-               pfn_gscan_cfg_t->swc_rssi_window_size = gscan_params->swc_rssi_window_size;
-               pfn_gscan_cfg_t->lost_ap_window = gscan_params->lost_ap_window;
-       } else {
-               pfn_gscan_cfg_t->swc_nbssid_threshold = 0;
-               pfn_gscan_cfg_t->swc_rssi_window_size = 0;
-               pfn_gscan_cfg_t->lost_ap_window = 0;
-       }
        pfn_gscan_cfg_t->flags =
                 (gscan_params->send_all_results_flag & GSCAN_SEND_ALL_RESULTS_MASK);
        pfn_gscan_cfg_t->flags |= GSCAN_ALL_BUCKETS_IN_FIRST_SCAN_MASK;
@@ -2265,45 +2162,6 @@ dhd_pno_set_for_gscan(dhd_pub_t *dhd, struct dhd_pno_gscan_params *gscan_params)
                        __FUNCTION__, err));
                goto exit;
        }
-       if (gscan_params->nbssid_significant_change) {
-               dhd_pno_significant_bssid_t *iter, *next;
-
-               p_pfn_significant_bssid = kzalloc(sizeof(wl_pfn_significant_bssid_t) *
-                                  gscan_params->nbssid_significant_change, GFP_KERNEL);
-               if (p_pfn_significant_bssid == NULL) {
-                       DHD_ERROR(("%s : failed to allocate memory %zd\n",
-                               __FUNCTION__,
-                               sizeof(wl_pfn_significant_bssid_t) *
-                               gscan_params->nbssid_significant_change));
-                       err = BCME_NOMEM;
-                       goto exit;
-               }
-               i = 0;
-               /* convert dhd_pno_significant_bssid_t to wl_pfn_significant_bssid_t */
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-               list_for_each_entry_safe(iter, next, &gscan_params->significant_bssid_list, list) {
-                       p_pfn_significant_bssid[i].rssi_low_threshold = iter->rssi_low_threshold;
-                       p_pfn_significant_bssid[i].rssi_high_threshold = iter->rssi_high_threshold;
-                       memcpy(&p_pfn_significant_bssid[i].macaddr, &iter->BSSID, ETHER_ADDR_LEN);
-                       i++;
-               }
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-               DHD_PNO(("nbssid_significant_change %d \n",
-                       gscan_params->nbssid_significant_change));
-               err = _dhd_pno_add_significant_bssid(dhd, p_pfn_significant_bssid,
-                               gscan_params->nbssid_significant_change);
-               if (err < 0) {
-                       DHD_ERROR(("%s : failed to call _dhd_pno_add_significant_bssid(err :%d)\n",
-                               __FUNCTION__, err));
-                       goto exit;
-               }
-       }
        /* Reprogram ePNO cfg from dhd cache if FW has been flushed */
        if (fw_flushed) {
                dhd_pno_set_epno(dhd);
@@ -2756,7 +2614,8 @@ _dhd_pno_get_gscan_batch_from_fw(dhd_pub_t *dhd)
        tail = gscan_params->gscan_batch_cache;
        while (plbestnet->status != PFN_COMPLETE) {
                memset(plbestnet, 0, PNO_BESTNET_LEN);
-               err = dhd_iovar(dhd, 0, "pfnlbest", (char *)plbestnet, PNO_BESTNET_LEN, 0);
+               err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, (char *)plbestnet, PNO_BESTNET_LEN,
+                               FALSE);
                if (err < 0) {
                        DHD_ERROR(("%s : Cannot get all the batch results, err :%d\n",
                                __FUNCTION__, err));
@@ -2870,13 +2729,8 @@ _dhd_pno_get_gscan_batch_from_fw(dhd_pub_t *dhd)
 
                                DHD_PNO(("\tSSID : "));
                                DHD_PNO(("\n"));
-                               DHD_PNO(("\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                                       result->macaddr.octet[0],
-                                       result->macaddr.octet[1],
-                                       result->macaddr.octet[2],
-                                       result->macaddr.octet[3],
-                                       result->macaddr.octet[4],
-                                       result->macaddr.octet[5]));
+                               DHD_PNO(("\tBSSID: "MACDBG"\n",
+                                       MAC2STRDBG(result->macaddr.octet)));
                                DHD_PNO(("\tchannel: %d, RSSI: %d, timestamp: %d ms\n",
                                        plnetinfo->pfnsubnet.channel,
                                        plnetinfo->RSSI, plnetinfo->timestamp));
@@ -2938,10 +2792,8 @@ dhd_pno_get_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type,
                        ptr->max_scan_cache_size = GSCAN_MAX_AP_CACHE;
                        ptr->max_scan_buckets = GSCAN_MAX_CH_BUCKETS;
                        ptr->max_ap_cache_per_scan = GSCAN_MAX_AP_CACHE_PER_SCAN;
-                       ptr->max_rssi_sample_size = PFN_SWC_RSSI_WINDOW_MAX;
                        ptr->max_scan_reporting_threshold = 100;
                        ptr->max_hotlist_aps = PFN_HOTLIST_MAX_NUM_APS;
-                       ptr->max_significant_wifi_change_aps = PFN_SWC_MAX_NUM_APS;
                        ptr->max_epno_ssid_crc32 = MAX_EPNO_SSID_NUM;
                        ptr->max_epno_hidden_ssid = MAX_EPNO_HIDDEN_SSID;
                        ptr->max_white_list_ssid = MAX_WHITELIST_SSID;
@@ -3140,7 +2992,7 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
        memset(plbestnet, 0, PNO_BESTNET_LEN);
        while (plbestnet->status != PFN_COMPLETE) {
                memset(plbestnet, 0, PNO_BESTNET_LEN);
-               err = dhd_iovar(dhd, 0, "pfnlbest", (char *)plbestnet, PNO_BESTNET_LEN, 0);
+               err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, (char *)plbestnet, PNO_BESTNET_LEN, 0);
                if (err < 0) {
                        if (err == BCME_EPERM) {
                                DHD_ERROR(("we cannot get the batching data "
@@ -3240,13 +3092,8 @@ _dhd_pno_get_for_batch(dhd_pub_t *dhd, char *buf, int bufsize, int reason)
                        for (j = 0; j < plnetinfo->pfnsubnet.SSID_len; j++)
                                DHD_PNO(("%c", plnetinfo->pfnsubnet.u.SSID[j]));
                        DHD_PNO(("\n"));
-                       DHD_PNO(("\tBSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                               plnetinfo->pfnsubnet.BSSID.octet[0],
-                               plnetinfo->pfnsubnet.BSSID.octet[1],
-                               plnetinfo->pfnsubnet.BSSID.octet[2],
-                               plnetinfo->pfnsubnet.BSSID.octet[3],
-                               plnetinfo->pfnsubnet.BSSID.octet[4],
-                               plnetinfo->pfnsubnet.BSSID.octet[5]));
+                       DHD_PNO(("\tBSSID: "MACDBG"\n",
+                               MAC2STRDBG(plnetinfo->pfnsubnet.BSSID.octet)));
                        DHD_PNO(("\tchannel: %d, RSSI: %d, timestamp: %d ms\n",
                                plnetinfo->pfnsubnet.channel,
                                plnetinfo->RSSI, plnetinfo->timestamp));
@@ -3770,96 +3617,6 @@ dhd_retreive_batch_scan_results(dhd_pub_t *dhd)
        return err;
 }
 
-/* Handle Significant WiFi Change (SWC) event from FW
- * Send event to HAL when all results arrive from FW
- */
-void *
-dhd_handle_swc_evt(dhd_pub_t *dhd, const void *event_data, int *send_evt_bytes)
-{
-       void *ptr = NULL;
-       dhd_pno_status_info_t *_pno_state = PNO_GET_PNOSTATE(dhd);
-       struct dhd_pno_gscan_params *gscan_params;
-       struct dhd_pno_swc_evt_param *params;
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-qual"
-#endif
-       wl_pfn_swc_results_t *results = (wl_pfn_swc_results_t *)event_data;
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-       wl_pfn_significant_net_t *change_array;
-       int i;
-
-       gscan_params = &(_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan);
-       params = &(gscan_params->param_significant);
-
-       if (!results->total_count) {
-               *send_evt_bytes = 0;
-               return ptr;
-       }
-
-       if (!params->results_rxed_so_far) {
-               if (!params->change_array) {
-                       params->change_array = (wl_pfn_significant_net_t *)
-                       kmalloc(sizeof(wl_pfn_significant_net_t) * results->total_count,
-                       GFP_KERNEL);
-
-                       if (!params->change_array) {
-                               DHD_ERROR(("%s Cannot Malloc %zd bytes!!\n", __FUNCTION__,
-                               sizeof(wl_pfn_significant_net_t) * results->total_count));
-                               *send_evt_bytes = 0;
-                               return ptr;
-                       }
-               } else {
-                       DHD_ERROR(("RX'ed WLC_E_PFN_SWC evt from FW, previous evt not complete!!"));
-                       *send_evt_bytes = 0;
-                       return ptr;
-               }
-
-       }
-
-       DHD_PNO(("%s: pkt_count %d total_count %d\n", __FUNCTION__,
-       results->pkt_count, results->total_count));
-
-       for (i = 0; i < results->pkt_count; i++) {
-               DHD_PNO(("\t %02x:%02x:%02x:%02x:%02x:%02x\n",
-               results->list[i].BSSID.octet[0],
-               results->list[i].BSSID.octet[1],
-               results->list[i].BSSID.octet[2],
-               results->list[i].BSSID.octet[3],
-               results->list[i].BSSID.octet[4],
-               results->list[i].BSSID.octet[5]));
-       }
-
-       change_array = &params->change_array[params->results_rxed_so_far];
-       if ((params->results_rxed_so_far + results->pkt_count) <= results->total_count) {
-               memcpy(change_array, results->list,
-               sizeof(wl_pfn_significant_net_t) * results->pkt_count);
-               params->results_rxed_so_far += results->pkt_count;
-       } else {
-               /* In case of spurious event or invalid data send hang event */
-               dhd->hang_reason = HANG_REASON_INVALID_EVENT_OR_DATA;
-               dhd_os_send_hang_message(dhd);
-       }
-
-       if (params->results_rxed_so_far == results->total_count) {
-               params->results_rxed_so_far = 0;
-               *send_evt_bytes = sizeof(wl_pfn_significant_net_t) * results->total_count;
-               /* Pack up change buffer to send up and reset
-                * results_rxed_so_far, after its done.
-                */
-               ptr = (void *) params->change_array;
-               /* expecting the callee to free this mem chunk */
-               params->change_array = NULL;
-       }
-       else {
-               *send_evt_bytes = 0;
-       }
-
-       return ptr;
-}
-
 void
 dhd_gscan_hotlist_cache_cleanup(dhd_pub_t *dhd, hotlist_type_t type)
 {
@@ -3890,7 +3647,7 @@ dhd_gscan_hotlist_cache_cleanup(dhd_pub_t *dhd, hotlist_type_t type)
 }
 
 void *
-dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, int *size)
+dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, uint32 len, int *size)
 {
        wl_bss_info_t *bi = NULL;
        wl_gscan_result_t *gscan_result;
@@ -3899,6 +3656,8 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, int *size)
        uint8 channel;
        uint32 mem_needed;
        struct timespec ts;
+       u32 bi_ie_length = 0;
+       u32 bi_ie_offset = 0;
 
        *size = 0;
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
@@ -3914,6 +3673,15 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, int *size)
                goto exit;
        }
 
+       if ((len < sizeof(*gscan_result)) ||
+           (len < dtoh32(gscan_result->buflen)) ||
+           (dtoh32(gscan_result->buflen) >
+           (sizeof(*gscan_result) + WL_SCAN_IE_LEN_MAX))) {
+               DHD_ERROR(("%s: invalid gscan buflen:%u\n", __FUNCTION__,
+                       dtoh32(gscan_result->buflen)));
+               goto exit;
+       }
+
        bi = &gscan_result->bss_info[0].info;
        bi_length = dtoh32(bi->length);
        if (bi_length != (dtoh32(gscan_result->buflen) -
@@ -3921,14 +3689,19 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, int *size)
                DHD_ERROR(("Invalid bss_info length %d: ignoring\n", bi_length));
                goto exit;
        }
+       bi_ie_offset = dtoh32(bi->ie_offset);
+       bi_ie_length = dtoh32(bi->ie_length);
+       if ((bi_ie_offset + bi_ie_length) > bi_length) {
+               DHD_ERROR(("%s: Invalid ie_length:%u or ie_offset:%u\n",
+                       __FUNCTION__, bi_ie_length, bi_ie_offset));
+               goto exit;
+       }
        if (bi->SSID_len > DOT11_MAX_SSID_LEN) {
-               DHD_ERROR(("Invalid SSID length %d: trimming it to max\n", bi->SSID_len));
-               bi->SSID_len = DOT11_MAX_SSID_LEN;
+               DHD_ERROR(("%s: Invalid SSID length:%u\n", __FUNCTION__, bi->SSID_len));
+               goto exit;
        }
-
-       mem_needed = OFFSETOF(wifi_gscan_full_result_t, ie_data) + bi->ie_length;
+       mem_needed = OFFSETOF(wifi_gscan_full_result_t, ie_data) + bi_ie_length;
        result = (wifi_gscan_full_result_t *) kmalloc(mem_needed, GFP_KERNEL);
-
        if (!result) {
                DHD_ERROR(("%s Cannot malloc scan result buffer %d bytes\n",
                  __FUNCTION__, mem_needed));
@@ -3948,9 +3721,9 @@ dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *data, int *size)
        result->fixed.ts = (uint64) TIMESPEC_TO_US(ts);
        result->fixed.beacon_period = dtoh16(bi->beacon_period);
        result->fixed.capability = dtoh16(bi->capability);
-       result->ie_length = dtoh32(bi->ie_length);
+       result->ie_length = bi_ie_length;
        memcpy(&result->fixed.macaddr, &bi->BSSID, ETHER_ADDR_LEN);
-       memcpy(result->ie_data, ((uint8 *)bi + bi->ie_offset), bi->ie_length);
+       memcpy(result->ie_data, ((uint8 *)bi + bi_ie_offset), bi_ie_length);
        *size = mem_needed;
 exit:
        return result;
@@ -3986,6 +3759,14 @@ dhd_pno_process_epno_result(dhd_pub_t *dhd, const void *data, uint32 event, int
                                  pfn_result->version, PFN_SCANRESULT_VERSION));
                        return NULL;
                }
+               /* Check if count of pfn results is corrupted */
+               if (pfn_result->count > EVENT_MAX_NETCNT_V2) {
+                       DHD_ERROR(("%s event %d: pfn results count %d"
+                               "exceeds the max limit\n", __FUNCTION__, event,
+                               pfn_result->count));
+                       return NULL;
+               }
+
                count = pfn_result->count;
                mem_needed = sizeof(dhd_epno_results_t) * count;
                results = (dhd_epno_results_t *) kmalloc(mem_needed, GFP_KERNEL);
@@ -4014,12 +3795,9 @@ dhd_pno_process_epno_result(dhd_pub_t *dhd, const void *data, uint32 event, int
                        }
                        memcpy(ssid, results[i].ssid, results[i].ssid_len);
                        ssid[results[i].ssid_len] = '\0';
-                       DHD_PNO(("ssid - %s bssid %02x:%02x:%02x:%02x:%02x:%02x "
-                               "ch %d rssi %d flags %d\n", ssid,
-                               bssid->octet[0], bssid->octet[1],
-                               bssid->octet[2], bssid->octet[3],
-                               bssid->octet[4], bssid->octet[5],
-                               results[i].channel, results[i].rssi, results[i].flags));
+                       DHD_PNO(("ssid - %s bssid "MACDBG" ch %d rssi %d flags %d\n",
+                               ssid, MAC2STRDBG(bssid->octet), results[i].channel,
+                               results[i].rssi, results[i].flags));
                }
        }
        *size = mem_needed;
@@ -4049,7 +3827,8 @@ dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data,
 
        gscan_params = &(_pno_state->pno_params_arr[INDEX_OF_GSCAN_PARAMS].params_gscan);
 
-       if (!results->count) {
+       if ((results->count == 0) || (results->count > EVENT_MAX_NETCNT_V2)) {
+               DHD_ERROR(("%s: wrong result count:%d\n", __FUNCTION__, results->count));
                *send_evt_bytes = 0;
                return ptr;
        }
@@ -4100,14 +3879,10 @@ dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data,
                hotlist_found_array->ssid[plnetinfo->pfnsubnet.SSID_len] = '\0';
 
                memcpy(&hotlist_found_array->macaddr, &plnetinfo->pfnsubnet.BSSID, ETHER_ADDR_LEN);
-               DHD_PNO(("\t%s %02x:%02x:%02x:%02x:%02x:%02x rssi %d\n", hotlist_found_array->ssid,
-               hotlist_found_array->macaddr.octet[0],
-               hotlist_found_array->macaddr.octet[1],
-               hotlist_found_array->macaddr.octet[2],
-               hotlist_found_array->macaddr.octet[3],
-               hotlist_found_array->macaddr.octet[4],
-               hotlist_found_array->macaddr.octet[5],
-               hotlist_found_array->rssi));
+               DHD_PNO(("\t%s "MACDBG" rssi %d\n",
+                       hotlist_found_array->ssid,
+                       MAC2STRDBG(hotlist_found_array->macaddr.octet),
+                       hotlist_found_array->rssi));
        }
 
 
@@ -4174,6 +3949,7 @@ int dhd_pno_init(dhd_pub_t *dhd)
 {
        int err = BCME_OK;
        dhd_pno_status_info_t *_pno_state;
+       char *buf = NULL;
        NULL_CHECK(dhd, "dhd is NULL", err);
        DHD_PNO(("%s enter\n", __FUNCTION__));
        UNUSED_PARAMETER(_dhd_pno_suspend);
@@ -4192,7 +3968,13 @@ int dhd_pno_init(dhd_pub_t *dhd)
 #ifdef GSCAN_SUPPORT
        init_waitqueue_head(&_pno_state->batch_get_wait);
 #endif /* GSCAN_SUPPORT */
-       err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, 0);
+       buf = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL);
+       if (!buf) {
+               DHD_ERROR((":%s buf alloc err.\n", __FUNCTION__));
+               return BCME_NOMEM;
+       }
+       err = dhd_iovar(dhd, 0, "pfnlbest", NULL, 0, buf, WLC_IOCTL_SMLEN,
+                       FALSE);
        if (err == BCME_UNSUPPORTED) {
                _pno_state->wls_supported = FALSE;
                DHD_INFO(("Current firmware doesn't support"
@@ -4202,6 +3984,7 @@ int dhd_pno_init(dhd_pub_t *dhd)
                        __FUNCTION__));
        }
 exit:
+       kfree(buf);
        return err;
 }
 int dhd_pno_deinit(dhd_pub_t *dhd)
index 26a450aa01d268ceb5bbc50c98dd5b392cdc594e..60db69a3f167121e7182db468867d70296eb6da8 100644 (file)
@@ -2,7 +2,7 @@
  * Header file of Broadcom Dongle Host Driver (DHD)
  * Prefered Network Offload code and Wi-Fi Location Service(WLS) code.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -25,7 +25,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_pno.h 674729 2016-12-12 07:01:08Z $
+ * $Id: dhd_pno.h 707287 2017-06-27 06:44:29Z $
  */
 
 #ifndef __DHD_PNO_H__
@@ -349,11 +349,6 @@ typedef struct dhd_epno_results {
        struct ether_addr bssid;
 } dhd_epno_results_t;
 
-typedef struct dhd_pno_swc_evt_param {
-       uint16 results_rxed_so_far;
-       wl_pfn_significant_net_t *change_array;
-} dhd_pno_swc_evt_param_t;
-
 typedef struct wifi_gscan_result {
        uint64 ts;                           /* Time of discovery           */
        char ssid[DOT11_MAX_SSID_LEN+1];     /* null terminated             */
@@ -408,8 +403,6 @@ struct dhd_pno_gscan_params {
        uint8 bestn;
        uint8 mscan;
        uint8 buffer_threshold;
-       uint8 swc_nbssid_threshold;
-       uint8 swc_rssi_window_size;
        uint8 lost_ap_window;
        uint8 nchannel_buckets;
        uint8 reason;
@@ -419,12 +412,9 @@ struct dhd_pno_gscan_params {
        gscan_results_cache_t *gscan_batch_cache;
        gscan_results_cache_t *gscan_hotlist_found;
        gscan_results_cache_t *gscan_hotlist_lost;
-       uint16 nbssid_significant_change;
        uint16 nbssid_hotlist;
-       struct dhd_pno_swc_evt_param param_significant;
        struct dhd_pno_gscan_channel_bucket channel_bucket[GSCAN_MAX_CH_BUCKETS];
        struct list_head hotlist_bssid_list;
-       struct list_head significant_bssid_list;
        dhd_epno_ssid_cfg_t epno_cfg;
        uint32 scan_id;
 };
@@ -452,26 +442,6 @@ typedef struct gscan_hotlist_scan_params {
        struct bssid_t bssid[1];  /* n bssids to follow */
 } gscan_hotlist_scan_params_t;
 
-/* SWC (Significant WiFi Change) params */
-typedef struct gscan_swc_params {
-       /* Rssi averaging window size */
-       uint8 rssi_window;
-       /* Number of scans that the AP has to be absent before
-        * being declared LOST
-        */
-       uint8 lost_ap_window;
-       /* if x  Aps have a significant change generate an event. */
-       uint8 swc_threshold;
-       uint8 nbssid;
-       wl_pfn_significant_bssid_t bssid_elem_list[1];
-} gscan_swc_params_t;
-
-typedef struct dhd_pno_significant_bssid {
-       struct ether_addr BSSID;
-       int8 rssi_low_threshold;
-       int8 rssi_high_threshold;
-       struct list_head list;
-} dhd_pno_significant_bssid_t;
 #endif /* GSCAN_SUPPORT || DHD_GET_VALID_CHANNELS */
 typedef union dhd_pno_params {
        struct dhd_pno_legacy_params params_legacy;
@@ -534,13 +504,11 @@ int dhd_dev_pno_lock_access_batch_results(struct net_device *dev);
 void dhd_dev_pno_unlock_access_batch_results(struct net_device *dev);
 extern int dhd_dev_pno_run_gscan(struct net_device *dev, bool run, bool flush);
 extern int dhd_dev_pno_enable_full_scan_result(struct net_device *dev, bool real_time);
-extern void * dhd_dev_swc_scan_event(struct net_device *dev, const void  *data,
-              int *send_evt_bytes);
 int dhd_retreive_batch_scan_results(dhd_pub_t *dhd);
 extern void * dhd_dev_hotlist_scan_event(struct net_device *dev,
             const void  *data, int *send_evt_bytes, hotlist_type_t type);
 void * dhd_dev_process_full_gscan_result(struct net_device *dev,
-            const void  *data, int *send_evt_bytes);
+            const void  *data, uint32 len, int *send_evt_bytes);
 extern int dhd_dev_gscan_batch_cache_cleanup(struct net_device *dev);
 extern void dhd_dev_gscan_hotlist_cache_cleanup(struct net_device *dev, hotlist_type_t type);
 extern int dhd_dev_wait_batch_results_complete(struct net_device *dev);
@@ -585,11 +553,10 @@ extern int dhd_pno_initiate_gscan_request(dhd_pub_t *dhd, bool run, bool flush);
 extern int dhd_pno_enable_full_scan_result(dhd_pub_t *dhd, bool real_time_flag);
 extern int dhd_pno_cfg_gscan(dhd_pub_t *dhd, dhd_pno_gscan_cmd_cfg_t type, void *buf);
 extern int dhd_dev_retrieve_batch_scan(struct net_device *dev);
-extern void *dhd_handle_swc_evt(dhd_pub_t *dhd, const void *event_data, int *send_evt_bytes);
 extern void *dhd_handle_hotlist_scan_evt(dhd_pub_t *dhd, const void *event_data,
                        int *send_evt_bytes, hotlist_type_t type);
 extern void *dhd_process_full_gscan_result(dhd_pub_t *dhd, const void *event_data,
-                       int *send_evt_bytes);
+                       uint32 len, int *send_evt_bytes);
 extern int dhd_gscan_batch_cache_cleanup(dhd_pub_t *dhd);
 extern void dhd_gscan_hotlist_cache_cleanup(dhd_pub_t *dhd, hotlist_type_t type);
 extern int dhd_wait_batch_results_complete(dhd_pub_t *dhd);
index 820e3449fa3ad4cafc2a0b3f236c89097e80019a..ec237ef2b2d154faa8742a3cdaba8a793c77dc08 100644 (file)
@@ -4,7 +4,7 @@
  * Provides type definitions and function prototypes used to link the
  * DHD OS, bus, and protocol modules.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_proto.h 678890 2017-01-11 11:48:36Z $
+ * $Id: dhd_proto.h 727682 2017-10-23 04:45:57Z $
  */
 
 #ifndef _dhd_proto_h_
@@ -136,7 +136,8 @@ extern int dhdmsgbuf_lpbk_req(dhd_pub_t *dhd, uint len);
 extern void dhd_prot_rx_dataoffset(dhd_pub_t *dhd, uint32 offset);
 extern int dhd_prot_txdata(dhd_pub_t *dhd, void *p, uint8 ifidx);
 extern int dhdmsgbuf_dmaxfer_req(dhd_pub_t *dhd,
-       uint len, uint srcdelay, uint destdelay, uint d11_lpbk);
+       uint len, uint srcdelay, uint destdelay, uint d11_lpbk, uint core_num);
+extern dma_xfer_status_t dhdmsgbuf_dmaxfer_status(dhd_pub_t *dhd);
 
 extern void dhd_dma_buf_init(dhd_pub_t *dhd, void *dma_buf,
        void *va, uint32 len, dmaaddr_t pa, void *dmah, void *secdma);
index 55c7825da09dfee028afc5ed6a3c02d2a7f4d22b..8878e43f0a5a4e1c4de66ebaa25540f6b05960aa 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom Dongle Host Driver (DHD), RTT
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -817,7 +817,7 @@ dhd_rtt_common_set_handler(dhd_pub_t *dhd, const ftm_subcmd_info_t *p_subcmd_inf
                return BCME_NOMEM;
 
        /* no TLV to pack, simply issue a set-proxd iovar */
-       ret = dhd_iovar(dhd, 0, "proxd", (void *) p_proxd_iov, proxd_iovsize, 1);
+       ret = dhd_iovar(dhd, 0, "proxd", (char *)p_proxd_iov, proxd_iovsize, NULL, 0, TRUE);
 #ifdef RTT_DEBUG
        if (ret != BCME_OK) {
                DHD_RTT(("error: IOVAR failed, status=%d\n", ret));
@@ -1100,7 +1100,7 @@ dhd_rtt_ftm_config(dhd_pub_t *dhd, wl_proxd_session_id_t session_id,
                all_tlvsize = (bufsize - buf_space_left);
                p_proxd_iov->len = htol16(all_tlvsize + WL_PROXD_IOV_HDR_SIZE);
                ret = dhd_iovar(dhd, 0, "proxd", (char *)p_proxd_iov,
-                       all_tlvsize + WL_PROXD_IOV_HDR_SIZE, 1);
+                               all_tlvsize + WL_PROXD_IOV_HDR_SIZE, NULL, 0, TRUE);
                if (ret != BCME_OK) {
                        DHD_ERROR(("%s : failed to set config\n", __FUNCTION__));
                }
@@ -1331,11 +1331,11 @@ dhd_rtt_start(dhd_pub_t *dhd)
                DHD_RTT(("RTT is stopped\n"));
                goto exit;
        }
-       err = wldev_ioctl(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm), false);
+       err = wldev_ioctl_get(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm));
        if (err) {
                DHD_ERROR(("Failed to get the PM value\n"));
        } else {
-               err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+               err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm));
                if (err) {
                        DHD_ERROR(("Failed to set the PM\n"));
                        rtt_status->pm_restore = FALSE;
@@ -1497,7 +1497,7 @@ exit:
                        DHD_ERROR(("pm_restore =%d func =%s \n",
                                rtt_status->pm_restore, __FUNCTION__));
                        pm = PM_FAST;
-                       err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+                       err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm));
                        if (err) {
                                DHD_ERROR(("Failed to set PM \n"));
                        } else {
@@ -1757,20 +1757,13 @@ dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
        rtt_results_header_t *entry, *rtt_results_header = NULL;
 #endif /* WL_CFG80211 */
 
+       DHD_RTT(("Enter %s \n", __FUNCTION__));
        NULL_CHECK(dhd, "dhd is NULL", ret);
+
 #ifdef WL_CFG80211
        rtt_status = GET_RTTSTATE(dhd);
        NULL_CHECK(rtt_status, "rtt_status is NULL", ret);
-#endif /* WL_CFG80211 */
-
-       event_type = ntoh32_ua((void *)&event->event_type);
 
-       DHD_RTT(("Enter %s \n", __FUNCTION__));
-       if (event_type != WLC_E_PROXD) {
-               DHD_ERROR((" failed event \n"));
-               return ret;
-       }
-#ifdef WL_CFG80211
        if (RTT_IS_STOPPED(rtt_status)) {
                /* Ignore the Proxd event */
                DHD_RTT((" event handler rtt is stopped \n"));
@@ -1781,6 +1774,21 @@ dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
                }
        }
 #endif /* WL_CFG80211 */
+       if (ntoh32_ua((void *)&event->datalen) < OFFSETOF(wl_proxd_event_t, tlvs)) {
+               DHD_RTT(("%s: wrong datalen:%d\n", __FUNCTION__,
+                       ntoh32_ua((void *)&event->datalen)));
+               return -EINVAL;
+       }
+       event_type = ntoh32_ua((void *)&event->event_type);
+       if (event_type != WLC_E_PROXD) {
+               DHD_ERROR((" failed event \n"));
+               return -EINVAL;
+       }
+
+       if (!event_data) {
+               DHD_ERROR(("%s: event_data:NULL\n", __FUNCTION__));
+               return -EINVAL;
+       }
        p_event = (wl_proxd_event_t *) event_data;
        version = ltoh16(p_event->version);
        if (version < WL_PROXD_API_VERSION) {
@@ -1802,9 +1810,15 @@ dhd_rtt_event_handler(dhd_pub_t *dhd, wl_event_msg_t *event, void *event_data)
        p_loginfo = ftm_get_event_type_loginfo(event_type);
        if (p_loginfo == NULL) {
                DHD_ERROR(("receive an invalid FTM event %d\n", event_type));
+               ret = -EINVAL;
                goto exit;      /* ignore this event */
        }
        /* get TLVs len, skip over event header */
+       if (ltoh16(p_event->len) < OFFSETOF(wl_proxd_event_t, tlvs)) {
+               DHD_ERROR(("invalid FTM event length:%d\n", ltoh16(p_event->len)));
+               ret = -EINVAL;
+               goto exit;
+       }
        tlvs_len = ltoh16(p_event->len) - OFFSETOF(wl_proxd_event_t, tlvs);
        DHD_RTT(("receive '%s' event: version=0x%x len=%d method=%d sid=%d tlvs_len=%d\n",
                p_loginfo->text,
@@ -2201,12 +2215,12 @@ dhd_rtt_enable_responder(dhd_pub_t *dhd, wifi_channel_info *channel_info)
                        DHD_ERROR(("Failed to set the chanspec \n"));
                }
        }
-       err = wldev_ioctl(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm), false);
+       err = wldev_ioctl_get(dev, WLC_GET_PM, &rtt_status->pm, sizeof(rtt_status->pm));
        DHD_RTT(("Current PM value read %d\n", rtt_status->pm));
        if (err) {
                DHD_ERROR(("Failed to get the PM value \n"));
        } else {
-               err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+               err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm));
                if (err) {
                        DHD_ERROR(("Failed to set the PM \n"));
                        rtt_status->pm_restore = FALSE;
@@ -2240,7 +2254,7 @@ exit:
                DHD_RTT(("restoring the PM value \n"));
                if (rtt_status->pm_restore) {
                        pm = PM_FAST;
-                       err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+                       err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm));
                        if (err) {
                                DHD_ERROR(("Failed to restore PM \n"));
                        } else {
@@ -2270,7 +2284,7 @@ dhd_rtt_cancel_responder(dhd_pub_t *dhd)
        if (rtt_status->pm_restore) {
                pm = PM_FAST;
                DHD_RTT(("pm_restore =%d \n", rtt_status->pm_restore));
-               err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+               err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm));
                if (err) {
                        DHD_ERROR(("Failed to restore PM \n"));
                } else {
index b3ca820b747823c24e8decea134bd3e557ab367c..df5f03e2dde9090f2bf3206fd73d81fbef2ddfb1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom Dongle Host Driver (DHD), RTT
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ba5dbc3e69e3acad31cb1e231c12f0a67344afc8..dbaf9da551d66c8a3d7d7bc464c22c8f69e548ac 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DHD Bus Module for SDIO
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_sdio.c 685082 2017-02-15 10:04:17Z $
+ * $Id: dhd_sdio.c 749762 2018-03-02 01:20:46Z $
  */
 
 #include <typedefs.h>
@@ -755,6 +755,11 @@ static int _dhdsdio_download_btfw(struct dhd_bus *bus);
 static int dhd_bus_ulp_reinit_fw(dhd_bus_t *bus);
 #endif /* DHD_ULP */
 
+#ifdef DHD_WAKE_STATUS
+int bcmsdh_get_total_wake(bcmsdh_info_t *bcmsdh);
+int bcmsdh_set_get_wake(bcmsdh_info_t *bcmsdh, int flag);
+#endif /* DHD_WAKE_STATUS */
+
 static void
 dhdsdio_tune_fifoparam(struct dhd_bus *bus)
 {
@@ -905,6 +910,7 @@ dhdsdio_sr_cap(dhd_bus_t *bus)
                (bus->sih->chip == BCM43349_CHIP_ID) ||
                BCM4345_CHIP(bus->sih->chip) ||
                (bus->sih->chip == BCM4354_CHIP_ID) ||
+               (bus->sih->chip == BCM43569_CHIP_ID) ||
                (bus->sih->chip == BCM4358_CHIP_ID) ||
                (BCM4349_CHIP(bus->sih->chip))          ||
                (bus->sih->chip == BCM4350_CHIP_ID) ||
@@ -928,6 +934,7 @@ dhdsdio_sr_cap(dhd_bus_t *bus)
                (bus->sih->chip == BCM43349_CHIP_ID) ||
                BCM4345_CHIP(bus->sih->chip) ||
                (bus->sih->chip == BCM4354_CHIP_ID) ||
+               (bus->sih->chip == BCM43569_CHIP_ID) ||
                (bus->sih->chip == BCM4358_CHIP_ID) ||
                (bus->sih->chip == BCM4350_CHIP_ID)) {
                uint32 enabval = 0;
@@ -939,6 +946,7 @@ dhdsdio_sr_cap(dhd_bus_t *bus)
                if ((bus->sih->chip == BCM4350_CHIP_ID) ||
                        BCM4345_CHIP(bus->sih->chip) ||
                        (bus->sih->chip == BCM4354_CHIP_ID) ||
+                       (bus->sih->chip == BCM43569_CHIP_ID) ||
                        (bus->sih->chip == BCM4358_CHIP_ID))
                        enabval &= CC_CHIPCTRL3_SR_ENG_ENABLE;
 
@@ -2531,6 +2539,9 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
 #ifdef DHD_LOSSLESS_ROAMING
        uint8 *pktdata;
        struct ether_header *eh;
+#ifdef BDC
+       struct bdc_header *bdc_header;
+#endif
 #endif /* DHD_LOSSLESS_ROAMING */
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -2575,6 +2586,7 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
                        pktdata = (uint8 *)PKTDATA(osh, pkts[i]);
 #ifdef BDC
                        /* Skip BDC header */
+                       bdc_header = (struct bdc_header *)pktdata;
                        pktdata += BDC_HEADER_LEN + ((struct bdc_header *)pktdata)->dataOffset;
 #endif
                        eh = (struct ether_header *)pktdata;
@@ -2584,6 +2596,11 @@ dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes)
                                /* Restore to original priority for 802.1X packet */
                                if (prio == PRIO_8021D_NC) {
                                        PKTSETPRIO(pkts[i], dhd->prio_8021x);
+#ifdef BDC
+                                       /* Restore to original priority in BDC header */
+                                       bdc_header->priority =
+                                               (dhd->prio_8021x & BDC_PRIORITY_MASK);
+#endif
                                }
                        }
 #endif /* DHD_LOSSLESS_ROAMING */
@@ -2788,7 +2805,8 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
                        }
 #ifdef DHD_FW_COREDUMP
                        /* Collect socram dump */
-                       if (bus->dhd->memdump_enabled) {
+                       if ((bus->dhd->memdump_enabled) &&
+                               (bus->dhd->txcnt_timeout >= MAX_CNTL_TX_TIMEOUT)) {
                                /* collect core dump */
                                bus->dhd->memdump_type = DUMP_TYPE_RESUMED_ON_TIMEOUT_TX;
                                dhd_os_sdunlock(bus->dhd);
@@ -2960,7 +2978,6 @@ enum {
        IOV_SDREG,
        IOV_SBREG,
        IOV_SDCIS,
-       IOV_MEMBYTES,
        IOV_RAMSIZE,
        IOV_RAMSTART,
 #ifdef DHD_DEBUG
@@ -3015,7 +3032,6 @@ const bcm_iovar_t dhdsdio_iovars[] = {
        {"idletime",    IOV_IDLETIME,   0, 0,   IOVT_INT32,     0 },
        {"idleclock",   IOV_IDLECLOCK,  0, 0,   IOVT_INT32,     0 },
        {"sd1idle",     IOV_SD1IDLE,    0, 0,   IOVT_BOOL,      0 },
-       {"membytes",    IOV_MEMBYTES,   0, 0,   IOVT_BUFFER,    2 * sizeof(int) },
        {"ramsize",     IOV_RAMSIZE,    0, 0,   IOVT_UINT32,    0 },
        {"ramstart",    IOV_RAMSTART,   0, 0,   IOVT_UINT32,    0 },
        {"dwnldstate",  IOV_SET_DOWNLOAD_STATE, 0, 0,   IOVT_BOOL,      0 },
@@ -4000,94 +4016,6 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, uint32 actionid, const ch
                break;
 
 
-       case IOV_SVAL(IOV_MEMBYTES):
-       case IOV_GVAL(IOV_MEMBYTES):
-       {
-               uint32 address;
-               uint size, dsize;
-               uint8 *data;
-
-               bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
-
-               ASSERT(plen >= 2*sizeof(int));
-
-               address = (uint32)int_val;
-               bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val));
-               size = (uint)int_val;
-
-               /* Do some validation */
-               dsize = set ? plen - (2 * sizeof(int)) : len;
-               if (dsize < size) {
-                       DHD_ERROR(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n",
-                                  __FUNCTION__, (set ? "set" : "get"), address, size, dsize));
-                       bcmerror = BCME_BADARG;
-                       break;
-               }
-
-               DHD_INFO(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__,
-                         (set ? "write" : "read"), size, address));
-
-               /* check if CR4 */
-               if (si_setcore(bus->sih, ARMCR4_CORE_ID, 0)) {
-                       /*
-                        * If address is start of RAM (i.e. a downloaded image),
-                        * store the reset instruction to be written in 0
-                        */
-                       if (set && address == bus->dongle_ram_base) {
-                               bus->resetinstr = *(((uint32*)params) + 2);
-                       }
-               } else {
-               /* If we know about SOCRAM, check for a fit */
-               if ((bus->orig_ramsize) &&
-                   ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize)))
-               {
-                       uint8 enable, protect, remap;
-                       si_socdevram(bus->sih, FALSE, &enable, &protect, &remap);
-                       if (!enable || protect) {
-                               DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d bytes at 0x%08x\n",
-                                       __FUNCTION__, bus->orig_ramsize, size, address));
-                               DHD_ERROR(("%s: socram enable %d, protect %d\n",
-                                       __FUNCTION__, enable, protect));
-                               bcmerror = BCME_BADARG;
-                               break;
-                       }
-
-                       if (!REMAP_ENAB(bus) && (address >= SOCDEVRAM_ARM_ADDR)) {
-                               uint32 devramsize = si_socdevram_size(bus->sih);
-                               if ((address < SOCDEVRAM_ARM_ADDR) ||
-                                       (address + size > (SOCDEVRAM_ARM_ADDR + devramsize))) {
-                                       DHD_ERROR(("%s: bad address 0x%08x, size 0x%08x\n",
-                                               __FUNCTION__, address, size));
-                                       DHD_ERROR(("%s: socram range 0x%08x,size 0x%08x\n",
-                                               __FUNCTION__, SOCDEVRAM_ARM_ADDR, devramsize));
-                                       bcmerror = BCME_BADARG;
-                                       break;
-                               }
-                               /* move it such that address is real now */
-                               address -= SOCDEVRAM_ARM_ADDR;
-                               address += SOCDEVRAM_BP_ADDR;
-                               DHD_INFO(("%s: Request to %s %d bytes @ Mapped address 0x%08x\n",
-                                       __FUNCTION__, (set ? "write" : "read"), size, address));
-                       } else if (REMAP_ENAB(bus) && REMAP_ISADDR(bus, address) && remap) {
-                               /* Can not access remap region while devram remap bit is set
-                                * ROM content would be returned in this case
-                                */
-                               DHD_ERROR(("%s: Need to disable remap for address 0x%08x\n",
-                                       __FUNCTION__, address));
-                               bcmerror = BCME_ERROR;
-                               break;
-                       }
-               }
-               }
-
-               /* Generate the actual data pointer */
-               data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg;
-
-               /* Call to do the transfer */
-               bcmerror = dhdsdio_membytes(bus, set, address, data, size);
-
-               break;
-       }
 
        case IOV_GVAL(IOV_RAMSIZE):
                int_val = (int32)bus->ramsize;
@@ -4940,8 +4868,10 @@ dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex)
                 */
                dhd_tcpack_info_tbl_clean(bus->dhd);
 #endif /* DHDTCPACK_SUPPRESS */
+               dhd_os_sdlock_txq(bus->dhd);
                /* Clear the data packet queues */
                pktq_flush(osh, &bus->txq, TRUE);
+               dhd_os_sdunlock_txq(bus->dhd);
        }
 
        /* Clear any held glomming stuff */
@@ -4979,7 +4909,6 @@ dhd_txglom_enable(dhd_pub_t *dhdp, bool enable)
         */
        dhd_bus_t *bus = dhdp->bus;
 #ifdef BCMSDIOH_TXGLOM
-       char buf[256];
        uint32 rxglom;
        int32 ret;
 
@@ -4992,9 +4921,8 @@ dhd_txglom_enable(dhd_pub_t *dhdp, bool enable)
 
        if (enable) {
                rxglom = 1;
-               memset(buf, 0, sizeof(buf));
-               bcm_mkiovar("bus:rxglom", (void *)&rxglom, 4, buf, sizeof(buf));
-               ret = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
+               ret = dhd_iovar(dhdp, 0, "bus:rxglom", (char *)&rxglom, sizeof(rxglom), NULL, 0,
+                               TRUE);
                if (ret >= 0)
                        bus->txglom_enable = TRUE;
                else {
@@ -5360,13 +5288,8 @@ int
 dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len,
        void **pkt, uint32 *pkt_count);
 
-#ifdef DHD_WAKE_STATUS
-static uint8
-dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq, int pkt_wake)
-#else
 static uint8
 dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
-#endif /* DHD_WAKE_STATUS */
 {
        uint16 dlen, totlen;
        uint8 *dptr, num = 0;
@@ -5777,13 +5700,7 @@ dhdsdio_rxglom(dhd_bus_t *bus, uint8 rxseq)
                                } while (temp);
                                if (cnt) {
                                        dhd_os_sdunlock(bus->dhd);
-#ifdef DHD_WAKE_STATUS
-                                       dhd_rx_frame(bus->dhd, idx, list_head[idx], cnt, 0,
-                                               pkt_wake, &bus->wake_counts);
-                                       pkt_wake = 0;
-#else
                                        dhd_rx_frame(bus->dhd, idx, list_head[idx], cnt, 0);
-#endif /* DHD_WAKE_STATUS */
                                        dhd_os_sdlock(bus->dhd);
                                }
                        }
@@ -5829,10 +5746,6 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
        bool sdtest = FALSE;    /* To limit message spew from test mode */
 #endif
 
-#ifdef DHD_WAKE_STATUS
-       int pkt_wake = bcmsdh_set_get_wake(bus->sdh, 0);
-#endif
-
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
        bus->readframes = TRUE;
 
@@ -5926,12 +5839,7 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished)
                        uint8 cnt;
                        DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n",
                                  __FUNCTION__, bus->glomd, bus->glom));
-#ifdef DHD_WAKE_STATUS
-                       cnt = dhdsdio_rxglom(bus, rxseq, pkt_wake);
-                       pkt_wake = 0;
-#else
                        cnt = dhdsdio_rxglom(bus, rxseq);
-#endif /* DHD_WAKE_STATUS */
                        DHD_GLOM(("%s: rxglom returned %d\n", __FUNCTION__, cnt));
                        rxseq += cnt - 1;
                        rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
@@ -6521,12 +6429,7 @@ deliver:
 
                /* Unlock during rx call */
                dhd_os_sdunlock(bus->dhd);
-#ifdef DHD_WAKE_STATUS
-               dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, chan, pkt_wake, &bus->wake_counts);
-               pkt_wake = 0;
-#else
                dhd_rx_frame(bus->dhd, ifidx, pkt, pkt_count, chan);
-#endif /* DHD_WAKE_STATUS */
                dhd_os_sdlock(bus->dhd);
        }
        rxcount = maxframes - rxleft;
@@ -7719,6 +7622,8 @@ dhdsdio_chipmatch(uint16 chipid)
                return TRUE;
        if (chipid == BCM4358_CHIP_ID)
                return TRUE;
+       if (chipid == BCM43569_CHIP_ID)
+               return TRUE;
        if (chipid == BCM43430_CHIP_ID)
                return TRUE;
        if (chipid == BCM43018_CHIP_ID)
@@ -7729,7 +7634,6 @@ dhdsdio_chipmatch(uint16 chipid)
                return TRUE;
        if (chipid == BCM4364_CHIP_ID)
                        return TRUE;
-
        if (chipid == BCM43012_CHIP_ID)
                return TRUE;
 
@@ -8405,6 +8309,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
                        case BCM4350_CHIP_ID:
                        case BCM4354_CHIP_ID:
                        case BCM4358_CHIP_ID:
+                       case BCM43569_CHIP_ID:
                                bus->dongle_ram_base = CR4_4350_RAM_BASE;
                                break;
                        case BCM4360_CHIP_ID:
@@ -10020,6 +9925,7 @@ static int
 concate_revision_bcm43455(dhd_bus_t *bus, char *fw_path, char *nv_path)
 {
        char chipver_tag[10] = {0, };
+       uint32 chip_rev = 0;
 #ifdef SUPPORT_MULTIPLE_BOARD_REV_FROM_DT
        int base_system_rev_for_nv = 0;
 #endif /* SUPPORT_MULTIPLE_BOARD_REV_FROM_DT */
@@ -10029,6 +9935,15 @@ concate_revision_bcm43455(dhd_bus_t *bus, char *fw_path, char *nv_path)
                DHD_ERROR(("%s:Chip is not BCM43455!\n", __FUNCTION__));
                return -1;
        }
+
+       chip_rev = bus->sih->chiprev;
+       if (chip_rev == 0x9) {
+               DHD_ERROR(("----- CHIP 43456 -----\n"));
+               strcat(fw_path, "_c5");
+               strcat(nv_path, "_c5");
+       } else {
+               DHD_ERROR(("----- CHIP 43455  -----\n"));
+       }
 #ifdef SUPPORT_MULTIPLE_BOARD_REV_FROM_DT
        base_system_rev_for_nv = dhd_get_system_rev();
        if (base_system_rev_for_nv > 0) {
@@ -10041,6 +9956,38 @@ concate_revision_bcm43455(dhd_bus_t *bus, char *fw_path, char *nv_path)
 }
 #endif /* SUPPORT_MULTIPLE_CHIP_4345X */
 
+static int
+concate_revision_bcm43430(dhd_bus_t *bus, char *fw_path, char *nv_path)
+{
+
+       uint chipver;
+       char chipver_tag[4] = {0, };
+
+       DHD_TRACE(("%s: BCM43430 Multiple Revision Check\n", __FUNCTION__));
+       if (bus->sih->chip != BCM43430_CHIP_ID) {
+               DHD_ERROR(("%s:Chip is not BCM43430\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+       chipver = bus->sih->chiprev;
+       DHD_ERROR(("CHIP VER = [0x%x]\n", chipver));
+       if (chipver == 0x0) {
+               DHD_ERROR(("----- CHIP bcm4343S -----\n"));
+               strcat(chipver_tag, "_3s");
+       } else if (chipver == 0x1) {
+               DHD_ERROR(("----- CHIP bcm43438 -----\n"));
+       } else if (chipver == 0x2) {
+               DHD_ERROR(("----- CHIP bcm43436L -----\n"));
+               strcat(chipver_tag, "_36");
+       } else {
+               DHD_ERROR(("----- CHIP bcm43430 unknown revision %d -----\n",
+                       chipver));
+       }
+
+       strcat(fw_path, chipver_tag);
+       strcat(nv_path, chipver_tag);
+       return 0;
+}
+
 int
 concate_revision(dhd_bus_t *bus, char *fw_path, char *nv_path)
 {
@@ -10089,6 +10036,9 @@ concate_revision(dhd_bus_t *bus, char *fw_path, char *nv_path)
                res = concate_revision_bcm43455(bus, fw_path, nv_path);
                break;
 #endif /* SUPPORT_MULTIPLE_CHIP_4345X */
+       case BCM43430_CHIP_ID:
+               res = concate_revision_bcm43430(bus, fw_path, nv_path);
+               break;
        default:
                DHD_ERROR(("REVISION SPECIFIC feature is not required\n"));
                return res;
@@ -10657,3 +10607,19 @@ int dhd_get_idletime(dhd_pub_t *dhd)
 {
        return dhd->bus->idletime;
 }
+
+#ifdef DHD_WAKE_STATUS
+wake_counts_t*
+dhd_bus_get_wakecount(dhd_pub_t *dhd)
+{
+       if (!dhd->bus) {
+               return NULL;
+       }
+       return &dhd->bus->wake_counts;
+}
+int
+dhd_bus_get_bus_wake(dhd_pub_t *dhd)
+{
+       return bcmsdh_set_get_wake(dhd->bus->sdh, 0);
+}
+#endif /* DHD_WAKE_STATUS */
index 6b1f9573b11f3aed12e6b200cb592d7e92d88da6..ef7522a0ada83ec95f8ba6188456e6a79f99ac4d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Customer HW 4 dependant file
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
        * CONFIG_ARCH_MSM8996 || CONFIG_SOC_EXYNOS8890
        */
 
-#if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_SOC_EXYNOS8890)
+#if defined(CONFIG_ARCH_MSM8996) || defined(CONFIG_SOC_EXYNOS8890) || \
+       defined(CONFIG_ARCH_MSM8998)
 #define SUPPORT_BCM4359_MIXED_MODULES
-#endif /* CONFIG_ARCH_MSM8996 || CONFIG_SOC_EXYNOS8890 */
+#endif /* MSM8996 || EXYNOS8890 || MSM8998 */
 
+#ifdef BCMPCIE
 /* For EXYNOS PCIe RC Control */
 #if defined(CONFIG_MACH_UNIVERSAL5433) || defined(CONFIG_MACH_UNIVERSAL7420) || \
        defined(CONFIG_SOC_EXYNOS8890) || defined(CONFIG_SOC_EXYNOS8895)
 #endif /* CONFIG_MACH_UNIVERSAL5433 || CONFIGA_MACH_UNIVERSAL7420 ||
        * CONFIG_SOC_EXYNOS8890 || CONFIG_SOC_EXYNOS8895
        */
+#endif /* BCMPCIE */
 
 #if defined(CONFIG_ARGOS)
 #if defined(CONFIG_SPLIT_ARGOS_SET)
 #define ARGOS_IRQ_WIFI_TABLE_LABEL "WIFI TX"
 #define ARGOS_WIFI_TABLE_LABEL "WIFI RX"
+#if defined(DYNAMIC_MUMIMO_CONTROL)
+#define ARGOS_WIFI_TABLE_FOR_MIMO_LABEL "WIFI"
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #else /* CONFIG_SPLIT_ARGOS_SET */
 #define ARGOS_IRQ_WIFI_TABLE_LABEL "WIFI"
 #define ARGOS_WIFI_TABLE_LABEL "WIFI"
 #endif /* CONFIG_ARGOS */
 
 #if defined(CONFIG_ARCH_MSM8998)
+#ifndef DHD_LB_IRQSET
 #define SET_PCIE_IRQ_CPU_CORE
 #define PCIE_IRQ_BIG_CORE 6
 #define PCIE_IRQ_LITTLE_CORE 0
-#endif
+#endif /* DHD_LB_IRQSET */
+#endif /* CONFIG_ARCH_MSM8998 */
 
 /* PROJECTS START */
 
 #define DPC_CPUCORE 4
 #define RXF_CPUCORE 7
 #define ARGOS_CPU_SCHEDULER
-#elif defined(CONFIG_MACH_UNIVERSAL5430) && defined(CONFIG_BCM43455)
+#elif (defined(CONFIG_MACH_UNIVERSAL5430) || defined(CONFIG_MACH_UNIVERSAL5433)) && \
+       defined(CONFIG_BCM43455)
 #define CUSTOM_SET_CPUCORE
 #define PRIMARY_CPUCORE 0
 #define MAX_RETRY_SET_CPUCORE 5
 #define MAX_RETRY_SET_CPUCORE 5
 #define DPC_CPUCORE 1
 #define RXF_CPUCORE 2
+#elif defined(CONFIG_SOC_EXYNOS7870) && defined(CONFIG_BCM43455)
+#define CUSTOM_SET_CPUCORE
+#define PRIMARY_CPUCORE 0
+#define MAX_RETRY_SET_CPUCORE 5
+#define DPC_CPUCORE 1
+#define RXF_CPUCORE 2
+#define ARGOS_CPU_SCHEDULER
+#elif defined(CONFIG_SOC_EXYNOS7870) && defined(CONFIG_BCM43456)
+#define CUSTOM_SET_CPUCORE
+#define PRIMARY_CPUCORE 0
+#define MAX_RETRY_SET_CPUCORE 5
+#define DPC_CPUCORE 1
+#define RXF_CPUCORE 2
+#define ARGOS_CPU_SCHEDULER
 #elif defined(CONFIG_MACH_UNIVERSAL5433) || defined(CONFIG_MACH_UNIVERSAL7420) || \
        defined(CONFIG_SOC_EXYNOS8890) || defined(CONFIG_SOC_EXYNOS8895)
 #undef CUSTOM_SET_CPUCORE
 #define DPC_CPUCORE 4
 #define RXF_CPUCORE 5
 #define TASKLET_CPUCORE 5
+#ifndef DHD_LB_IRQSET
 #define ARGOS_CPU_SCHEDULER
+#endif /* DHD_LB_IRQSET */
 #define ARGOS_RPS_CPU_CTL
 
 #ifdef CONFIG_SOC_EXYNOS8895
 #define DHD_LB_SECONDARY_CPUS   (0x0E)
 #endif /* CONFIG_SOC_EXYNOS8890 */
 #else /* !DHD_LB */
+#ifdef BCMPCIE
 #define ARGOS_DPC_TASKLET_CTL
+#endif /* BCMPCIE */
 #endif /* !DHD_LB */
 
 #if defined(CONFIG_ARCH_MSM) || defined(CONFIG_SOC_EXYNOS8895)
index 9f8849754410b1ad19846d918b4487e2a4ae334d..5acb96a1a4a82627cd6c7556f2476c736021c7ae 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DHD PROP_TXSTATUS Module.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhd_wlfc.c 679733 2017-01-17 06:40:39Z $
+ * $Id: dhd_wlfc.c 735359 2017-12-08 10:56:04Z $
  *
  */
 
@@ -2627,8 +2627,8 @@ _dhd_wlfc_mac_table_update(dhd_pub_t *dhd, uint8* value, uint8 type)
        uint8 ifid;
        uint8* ea;
 
-       WLFC_DBGMESG(("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n",
-               __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7],
+       WLFC_DBGMESG(("%s(), mac ["MACDBG"],%s,idx:%d,id:0x%02x\n",
+               __FUNCTION__, MAC2STRDBG(&value[2]),
                ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"),
                WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]));
 
@@ -3958,10 +3958,9 @@ dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
 
                        ea = interfaces[i].ea;
                        bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
-                               "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s "
+                               "["MACDBG"], if:%d, type: %s "
                                "netif_flow_control:%s\n", i,
-                               ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
-                               interfaces[i].interface_id,
+                               MAC2STRDBG(ea), interfaces[i].interface_id,
                                iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
                                ? " OFF":" ON"));
 
@@ -4005,9 +4004,8 @@ dhd_wlfc_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
                if (mac_table[i].occupied) {
                        ea = mac_table[i].ea;
                        bcm_bprintf(strbuf, "MAC_table[%d].ea = "
-                               "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i,
-                               ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
-                               mac_table[i].interface_id);
+                               "["MACDBG"], if:%d \n", i,
+                               MAC2STRDBG(ea), mac_table[i].interface_id);
 
                        bcm_bprintf(strbuf, "MAC_table[%d].PSQ(len,state,credit),"
                                "(trans,supp_trans,onbus)"
index 1e8b01f97a44b2ca5d8dfc975aaf1021bc0e970a..aff86b6fef1e26f07540bb07b14959425019ea3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index b995ec5b0ed47e7b24bf903781703b362619656f..03d427484b6746bf497355d57c3f37224f58a22d 100644 (file)
@@ -2,7 +2,7 @@
  * Common stats definitions for clients of dongle
  * ports
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index b710ee0cc1718b59cf12e319c7d00e81dea12872..93958be722401e9be7a7142bb69c72e2995ef236 100644 (file)
-BCM4361 DHD 1.77.11 for Android Dream & J5/J7 & BCM43438 NOS Project
+BCM4361 DHD 1.77.67 for Android Great/Dream/Hero & BCM4345X & BCM4343X Project
 (Notes: 1.77.x is twigged off from 1.579.235.9)
 
+DHD 1.77.67 - 2018.03.23
+New Feature
+ - CS4714586(By kwon Jaecheol) Increased the number of maximum STA association to 10 in case of STA/SoftAP concurrent mode
+
+Others
+ - CS4688655(By Lee SoonHo) Added to disable vhtmode after set country code
+ - CS4696802(By Ahn Byunghun) Added UDP port 137 packet filter for Tizen
+ - CS4713830(By Choi Jongmin) Added to execute memdump when performing private command 'DEBUG_DUMP' on SDIO bus interface
+
+
+DHD 1.77.65 - 2018.03.16
+Others
+ - CS4384009(By bang haejung) Fixed wrong configurations at MIRACAST
+ - CS4456720(By Cho Seong Ji) Added MAX_CNTL_TX_TIMEOUT in memdump condition if TX control timeout
+ - CS4539141(By Cho Seong Ji) Added additional string ('_plus') at nvram file name for 4359C0 (B90S module/GraceR projects)
+ - CS4596042(By Kwak Hogil) Changed EXCESS_PM_WAKE_EVENT interval time on suspend mode
+ - CS4611122(By Kim Gwang Min) CS4617024(By Cho Seong Ji) Added CLM multiple/single regrev blob checking logic
+ - CS4678265(By Anh Tran Tuan) Fixed Single Nvram define on BCM4343X for Android O-OS
+
+
+DHD 1.77.64 - 2018.03.05
+New Feature
+ - CS2472363(By Seo Jung Kuk Seo) Supported STA+SoftAP concurrent mode for non-RSDB chip(BCM43456)
+   SoftAP and STA interfaces simultaneously using single firmware in the Single Channel Concurrency (same channel operation)
+   (It should be sync up with FW version BIS5718B120RC8_REL_7_84_9)
+
+Security Patch
+ - CVE-2017-13292 V2018010201 Fixed buffer overflow in wl_get_assoc_ies() during assoc_info iovar results handling
+
+Others
+ - CS4429886(By Junsu Choi) Fixed to get proper VTS feature capabilities
+ - CS4474435(By Cho Seong Ji) Fixed AP scan results corrupted issue by wrong IE channel information in beacon
+ - CS4523209(By Jeong Min Cheol) Added VENDOR path ahead CLM blob path
+ - CS4539141(By Cho Seong Ji) Added function which conditionally add vendor name string (murata/wisol) at nvram file name for 4359C0 (B90S module)
+ - CS4593020(By Jeong Min Cheol) Moved memdump path to common feature list in Makefile
+ - Added Single Nvram define on BCM4343X for Android O-OS
+
+
+DHD 1.77.63 - 2018.02.02
+Security Patch
+ - CS4417295(By Jeong Min Cheol) Fixed for wl/cfg driver vulnerability by buffer overflow
+
+Others
+ - CS2864574(By Kim Tae-Yong) Fixed PCIE LINK DOWN issue by changing PCIE RC API
+ - CS3420505(By Huang Junming) Fixed wrong nvram loading issue from W2018 project
+ - CS3846389(By Kwak Hogil) Limit the number of dump files that DHD can store to local file system
+ - CS4324680(By Cho Seong Ji) Changed API from dev_alloc_skb(GFP_ATOMIC) to __dev_alloc_skb(GFP_KERNEL) in dhd_init_wlan_mem()
+ - CS4392874(By Gu Ja Heon) IRQ Affinity set to Big core and blocking CPU migration to Big Core
+ - Update correct STA channel for the Auto channel selection in case of STA/SoftAP concurrent mode
+
+Merged 1.363.59 to 1.77 for BCM4359C0 Projects only
+ - CS1914112(By Jeong Min Cheol) Added WIFI HANG operation when happen "scan timeout"
+ - CS2350019 Added Kernel log for RSDB mode switch status
+ - Added a firmware and nvram path (_plus) for Samsung GraceR project
+ - Added CLMINFO_PARSER feature
+   (For GraceR project, It should be sync up with FW DIN975T155RC47_REL_9_96_8 or higher version.
+    The FW file path should add "_blob" at the end of filename extension. ex)bcmdhd_sta.bin_c0_plus_blob )
+ - Added exception handling for LOGTRACE feature
+ - Added KEEP_KR_REGREV feature for replacing the regrev via NVRAM when Country code is KR
+ - Added private command for set CAC
+ - Modify virtual interface creation routines
+ - Replaced the ccode/regrev in translate_custom_table
+   (It should be sync up FW version with DIN975T155RC47_REL_9_96_3 or higher version for HERO project)
+ - Synced Makefile/Kconfig
+
+
+DHD 1.77.61 - 2018.01.24
+Others
+ - CS4094253(Byunghun Ahn) Fixed to support SR on 43569
+ - CS4115086(By Kwak Hogil) Added android private command to change pkt logging size
+ - CS4129114(By Choi Junsu) Added Single Nvram define on BCM43456 when Android O-OS
+ - CS4233933(By Kwak Hogil) Print mask and pattern values for pktlog filter separately
+ - CS4261039(By Min SungBin) Fixed to use proper locally_generated value on cfg80211_disconnect() when upper layer request disconnection
+ - CS4307298(By Jeong Min Cheol) Added to miss merged for WLAN_5GDISABLE in Kconfig
+ - CS4318264(By Anh Tran Tuan) Added to miss merged for WLAN_VHTDISABLE in Kconfig
+ - Changed debug log level in ISR routine which caused throughput regression on reference platform
+ - Changed MAC OUI format for Bigdata
+
+
+DHD 1.77.59 - 2017.12.22
+Others
+ - CS4139777(By Kwak Hogil) Fixed call mute issue during LCD Off(Changed Packet filter ID 107)
+ - CS4163743(By Kwak Hogil) Fixed code defect for wl_pattern_atoh() with invalid return value
+ - Changed MAC masking pattern and masking position to sync up with Firmware masking pattern
+ - Enhanced SoftAP/P2PGO keep alive to avoid unexpected keep alive disconnection
+ - Fixed a possible memory leak in dhdpcie_bus_write_vars
+ - Fixed missed SSID/MAC filtering in log for security reason
+ - Fixed parsing issue on wl_parse_ssid_list_tlv() for PNO setup
+
+
+DHD 1.77.58 - 2017.12.18
+Major Issue
+ - CS4083402(By Jeong Min Cheol) Added to define DHD_2G_ONLY_SUPPORT
+     * Issue summary
+       To support for 2.4G band only model requirement
+     * Analysis / Root cause
+       In order to support 2.4G band, it needs to block 5G band setting.
+     * Solution
+       In order to enable this feature, it needs to define CONFIG_WLAN_5GDISABLE in kernel config
+
+ - Added to define DHD_DISABLE_VHTMODE
+     * Issue summary
+       To support for 802.11ac disable model requirement
+     * Analysis / Root cause
+       In order to support 802.11ac disable, it needs to disable vhtmode
+     * Solution
+       In order to enable this feature, it needs to define CONFIG_WLAN_VHTDISABLE in kernel config
+
+Kernel Panic
+ - CS3959621(By Kim Gwang Min) Added debug log in ISR for debugging dpc un-scheduling issue
+ - CS3959621(By Kim Gwang Min) Fixed watchdog reset due to deadlock path from PM handler
+
+Others
+ - CS3898979(By Yoon Jae Ho) Fixed unintended hang issue by invalid deauth reason code from specific AP
+ - Enabled an Android private command for setting ADPS on BCM43456
+ - Fixed connection fail if BDC is enabled in DHD and CAC is enabled in both STA and AP (SDIO only)
+
+
+DHD 1.77.56.1 - 2017.11.30
+Others
+ - Fixed link down by null BSSID during roaming
+
+
+DHD 1.77.56 - 2017.11.30
+Major Issue
+ - CS3928981 Fixed to allocate 64KB for WLAN_DHD_WLFC_BUF_SIZE on 32bit platform also
+     * Issue summary
+       A8/43455/NOS, couldn't operate screen mirroring over WFD only under the VSDB/MCC       
+     * Analysis / Root cause
+       For a smooth VSDB/TX operation, PROP_TXSTATUS(WLFC) feature is being used
+       However, not enough pre-allocated memory for WLFC was allocated on 32bit platform
+       So VSDB/TX regression issue happened due to low pre-allocated memory size (16KB)        
+     * Solution
+       For WLFC_BUF_SIZE, pre-allocates 64KB for 32bit platform also
+
+ - CS4011220 Block ADPS enable private command at RF test mode
+     * Issue summary
+       Have a trouble to measure RF performance at RF test mode by ADPS
+     * Analysis / Root cause
+       During RF test mode, PM 0 is set to disable WiFi dongle PM operation including ADPS,
+       but “ADPS enable“ private command was called after setting PM 0 so ADPS was run again
+       This issue happened after enabling ADPS by default
+     * Solution
+       Block “ADPS enable” private command when PM 0 is set for RF test mode
+
+ - CS4034777 Enabled ARGOS notification callback for DHD TCP ACK suppress
+     * Issue summary
+       Low TPUT issue occurred in TCP long RTT environment
+     * Analysis / Root cause
+       The reason is that DHD TCP ACK suppress was always enabled because ARGOS feature was removed in DHD
+     * Solution
+       Turn off DHD TCP ACK suppress by default and enable ARGOS notification callback to control DHD TCP ACK suppress by current TPUT
+
+ - Configure 64bit DMA mask for MSM8998 (Default enabled: it can be controlled by the SET_DMA_MASK_64BIT  definition in the Makefile)
+     * Issue summary
+       Kernel allocated the memory in swiotlb region for DMA mapping since the default DMA mask is set to 32bit
+     * Analysis / Root cause
+       It's configured to 64bit mask for DMA mapping to check if  kernel allocates the memory for DMA mapping to different region and TPUT is improved
+     * Solution
+       Based on the kernel DMA mapping guidance, DHD configure DMA mask to 64bit
+
+Security Patch
+ - CVE-2017-13161 V2017092501 Fixed buffer overrun issue in wl_parse_ssid_list_tlv()
+ - CVE-2017-13213 V2017081501 Fixed buffer overrun issue in wl_cfgvendor_set_bssid_blacklist()
+ - V2017081701 Fixed buffer overrun issue in wl_cfgvendor_set_ssid_whitelist()
+ - V2017082201 Fixed buffer overrun issue in wl_cfgvendor_set_rand_mac_oui()
+ - V2017082202 Fixed buffer overrun issue in wl_cfgvendor_set_bssid_pref()
+
+Others
+ - CS3742062 Added STP / XID packet filter
+ - CS3863852 Added log to detect abnormal skb operation
+ - CS3914585 Fixed RCC channel missing issue when scan result is more than 100
+ - CS3927468 Added Bring-up patch for BCM43569
+ - CS3976846 Clear the bus state related flags for recovery during turning on Wi-Fi
+ - Block processing the rest of ring buffers once PCIe bus enters low power state
+ - Enabled feature for the Dongle memory loopback test and the PCIE Non DMA M2M loopback test when CONFIG_SEC_FACTORY enabled case
+   (It should be sync up FW version with IGU35RC65_REL_13_38_45(GREAT), IGU3565T38RC13_REL_13_41_13(DREAM) or higher version)
+ - Fixed memory leak in PNO stop command
+
+
+DHD 1.77.55.1 - 2017.11.10
+Others
+ - Disabled FW corruption test and PCIE Non DMA M2M loopback test in Makefile
+   (For enabling it, please modify Makefile and sync up FW version with IGU35RC65_REL_13_38_45(GREAT), IGU3565T38RC13_REL_13_41_13(DREAM) or higher version)
+
+
+DHD 1.77.55 - 2017.11.10
+Others
+ - CS3750290 Fixed mis-merged Makefile for BCM43456 Bring-up patch
+ - CS3962099 Fixed lockup corner case of Non-DMA M2M loopback test
+
+
+DHD 1.77.54 - 2017.11.03
+New Feature
+ - CS3688359 Added PCIe M2M non DMA loopback test in MFG mode
+
+Kernel Panic
+ - CS3830411 Fixed cpu lock up during de-init tcpack suppress module
+
+Security Patch
+ - CS3621122 Fixed vulnerability issue by dhd_parse_logstrs_file() which contains problematic code
+
+Others
+ - CS3509434 Changed beacon receive timeout
+ - CS3558828 Added NDO_CONFIG_SUPPORT
+ - CS3661384 Disabled WLAN_REASON_UNSPECIFIED reason code used as hang event code
+ - CS3685473 TPUT enhancement for A8 project (Exynos 5433 + BCM43455)
+ - CS3724694 Cancel roaming process when BSS was not matched
+ - CS3750290 Added BCM43456 Bring-up patch
+ - CS3799104 Added lock to protect vndr_oui_list
+ - CS3863852 Added log to detect abnormal skb operation
+ - Cleaned up the memory allocation logic of DHD_FW_MEM_CORRUPTION feature
+
+
+DHD 1.77.48 - 2017.09.21
+Kernel Panic
+ - CS3275366 Fixed kernel panic issue when returning invalid dongle ram size
+ - CS3341471 Fixed kernel panic from ASSERT during driver initialization
+ - Fixed kernel panic during connection test on debugging mode
+
+Others
+ - CS3274682 Fixed low performance of NAS download due to CPU migration
+ - CS3291870 Fixed the current consumption issue on SoftAP due to the wl_wdwake wakelock (Available for SDIO projects)
+ - CS3409811 Supported private command of clearing pktlogging data for security
+ - CS3483269 Extended dongle_isolation for all customer platform using PCIe bus
+ - CS3508335 Limited some security information in debug_dump
+ - CS3509434 Added WLC_E_SET_SSID fail custom reason code
+ - CS3558874 Added Assoc Reject - WLC_E_STATUS_NO_NETWORKS status code for Assoc Reject Bigdata
+ - CS3585868 Integrated GREAT Android N OS features into DREAM/GREAT Android O OS project
+ - CS3591398 Enabled TCP ACK suppress enable/disable log message
+ - Support RSSI summation report feature (Available for Android O or later version)
+
+
+DHD 1.77.44 - 2017.08.24
+Others
+ - CS3088602 Reduced value length of WSR counters variable
+ - CS3247015 Fixed disconnection during roaming on CISCO hidden networks
+ - CS3396150 Enabled legacy SCAN wakelock for SDIO Project
+ - CS3429070 Fixed SDIO init CLK issue for Exynos 7580 platform
+ - CS3455796 Changed path of wifi dump-files for DREAM/STAR
+
+
+DHD 1.77.43 - 2017.08.11
+Security Patch
+ - V2017063001 Removed not required IOVAR for SDIO
+ - V2017063002 Added length check in event log handler
+
+Others
+ - CS3088602 Minimized Wifi Statistics Report for host buffer size limitation
+ - CS3247009 Changed FW/NVRAM/BLOB location following ANDROID PLATFORM VERSION
+ - CS3351562 Changed MAC address encoding due to security issue
+
+
+DHD 1.77.37.3 - 2017.07.27
+Others
+ - CS3088602 Add missed 4 values while report to Framework
+ - CS3203998 Fixed to support big data of 11kv
+ - CS3215091 Fixed build error of detect consecutive hang event
+ - CS3255825 Changed path of wifi dump-files only if GREAT
+
+
+DHD 1.77.37.2 - 2017.07.19
+Kernel Panic
+ - CS3203896 Fixed kernel panic caused by referred NULL Pointer in dhd_pktlog_pkts_write_file
+ - CS3204538 Fixed Kernel panic when D3_ACK timeout is occurred
+
+Others
+ - CS3215091 Detect consecutive hang event from dongle on factory binary
+ - CS3221222 Fixed wrong 11kv default setting
+ - CS3265424 CS3160208 Fixed to update correct DHD connection status on AUTO_ROAM operation
+ - CS3265424 CS3214374 Fixed Roaming event drop issue when roaming to same BSSID case
+
+
+DHD 1.77.37 - 2017.07.04
+New Feature
+ - CS2955162 Supported RSSI Logging 
+   (This implementation should be sync up with FW 13.38.30 or higher version)
+ - CS3088602 Introduced Wifi Statistics Report for Big data logging
+
+Kernel Panic
+ - CS1812549 Fixed kernel panic for GETSTAINFO command
+ - CS3114183 Fixed kernel panic that filp_close() referred NULL Pointer in dhd_pktlog_write_file()
+ - CS3179018 Changed log level of scan warn event log to prevent scan time out
+
+Security Patch
+ - CVE-2017-0705 Added boundary check in wl_cfgvendor_significant_change_cfg()
+ - CVE-2017-0706 Added boundary check in wl_cfg80211_mgmt_tx()
+ - V2017053101 Added boundary check in dhd_process_full_gscan_result()
+ - V2017053102 Fixed Heap overflow in dhd_handle_swc_evt()
+ - V2017053103 Added boundary check in dhd_handle_hotlist_scan_evt()
+ - V2017053104 Added boundary check in dhd_pno_process_epno_result()
+ - V2017060101 Added boundary check in wl_escan_handler()
+ - Fixed overflow issue in wl_android_set_ibss_beacon_ouidata()
+Others
+ - CS1760272 Added BCM43430 FW/NVRAM dual operation
+ - CS2459522 Re-enabled GEN_SOFTAP_INFO_FILE feature
+ - CS2554190 Enhanced Packet Logging feature - Used Pre-allocated buffer pool & Added private command & Added packet failure reason into pcap
+ - CS2901316 Fixed to send up common error code for Android-O VTS
+ - CS2901316 Fixed to use proper chipset number when parsing link stats
+ - CS3057710 Added spin lock for Packet Monitoring and Debugability feature - Avoid packet fetching on invalid states
+ - CS3057710 Disabled Android Packet Monitoring
+ - CS3059107 Fixed build error on BCM43455 A8 platform
+ - CS3092630 Added to HEX dump for host wake packet
+ - CS3093675 Fixed prevent issue in dhd_pktlog.c file
+ - CS3121464 Added to check invalid hang reason
+ - Added log for packet monitor entry functions
+
+
+DHD 1.77.27.12 - 2017.06.20
+New Feature
+ - CS2554190 Enabled Packet Logging feature for Great Project
+
+Kernel Panic
+ - CS2931791 Fixed kernel panic when flushing packet in Tx queue for SDIO interface
+ - CS3024217 Fixed the Kernel panic when Kernel calls the CPU hotplug notification function during driver initialization
+Security Patch
+ - Enhanced event length check in is_wlc_event_frame()
+ - V2017052301 Added event length check in dhd_rtt_event_handler()
+ - V2017052302 Added event length check in wl_notify_rx_mgmt_frame()
+
+Others
+ - CS2934714 Fixed MFG firmware loading failure with single nvram file
+ - CS3018308 Fixed repetitive connection drops of clients with Mobile Hotspot
+ - Added log for scan timeout issue
+ - Disabled Preempt when scan results sent to host - avoid scan timeout issue
+ - Provide roaming reason when WLC_E_ROAM_PREP event has occurred
+   (This patch should be sync up with FW 13.38.30 or higher version)
+ - Sync up Makefile/Kconfig with Samsung requirement
+
+
+DHD 1.77.24 - 2017.06.02
+Kernel Panic
+ - Fixed Kernel Panic in wl_event_handler() while doing STA+P2P stress test
+
+Security Patch
+ - Supported Heap ASLR(Address Space Layout Randomization) in dongle. Heap ASLR will be enabled when firmware supports it
+
+Others
+ - Fixed incorrect nvram path modification routines to support Murata module
+
+
+DHD 1.77.22 - 2017.05.25
+Kernel Panic
+ - CS2714944 Fixed the Kernel Panic during dynamic TCP ACK suppress mode change in SDIO platform
+
+Others
+ - CS2595140 Added an Android private command for setting ADPS
+ - CS2675989 Fixed reverse-order of EAP-Failure and deauth packet
+ - 11kv - Fixed BTM capability check
+ - Unified one DHD for Dream & Great Project with CONFIG_WLAN_GREAT define
+
+
+DHD 1.77.21 - 2017.05.19
+New Feature
+ - CS2459522 Disabled GEN_SOFTAP_INFO_FILE feature in Makefile
+ - Comment out ADPS define at Makefile
+
+Kernel Panic
+ - CS2472525 Avoid to trigger Kernel panic on abnormal devices during device initialization
+ - CS2716890 Fixed Scan timeout issue with blocking suspend during P2P scan
+
+Security Patch
+ - CVE-2017-0633 V2017022301 Enhanced wrong buffer usage in IOCTL path
+
+Others
+ - CS2454032 Changed to implement wake stat support
+ - CS2460373 Added WIFI_LOGGER feature in Makefile
+ - CS2472434 Fixed roam failure on PMF required APs
+ - CS2475910 Print last roaming event log when link down is happened
+ - CS2642368 Fixed type casting issue in wl_android_send_action_frame()
+ - CS2761292 Added dhd rxq sdlock operation
+ - CS2769153 Fixed compile error on exymos5433 sdio model
+ - CS2791743 Fixed duplicated tx_error counter summation
+ - CS2793328 Relocated WLAN onoff delay on dhd_wlan_init_gpio()
+ - Added max payload length check in dhd_dbg_msgtrace_log_parser() function
+ - Changed the nvram file name to nvram.txt to support single nvram file
+ - Fixed assoc state sync issue between wpa_supplicant & DHD driver
+ - Fixed SoftAP interface delete issue observed while running APSTA stability test
+ - Fixed the spinlock related problem in the DHD_WAKE_STATUS feature
+
+
+DHD 1.77.16 - 2017.05.01
+New Feature
+ - CS2459522 Created .softap.info file when boot-up time for SoftAP information
+
+Kernel Panic
+ - CS2471281 Fixed null pointer reference exception during interface down
+ - CS2472873 Fixed to prevent accessing  CPU hotplug call back before initialization
+ - CS2477559 Implement exception handling routines if DMA mapping error for TX data packet is happened
+
+Security Patch
+ - CVE-2017-0568 V2017051814 Fixed buffer overrun in wl_run_escan()
+ - CVE-2017-0570 V2017051815 Removed unused file (wl_iw.c/wl_iw.h)
+ - CVE-2017-0574 V2017051817 Fixed vulnerability issues
+ - CVE-2017-0740 V2017030901 Fixed length overflow issue in dhd_wl_ioctl() function
+
+Others
+ - CS2456626 Enabled SETBAND API
+ - CS2470635 Enabled frameburst on SDIO platform
+ - CS2471300 Fixed Buffer overflow issue
+ - CS2473469 Added force disconnect when continuously update DPM event
+ - CS2474767 Fixed compile error for Dream project
+ - CS2476640 Added to control tcpack_suppress as throughput on BCM43455
+ - CS2555123 Fixed page fault issue in dhd_wl_ioctl()
+ - Enabled CAC by default and modified CAC dynamically based on the interface
+ - Enabled Random MAC address scan by default for all WIFI chip
+ - Fixed wrong event message print log issue
+
+
+DHD 1.77.12.1 - 2017.03.27
+Others
+ - CSP:1138026 Fixed compile error for Dream project
+
+
+DHD 1.77.12 - 2017.03.22
+Others
+ - CSP:1122174 Fixed to clean up dongle arp table when using arp request host offloading option
+ - CSP:1136579 Removed gtk_key_info set fail error log
+ - Fixed memory buffer overrun with interworking IE
+
+
 DHD 1.77.11 - 2017.03.17
 Others
  - Removed unnecessary country code list in translate_custom_table
  - Supported A3 project for BCM43438
 
 
+DHD 1.77.9.1 - 2017.03.28
+Kernel Panic
+ - CSP:1139481 Fixed null pointer reference exception during interface down
+
+
 DHD 1.77.9 - 2017.03.14
 Kernel Panic
  - CSP:1133051 Fixed livelock issue from unterminated tasklet
@@ -90,6 +518,11 @@ New Feature
 Kernel Panic
  - Fixed Kernel Panic during STA-GO connection test case
 
+11kv
+ - Fixed to send BTM query in dongle
+ - Override WNM Max Idle period to keep alive period
+ - Update RCC with channels in neighbor report response
+
 Others
  - CSP:1104911 Added to get hostapd_cli STA_INFO command
  - CSP:1111618 Disabled WLADPS_SEAK_AP_WAR feature
@@ -104,11 +537,6 @@ Others
  - Added to control scan suppress during RF test mode
  - Enhanced more for nested connection case handling
 
-11kv
- - Fixed to send BTM query in dongle
- - Override WNM Max Idle period to keep alive period
- - Update RCC with channels in neighbor report response
-
 
 DHD 1.579.235.7 - 2017.01.19
 Kernel Panic
index 0c5c3a8a3525a08675e667bd86b6632541f0dd86..57193dfff5e0874b5fc44eef3d329411c1308e28 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND generic packet pool operation primitives
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 743a23601a012886efd280dcce3f7c8e17052dbb..102aabce6f80196767110c43b6f1bf3eb6372700 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND generic pktq operation primitives
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index c76a943dab38e56483969a51fc881aeb0c36f76d..a6aa44d54f8d0580a23a218728a794149a623ccd 100644 (file)
@@ -2,7 +2,7 @@
  * Misc utility routines for accessing PMU corerev specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 794840ee4ec1cb7cce3215bf5f9e52c3e513370b..80cf28bdd8aeff143926b699e7288b3a23318317 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental types and constants relating to 802.11
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: 802.11.h 677080 2016-12-28 19:10:53Z $
+ * $Id: 802.11.h 700693 2017-05-20 20:29:07Z $
  */
 
 #ifndef _802_11_H_
@@ -264,7 +264,10 @@ BWL_PRE_PACKED_STRUCT struct dot11_auth {
        uint16                  seq;            /* sequence control */
        uint16                  status;         /* status code */
 } BWL_POST_PACKED_STRUCT;
-#define DOT11_AUTH_FIXED_LEN   6               /* length of auth frame without challenge IE */
+#define DOT11_AUTH_FIXED_LEN           6       /* length of auth frame without challenge IE */
+#define DOT11_AUTH_SEQ_STATUS_LEN      4       /* length of auth frame without challenge IE and
+                                                * without algorithm
+                                                */
 
 BWL_PRE_PACKED_STRUCT struct dot11_assoc_req {
        uint16                  capability;     /* capability information */
@@ -399,6 +402,17 @@ BWL_PRE_PACKED_STRUCT struct dot11_action_frmhdr {
        uint8   data[1];
 } BWL_POST_PACKED_STRUCT;
 typedef struct dot11_action_frmhdr dot11_action_frmhdr_t;
+
+/* Action Field length */
+#define DOT11_ACTION_CATEGORY_LEN      1
+#define DOT11_ACTION_ACTION_LEN                1
+#define DOT11_ACTION_DIALOG_TOKEN_LEN  1
+#define DOT11_ACTION_CAPABILITY_LEN    2
+#define DOT11_ACTION_STATUS_CODE_LEN   2
+#define DOT11_ACTION_REASON_CODE_LEN   2
+#define DOT11_ACTION_TARGET_CH_LEN     1
+#define DOT11_ACTION_OPER_CLASS_LEN    1
+
 #define DOT11_ACTION_FRMHDR_LEN        2
 
 /** CSA IE data structure */
@@ -660,6 +674,16 @@ BWL_PRE_PACKED_STRUCT struct dot11_lci_subelement {
 } BWL_POST_PACKED_STRUCT;
 typedef struct dot11_lci_subelement dot11_lci_subelement_t;
 
+BWL_PRE_PACKED_STRUCT struct dot11_colocated_bssid_list_se {
+       uint8 sub_id;
+       uint8 length;
+       uint8 max_bssid_ind; /* MaxBSSID Indicator */
+       struct ether_addr bssid[1]; /* variable */
+} BWL_POST_PACKED_STRUCT;
+typedef struct dot11_colocated_bssid_list_se dot11_colocated_bssid_list_se_t;
+#define DOT11_LCI_COLOCATED_BSSID_LIST_FIXED_LEN     3
+#define DOT11_LCI_COLOCATED_BSSID_SUBELEM_ID         7
+
 BWL_PRE_PACKED_STRUCT struct dot11_civic_subelement {
        uint8 type;  /* type of civic location */
        uint8 subelement;
@@ -943,6 +967,22 @@ typedef struct ti_ie ti_ie_t;
 #define TI_TYPE_REASSOC_DEADLINE       1
 #define TI_TYPE_KEY_LIFETIME           2
 
+#ifndef CISCO_AIRONET_OUI
+#define CISCO_AIRONET_OUI      "\x00\x40\x96"  /* Cisco AIRONET OUI */
+#endif
+/* QoS FastLane IE. */
+BWL_PRE_PACKED_STRUCT struct ccx_qfl_ie {
+       uint8   id;             /* 221, DOT11_MNG_VS_ID */
+       uint8   length;         /* 5 */
+       uint8   oui[3];         /* 00:40:96 */
+       uint8   type;           /* 11 */
+       uint8   data;
+} BWL_POST_PACKED_STRUCT;
+typedef struct ccx_qfl_ie ccx_qfl_ie_t;
+#define CCX_QFL_IE_TYPE        11
+#define CCX_QFL_ENABLE_SHIFT   5
+#define CCX_QFL_ENALBE (1 << CCX_QFL_ENABLE_SHIFT)
+
 /* WME Action Codes */
 #define WME_ADDTS_REQUEST      0       /* WME ADDTS request */
 #define WME_ADDTS_RESPONSE     1       /* WME ADDTS response */
@@ -962,6 +1002,10 @@ typedef struct ti_ie ti_ie_t;
 #define DOT11_OPEN_SYSTEM      0       /* d11 open authentication */
 #define DOT11_SHARED_KEY       1       /* d11 shared authentication */
 #define DOT11_FAST_BSS         2       /* d11 fast bss authentication */
+#define DOT11_SAE              3       /* d11 simultaneous authentication of equals */
+#define DOT11_FILS_SKEY_PFS    4       /* d11 fils shared key authentication w/o pfs */
+#define DOT11_FILS_SKEY                5       /* d11 fils shared key authentication w/ pfs */
+#define DOT11_FILS_PKEY                6       /* d11 fils public key authentication */
 #define DOT11_CHALLENGE_LEN    128     /* d11 challenge text length */
 
 /* Frame control macros */
@@ -1434,8 +1478,9 @@ typedef struct ti_ie ti_ie_t;
 #define DOT11_MNG_CHANNEL_SWITCH_WRAPPER_ID    196     /* Channel Switch Wrapper IE */
 #define DOT11_MNG_AID_ID                       197     /* Association ID  IE */
 #define        DOT11_MNG_OPER_MODE_NOTIF_ID            199     /* d11 mgmt VHT oper mode notif */
-#define DOT11_MNG_HE_CAP_ID                    201
-#define DOT11_MNG_HE_OP_ID                     202
+#define DOT11_MNG_RNR_ID                       201
+#define DOT11_MNG_HE_CAP_ID                    202
+#define DOT11_MNG_HE_OP_ID                     203
 #define DOT11_MNG_FTM_PARAMS_ID                        206
 #define DOT11_MNG_TWT_ID                       216     /* 11ah D5.0 */
 #define DOT11_MNG_WPA_ID                       221     /* d11 management WPA id */
@@ -1452,8 +1497,16 @@ typedef struct ti_ie ti_ie_t;
 #define DOT11_MNG_RAPS_ID      (DOT11_MNG_ID_EXT_ID+11)  /* OFDMA Random Access Parameter Set */
 
 /* FILS ext ids */
-#define FILS_REQ_PARAMS_EXT_ID 2
+#define FILS_REQ_PARAMS_EXT_ID         2
 #define DOT11_MNG_FILS_REQ_PARAMS      (DOT11_MNG_ID_EXT_ID + FILS_REQ_PARAMS_EXT_ID)
+#define FILS_SESSION_EXT_ID            4
+#define DOT11_MNG_FILS_SESSION         (DOT11_MNG_ID_EXT_ID + FILS_SESSION_EXT_ID)
+#define FILS_HLP_CONTAINER_EXT_ID              5
+#define DOT11_MNG_FILS_HLP_CONTAINER           (DOT11_MNG_ID_EXT_ID + FILS_HLP_CONTAINER_EXT_ID)
+#define FILS_WRAPPED_DATA_EXT_ID       8
+#define DOT11_MNG_FILS_WRAPPED_DATA    (DOT11_MNG_ID_EXT_ID + FILS_WRAPPED_DATA_EXT_ID)
+#define FILS_NONCE_EXT_ID              13
+#define DOT11_MNG_FILS_NONCE           (DOT11_MNG_ID_EXT_ID + FILS_NONCE_EXT_ID)
 
 #define DOT11_MNG_IE_ID_EXT_MATCH(_ie, _id) (\
        ((_ie)->id == DOT11_MNG_ID_EXT_ID) && \
@@ -1498,13 +1551,14 @@ typedef struct ti_ie ti_ie_t;
 #define DOT11_RATE_MASK                 0x7F /* mask for numeric part of rate */
 
 /* BSS Membership Selector parameters
- * 802.11-2012 and 802.11ac_D4.0 sec 8.4.2.3
+ * 802.11-2016 (and 802.11ax-D1.1), Sec 9.4.2.3
  * These selector values are advertised in Supported Rates and Extended Supported Rates IEs
  * in the supported rates list with the Basic rate bit set.
  * Constants below include the basic bit.
  */
 #define DOT11_BSS_MEMBERSHIP_HT         0xFF  /* Basic 0x80 + 127, HT Required to join */
 #define DOT11_BSS_MEMBERSHIP_VHT        0xFE  /* Basic 0x80 + 126, VHT Required to join */
+#define DOT11_BSS_MEMBERSHIP_HE         0xFD  /* Basic 0x80 + 125, HE Required to join */
 
 /* ERP info element bit values */
 #define DOT11_MNG_ERP_LEN                      1       /* ERP is currently 1 byte long */
@@ -1603,9 +1657,13 @@ BWL_PRE_PACKED_STRUCT struct dot11_extcap {
 } BWL_POST_PACKED_STRUCT;
 typedef struct dot11_extcap dot11_extcap_t;
 
-/* VHT Operating mode bit fields -  (11ac D3.0 - 8.4.1.50) */
+/* VHT Operating mode bit fields -  (11ac D8.0/802.11-2016 - 9.4.1.53) */
 #define DOT11_OPER_MODE_CHANNEL_WIDTH_SHIFT 0
 #define DOT11_OPER_MODE_CHANNEL_WIDTH_MASK 0x3
+#define DOT11_OPER_MODE_160_8080_BW_SHIFT 2
+#define DOT11_OPER_MODE_160_8080_BW_MASK 0x04
+#define DOT11_OPER_MODE_NOLDPC_SHIFT 3
+#define DOT11_OPER_MODE_NOLDPC_MASK 0x08
 #define DOT11_OPER_MODE_RXNSS_SHIFT 4
 #define DOT11_OPER_MODE_RXNSS_MASK 0x70
 #define DOT11_OPER_MODE_RXNSS_TYPE_SHIFT 7
@@ -1618,9 +1676,22 @@ typedef struct dot11_extcap dot11_extcap_t;
        ((chanw) << DOT11_OPER_MODE_CHANNEL_WIDTH_SHIFT &\
                 DOT11_OPER_MODE_CHANNEL_WIDTH_MASK))
 
+#define DOT11_D8_OPER_MODE(type, nss, ldpc, bw160_8080, chanw) (\
+       ((type) << DOT11_OPER_MODE_RXNSS_TYPE_SHIFT &\
+                DOT11_OPER_MODE_RXNSS_TYPE_MASK) |\
+       (((nss) - 1) << DOT11_OPER_MODE_RXNSS_SHIFT & DOT11_OPER_MODE_RXNSS_MASK) |\
+       ((ldpc) << DOT11_OPER_MODE_NOLDPC_SHIFT & DOT11_OPER_MODE_NOLDPC_MASK) |\
+       ((bw160_8080) << DOT11_OPER_MODE_160_8080_BW_SHIFT &\
+                DOT11_OPER_MODE_160_8080_BW_MASK) |\
+       ((chanw) << DOT11_OPER_MODE_CHANNEL_WIDTH_SHIFT &\
+                DOT11_OPER_MODE_CHANNEL_WIDTH_MASK))
+
 #define DOT11_OPER_MODE_CHANNEL_WIDTH(mode) \
        (((mode) & DOT11_OPER_MODE_CHANNEL_WIDTH_MASK)\
                >> DOT11_OPER_MODE_CHANNEL_WIDTH_SHIFT)
+#define DOT11_OPER_MODE_160_8080(mode) \
+       (((mode) & DOT11_OPER_MODE_160_8080_BW_MASK)\
+               >> DOT11_OPER_MODE_160_8080_BW_SHIFT)
 #define DOT11_OPER_MODE_RXNSS(mode) \
        ((((mode) & DOT11_OPER_MODE_RXNSS_MASK)         \
                >> DOT11_OPER_MODE_RXNSS_SHIFT) + 1)
@@ -1633,6 +1704,7 @@ typedef struct dot11_extcap dot11_extcap_t;
 #define DOT11_OPER_MODE_80MHZ 2
 #define DOT11_OPER_MODE_160MHZ 3
 #define DOT11_OPER_MODE_8080MHZ 3
+#define DOT11_OPER_MODE_1608080MHZ 1
 
 #define DOT11_OPER_MODE_CHANNEL_WIDTH_20MHZ(mode) (\
        ((mode) & DOT11_OPER_MODE_CHANNEL_WIDTH_MASK) == DOT11_OPER_MODE_20MHZ)
@@ -1641,9 +1713,9 @@ typedef struct dot11_extcap dot11_extcap_t;
 #define DOT11_OPER_MODE_CHANNEL_WIDTH_80MHZ(mode) (\
        ((mode) & DOT11_OPER_MODE_CHANNEL_WIDTH_MASK) == DOT11_OPER_MODE_80MHZ)
 #define DOT11_OPER_MODE_CHANNEL_WIDTH_160MHZ(mode) (\
-       ((mode) & DOT11_OPER_MODE_CHANNEL_WIDTH_MASK) == DOT11_OPER_MODE_160MHZ)
+       ((mode) & DOT11_OPER_MODE_160_8080_BW_MASK))
 #define DOT11_OPER_MODE_CHANNEL_WIDTH_8080MHZ(mode) (\
-       ((mode) & DOT11_OPER_MODE_CHANNEL_WIDTH_MASK) == DOT11_OPER_MODE_8080MHZ)
+       ((mode) & DOT11_OPER_MODE_160_8080_BW_MASK))
 
 /* Operating mode information element 802.11ac D3.0 - 8.4.2.168 */
 BWL_PRE_PACKED_STRUCT struct dot11_oper_mode_notif_ie {
@@ -1682,6 +1754,7 @@ typedef struct dot11_oper_mode_notif_ie dot11_oper_mode_notif_ie_t;
 #define DOT11_ACTION_CAT_SELFPROT      15      /* category for Mesh, self protected */
 #define DOT11_ACTION_NOTIFICATION      17
 #define DOT11_ACTION_CAT_VHT           21      /* VHT action */
+#define DOT11_ACTION_CAT_S1G           22      /* S1G action */
 #define DOT11_ACTION_CAT_HE            27      /* HE action frame */
 #define DOT11_ACTION_CAT_FILS          26      /* FILS action frame */
 #define DOT11_ACTION_CAT_VSP           126     /* protected vendor specific */
@@ -3568,11 +3641,6 @@ typedef int vht_group_id_t;
 #define VHT_N_SERVICE           16     /* bits in SERVICE field */
 #define VHT_N_TAIL               6     /* tail bits per BCC encoder */
 
-#define HE_LTF_1_GI_1_6us              (0)
-#define HE_LTF_2_GI_0_8us              (1)
-#define HE_LTF_2_GI_1_6us              (2)
-#define HE_LTF_4_GI_3_2us              (3)
-
 /** dot11Counters Table - 802.11 spec., Annex D */
 typedef struct d11cnt {
        uint32          txfrag;         /* dot11TransmittedFragmentCount */
@@ -3913,6 +3981,8 @@ typedef struct ht_prop_add_ie ht_prop_add_ie_t;
 #define HT_OPMODE_NONGF        0x0004  /* protection mode non-GF */
 #define DOT11N_TXBURST         0x0008  /* Tx burst limit */
 #define DOT11N_OBSS_NONHT      0x0010  /* OBSS Non-HT STA present */
+#define HT_OPMODE_CCFS2_MASK   0x1fe0  /* Channel Center Frequency Segment 2 mask */
+#define HT_OPMODE_CCFS2_SHIFT  5       /* Channel Center Frequency Segment 2 shift */
 
 /* misc_bites defn's */
 #define HT_BASIC_STBC_MCS      0x007f  /* basic STBC MCS */
@@ -3944,7 +4014,14 @@ typedef struct ht_prop_add_ie ht_prop_add_ie_t;
                                        == DOT11N_TXBURST)      /* Tx Burst present */
 #define DOT11N_OBSS_NONHT_PRESENT(add_ie)      ((ltoh16_ua(&add_ie->opmode) & DOT11N_OBSS_NONHT) \
                                        == DOT11N_OBSS_NONHT)   /* OBSS Non-HT present */
-/* Macros for HT MCS filed access */
+#define HT_OPMODE_CCFS2_GET(add_ie)    ((ltoh16_ua(&(add_ie)->opmode) & HT_OPMODE_CCFS2_MASK) \
+                                       >> HT_OPMODE_CCFS2_SHIFT)       /* get CCFS2 */
+#define HT_OPMODE_CCFS2_SET(add_ie, ccfs2)     do { /* set CCFS2 */ \
+       (add_ie)->opmode &= htol16(~HT_OPMODE_CCFS2_MASK); \
+       (add_ie)->opmode |= htol16(((ccfs2) << HT_OPMODE_CCFS2_SHIFT) & HT_OPMODE_CCFS2_MASK); \
+} while (0)
+
+/* Macros for HT MCS field access */
 #define HT_CAP_MCS_BITMASK(supp_mcs)                 \
        ((supp_mcs)[HT_CAP_MCS_RX_8TO15_BYTE_OFFSET])
 #define HT_CAP_MCS_TX_RX_UNEQUAL(supp_mcs)          \
@@ -4037,6 +4114,16 @@ typedef struct vht_cap_ie vht_cap_ie_t;
 #define VHT_CAP_INFO_AMPDU_MAXLEN_EXP_SHIFT     23
 #define VHT_CAP_INFO_LINK_ADAPT_CAP_MASK        0x0c000000
 #define VHT_CAP_INFO_LINK_ADAPT_CAP_SHIFT       26
+#define VHT_CAP_INFO_EXT_NSS_BW_SUP_MASK        0xc0000000
+#define VHT_CAP_INFO_EXT_NSS_BW_SUP_SHIFT       30
+
+/* get Extended NSS BW Support passing vht cap info */
+#define VHT_CAP_EXT_NSS_BW_SUP(cap_info) \
+       (((cap_info) & VHT_CAP_INFO_EXT_NSS_BW_SUP_MASK) >> VHT_CAP_INFO_EXT_NSS_BW_SUP_SHIFT)
+
+/* VHT CAP INFO extended NSS BW support - refer to IEEE 802.11 REVmc D8.0 Figure 9-559 */
+#define VHT_CAP_INFO_EXT_NSS_BW_HALF_160       1 /* 160MHz at half NSS CAP */
+#define VHT_CAP_INFO_EXT_NSS_BW_HALF_160_80P80 2 /* 160 & 80p80 MHz at half NSS CAP */
 
 /* VHT Supported MCS Set - 64-bit - in VHT Cap IE */
 #define VHT_CAP_SUPP_MCS_RX_HIGHEST_RATE_MASK   0x1fff
@@ -4046,6 +4133,13 @@ typedef struct vht_cap_ie vht_cap_ie_t;
 #define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_MASK   0x1fff
 #define VHT_CAP_SUPP_MCS_TX_HIGHEST_RATE_SHIFT  0
 
+/* defines for field(s) in vht_cap_ie->rx_max_rate */
+#define VHT_CAP_MAX_NSTS_MASK                  0xe000
+#define VHT_CAP_MAX_NSTS_SHIFT                 13
+
+/* defines for field(s) in vht_cap_ie->tx_max_rate */
+#define VHT_CAP_EXT_NSS_BW_CAP                 0x2000
+
 #define VHT_CAP_MCS_MAP_0_7                     0
 #define VHT_CAP_MCS_MAP_0_8                     1
 #define VHT_CAP_MCS_MAP_0_9                     2
@@ -4146,8 +4240,8 @@ typedef struct vht_op_ie vht_op_ie_t;
 typedef enum vht_op_chan_width {
        VHT_OP_CHAN_WIDTH_20_40 = 0,
        VHT_OP_CHAN_WIDTH_80    = 1,
-       VHT_OP_CHAN_WIDTH_160   = 2,
-       VHT_OP_CHAN_WIDTH_80_80 = 3
+       VHT_OP_CHAN_WIDTH_160   = 2, /* deprecated - IEEE 802.11 REVmc D8.0 Table 11-25 */
+       VHT_OP_CHAN_WIDTH_80_80 = 3  /* deprecated - IEEE 802.11 REVmc D8.0 Table 11-25 */
 } vht_op_chan_width_t;
 
 /* AID length */
@@ -4215,6 +4309,10 @@ typedef struct vht_features_ie_hdr vht_features_ie_hdr_t;
 #define WPS_OUI_TYPE           4
 
 /* ************* WFA definitions. ************* */
+#if defined(WL_LEGACY_P2P)
+#define MAC_OUI                        "\x00\x17\xF2"  /* MACOSX OUI */
+#define MAC_OUI_TYPE_P2P       5
+#endif 
 
 #ifdef P2P_IE_OVRD
 #define WFA_OUI                        MAC_OUI
@@ -4255,6 +4353,8 @@ typedef struct vht_features_ie_hdr vht_features_ie_hdr_t;
 #define RSN_AKM_SHA256_1X      5       /* SHA256 key derivation, using 802.1X */
 #define RSN_AKM_SHA256_PSK     6       /* SHA256 key derivation, using Pre-shared Key */
 #define RSN_AKM_TPK            7       /* TPK(TDLS Peer Key) handshake */
+#define RSN_AKM_FILS_SHA256    14      /* SHA256 key derivation, using FILS */
+#define RSN_AKM_FILS_SHA384    15      /* SHA384 key derivation, using FILS */
 
 /* OSEN authenticated key managment suite */
 #define OSEN_AKM_UNSPECIFIED   RSN_AKM_UNSPECIFIED     /* Over 802.1x */
@@ -4782,6 +4882,7 @@ enum {
        FTM_VS_TLV_SEC_PARAMS = 3,              /* security parameters (in either) */
        FTM_VS_TLV_SEQ_PARAMS = 4,              /* toast parameters (FTM_REQ, BRCM proprietary) */
        FTM_VS_TLV_MF_BUF = 5,                  /* multi frame buffer - may span ftm vs ie's */
+       FTM_VS_TLV_TIMING_PARAMS = 6            /* timing adjustments */
        /* add additional types above */
 };
 
@@ -4791,11 +4892,16 @@ enum {
 #define FTM_TPK_LEN            16
 #define FTM_RI_RR_BUF_LEN      32
 #define FTM_TPK_RI_RR_LEN      13
+#define FTM_TPK_RI_RR_LEN_SECURE_2_0    28
 #define FTM_TPK_DIGEST_LEN     32
 #define FTM_TPK_BUFFER_LEN     128
 #define FTM_TPK_RI_PHY_LEN     7
 #define FTM_TPK_RR_PHY_LEN     7
 #define FTM_TPK_DATA_BUFFER_LEN 88
+#define FTM_TPK_LEN_SECURE_2_0          32
+#define FTM_TPK_RI_PHY_LEN_SECURE_2_0  14
+#define FTM_TPK_RR_PHY_LEN_SECURE_2_0  14
+
 
 BWL_PRE_PACKED_STRUCT struct dot11_ftm_vs_params {
        uint8 id;                       /* DOT11_MNG_VS_ID */
@@ -4973,6 +5079,13 @@ typedef struct dot11_ftm_sync_info dot11_ftm_sync_info_t;
 #define G3PP_GUD_VERSION                               0
 #define G3PP_PLMN_LIST_IE                              0
 
+/* AP Location Public ID Info encoding */
+#define PUBLIC_ID_URI_FQDN_SE_ID               0
+/* URI/FQDN Descriptor field values */
+#define LOCATION_ENCODING_HELD                 1
+#define LOCATION_ENCODING_SUPL                 2
+#define URI_FQDN_SIZE                                  255
+
 /** hotspot2.0 indication element (vendor specific) */
 BWL_PRE_PACKED_STRUCT struct hs20_ie {
        uint8 oui[3];
index eb86b078adcb236f1155b8028ea4f71d27ac644e..dae3dd9755430568222debb3e898b0ae09eb3588 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental types and constants relating to 802.11s Mesh
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: 802.11s.h 674150 2016-12-07 03:14:40Z $
+ * $Id: 802.11s.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _802_11s_h_
@@ -290,7 +290,7 @@ BWL_PRE_PACKED_STRUCT struct dot11_mcsp_body {
        uint8 ttl;           /* remaining number of hops allowed for this element. */
        uint8 flags;         /* attributes of this channel switch attempt */
        uint8 reason;        /* reason for the mesh channel switch */
-       uint8 precedence;    /* random value in the range 0 to 65535 */
+       uint16 precedence;    /* random value in the range 0 to 65535 */
 } BWL_POST_PACKED_STRUCT;
 
 #define DOT11_MCSP_TTL_DEFAULT          1
@@ -306,7 +306,7 @@ BWL_PRE_PACKED_STRUCT struct dot11_mesh_csp {
        struct dot11_mcsp_body body; /* body of the ie */
 } BWL_POST_PACKED_STRUCT;
 typedef struct dot11_mesh_csp dot11_mesh_csp_ie_t;
-#define DOT11_MESH_CSP_IE_LEN    4       /* length of mesh channel switch parameter IE body */
+#define DOT11_MESH_CSP_IE_LEN    5       /* length of mesh channel switch parameter IE body */
 
 /* This marks the end of a packed structure section. */
 #include <packed_section_end.h>
index 85fd7e4a2fae6a7a447993a44dbe797439dd95c3..f1417935cae214693b32feae821281aa8ff0dd0e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental types and constants relating to 802.1D
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: 802.1d.h 518342 2014-12-01 23:21:41Z $
+ * $Id: 802.1d.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _802_1_D_
index d834cb741f39440b6a44cad5387c7a711d69ea95..121ec4750a966684894b2cc400d83e51e075882b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental constants relating to 802.3
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: 802.3.h 518342 2014-12-01 23:21:41Z $
+ * $Id: 802.3.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _802_3_h_
index 10992e7635f435706fc9b3a589460fdf2c7d0e9a..890b4a25545dd974dd4ccb5f365419f718028a3e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom AMBA Interconnect definitions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 12e3cb2ca27a5e6e74f1f1b53f225f459b31ab06..5f80f5bf39fa95f015bc32cf8aabb665d409d1de 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCM common config options
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index f8ce7a78e5b4eda2b4fedf85c28ba5ee22742685..77095e68fd5bcbc53f8a527d94eecd61302fe993 100644 (file)
@@ -35,7 +35,7 @@
  *              and instrumentation on top of the heap, without modifying the heap
  *              allocation implementation.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 721d7eab6b08467e413f1375f99d5808eefd88f3..0cc9ce4fda716bc775677614bf4928ad8b3c9fe8 100644 (file)
@@ -6,7 +6,7 @@
  *
  * NOTE: A ring of size N, may only hold N-1 elements.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * private L1 data cache.
  * +----------------------------------------------------------------------------
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 22fd8a0933bbfb8f0fa097458dc27e7b106409ed..b2adf61ce691e55b715bc1e547f1ac7d2248e977 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 0af59ff4f7a65893dbf8188ca9660470dd0a3f21..0a3e2b4ea75cc7c54104cef3f4b949e5de6ac478 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Misc system wide definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ed17dd53c73184d1738df9d9b9d509cf4da80b98..05743b4db2d80094c040508f8e0f22f805cd4a81 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom device-specific manifest constants.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 00adedf1cd978cf34e83b6fecb52c7fcfeec598c..7b7b23fa35a874ae21c1da5e2128b1030b4aa114 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Byte order utilities
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 97f893546b77941056cd54a7ae3987ffb232bb6e..49680d6f753e00cefbac0e0c123d4222c9701bdd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom Ethernettype  protocol definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmeth.h 565501 2015-06-22 14:29:02Z $
+ * $Id: bcmeth.h 701825 2017-05-26 16:45:27Z $
  */
 
 /*
@@ -97,6 +97,7 @@
 
 #define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH       8
 #define BCMILCP_BCM_SUBTYPEHDR_VERSION         0
+#define BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD     2
 
 /* These fields are stored in network order */
 typedef BWL_PRE_PACKED_STRUCT struct bcmeth_hdr
index a0da3f25b74ebaaf5b42f6096dc50dc7033ceb23..72c956ceebc7a5d4d2c6ff62024faa6dc3ee6c76 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Dependencies: bcmeth.h
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -26,7 +26,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmevent.h 676796 2016-12-24 18:16:02Z $
+ * $Id: bcmevent.h 700076 2017-05-17 14:42:22Z $
  *
  */
 
@@ -267,7 +267,8 @@ typedef union bcm_event_msg_u {
 #define WLC_E_TEMP_THROTTLE            154     /* Temperature throttling control event */
 #define WLC_E_LINK_QUALITY             155     /* Link quality measurement complete */
 #define WLC_E_BSSTRANS_RESP            156     /* BSS Transition Response received */
-#define WLC_E_HE_TWT_SETUP             157     /* HE TWT Setup Complete event */
+#define WLC_E_TWT_SETUP                        157     /* TWT Setup Complete event */
+#define WLC_E_HE_TWT_SETUP             157     /* TODO:Remove after merging TWT changes to trunk */
 #define WLC_E_NAN_CRITICAL             158     /* NAN Critical Event */
 #define WLC_E_NAN_NON_CRITICAL         159     /* NAN Non-Critical Event */
 #define WLC_E_RADAR_DETECTED           160     /* Radar Detected event */
@@ -279,9 +280,13 @@ typedef union bcm_event_msg_u {
                                                                                        * tx/rxchain
                                                                                        */
 #define WLC_E_FBT                      166     /* FBT event */
-#define WLC_E_LAST                     167     /* highest val + 1 for range checking */
-#if (WLC_E_LAST > 167)
-#error "WLC_E_LAST: Invalid value for last event; must be <= 166."
+#define WLC_E_PFN_SCAN_BACKOFF 167     /* PFN SCAN Backoff event */
+#define WLC_E_PFN_BSSID_SCAN_BACKOFF   168     /* PFN BSSID SCAN BAckoff event */
+#define WLC_E_AGGR_EVENT               169     /* Aggregated event */
+#define WLC_E_TVPM_MITIGATION          171     /* Change in mitigation applied by TVPM */
+#define WLC_E_LAST                     172     /* highest val + 1 for range checking */
+#if (WLC_E_LAST > 172)
+#error "WLC_E_LAST: Invalid value for last event; must be <= 172."
 #endif /* WLC_E_LAST */
 
 /* define an API for getting the string name of an event */
@@ -728,6 +733,7 @@ typedef enum wl_nan_events {
        WL_NAN_EVENT_RNG_RPT_IND                = 28,   /* Range Report */
        WL_NAN_EVENT_RNG_TERM_IND               = 29,   /* Range Termination */
        WL_NAN_EVENT_PEER_DATAPATH_SEC_INST     = 30,   /* Peer's DP sec install */
+       WL_NAN_EVENT_TXS                        = 31,   /* for tx status of follow-up and SDFs */
        WL_NAN_EVENT_INVALID                            /* delimiter for max value */
 } nan_app_events_e;
 
@@ -838,6 +844,7 @@ typedef struct {
 #define WL_EVENT_FBT_VER_1             1
 
 #define WL_E_FBT_TYPE_FBT_OTD_AUTH     1
+#define WL_E_FBT_TYPE_FBT_OTA_AUTH     2
 
 /* event structure for WLC_E_FBT */
 typedef struct {
@@ -921,4 +928,34 @@ typedef enum {
 
 #define CHANSW_REASON(reason)  (1 << reason)
 
+#define EVENT_AGGR_DATA_HDR_LEN        8
+
+typedef struct event_aggr_data {
+       uint16  num_events; /* No of events aggregated */
+       uint16  len;    /* length of the aggregated events, excludes padding */
+       uint8   pad[4]; /* Padding to make aggr event packet header aligned
+                                        * on 64-bit boundary, for a 64-bit host system.
+                                        */
+       uint8   data[]; /* Aggregate buffer containing Events */
+} event_aggr_data_t;
+
+
+/* WLC_E_TVPM_MITIGATION event structure version */
+#define WL_TVPM_MITIGATION_VERSION 1
+
+/* TVPM mitigation on/off status bits */
+#define WL_TVPM_MITIGATION_TXDC                0x1
+#define WL_TVPM_MITIGATION_TXPOWER     0x2
+#define WL_TVPM_MITIGATION_TXCHAINS    0x4
+
+/* Event structure for WLC_E_TVPM_MITIGATION */
+typedef struct wl_event_tvpm_mitigation {
+       uint16 version;         /* structure version */
+       uint16 length;          /* length of this structure */
+       uint32 timestamp_ms;    /* millisecond timestamp */
+       uint8 slice;            /* slice number */
+       uint8 pad;
+       uint16 on_off;          /* mitigation status bits */
+} wl_event_tvpm_mitigation_t;
+
 #endif /* _BCMEVENT_H_ */
index fdfd83c9ea9d90c7f2c595bd8fe968c19e5e8d29..752cd3e57566dccc2b3725a2e132a80b5cbc7096 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental constants relating to IP Protocol
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmip.h 594480 2015-10-22 03:14:33Z $
+ * $Id: bcmip.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _bcmip_h_
index f446e47bf29696c9d878c1e8e8700441583bf841..f5f2b833b935504a5949614bf9e8ed12a2009597 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental constants relating to Neighbor Discovery Protocol
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmipv6.h 518342 2014-12-01 23:21:41Z $
+ * $Id: bcmipv6.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _bcmipv6_h_
index 08d66930db742d728aecb2d43dbef05568907d88..87abca085e5fd71604b17b7b609cfcbd6a241d15 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmmsgbuf.h 676811 2016-12-24 20:48:46Z $
+ * $Id: bcmmsgbuf.h 727682 2017-10-23 04:45:57Z $
  */
 #ifndef _bcmmsgbuf_h_
 #define        _bcmmsgbuf_h_
@@ -342,8 +342,10 @@ typedef struct info_buf_payload_hdr_s {
        uint16 length;
 } info_buf_payload_hdr_t;
 
-#define PCIE_DMA_XFER_FLG_D11_LPBK_MASK        0x00000001
+#define PCIE_DMA_XFER_FLG_D11_LPBK_MASK                3
 #define PCIE_DMA_XFER_FLG_D11_LPBK_SHIFT       0
+#define PCIE_DMA_XFER_FLG_CORE_NUMBER_MASK     1
+#define PCIE_DMA_XFER_FLG_CORE_NUMBER_SHIFT    2
 
 typedef struct pcie_dma_xfer_params {
        /** common message header */
@@ -362,6 +364,7 @@ typedef struct pcie_dma_xfer_params {
        /** delay before doing the dest txfer */
        uint32          destdelay;
        uint8           rsvd[3];
+       /* bit0: D11 DMA loopback flag */
        uint8           flags;
 } pcie_dma_xfer_params_t;
 
index 114924cc9fec07786e9da52837d58c2ac352fbcc..a63e5d09494b2c0ca86c39ea95e96b94d2b368e8 100644 (file)
@@ -3,7 +3,7 @@
  * Software-specific definitions shared between device and host side
  * Explains the shared area between host and dongle
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 03a05c2ee8e43a4e9e0e09e62e1ae6362ba38e5d..570d8abc79400a97a108ce011d522eea96d7db5d 100644 (file)
@@ -2,7 +2,7 @@
  * Definitions for API from sdio common code (bcmsdh) to individual
  * host controller drivers.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 160426f952f09cbfe82273e3a5fe706011b1f5d2..1a4d12849bc20e003587d8920f37e883be988cff 100644 (file)
@@ -3,7 +3,7 @@
  *     export functions to client drivers
  *     abstract OS and BUS specific details of SDIO
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -26,7 +26,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmsdh.h 671244 2016-11-21 08:36:36Z $
+ * $Id: bcmsdh.h 698895 2017-05-11 02:55:17Z $
  */
 
 /**
@@ -75,6 +75,10 @@ struct bcmsdh_info
        uint32  sbwad;          /* Save backplane window address */
        void    *os_cxt;        /* Pointer to per-OS private data */
        bool    force_sbwad_calc; /* forces calculation of sbwad instead of using cached value */
+#ifdef DHD_WAKE_STATUS
+       unsigned int    total_wake_count;
+       int             pkt_wake;
+#endif /* DHD_WAKE_STATUS */
 };
 
 /* Detach - freeup resources allocated in attach */
index d9305e509464ed4a98c9403b806abbe9cd603e65..4786be01cbbf959af5f1b581239b4c31d20c9171 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 6230047f4f3aa437a9463875ac1c09d079a99b6e..e59b1e4c1d668b6c392c20686bf9b7af70dac39a 100644 (file)
@@ -2,7 +2,7 @@
  * Broadcom SDIO/PCMCIA
  * Software-specific definitions shared between device and host side
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ff3b0d1f2750c4cae75d1916edc9731c43678800..3b602fe0001566ce036541dcfc6de79faafd7f6e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  'Standard' SDIO HOST CONTROLLER driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 931a1a6f8fcf9f02fe6968da06c52a09eba7ca6b..44fed036beadb35ac2548bd6dcd2eb0fb18f8edc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental constants relating to TCP Protocol
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmtcp.h 518342 2014-12-01 23:21:41Z $
+ * $Id: bcmtcp.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _bcmtcp_h_
index 34cd53b6ff3505f94836b94e2d9b42424c9eea40..5884257694b30caae79e4adcc86662cabfbb764f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Misc useful os-independent macros and functions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmutils.h 674174 2016-12-07 06:09:24Z $
+ * $Id: bcmutils.h 738164 2017-12-27 08:38:59Z $
  */
 
 #ifndef        _bcmutils_h_
@@ -651,10 +651,16 @@ DECLARE_MAP_API(8, 2, 3, 3U, 0x00FF) /* setbit8() and getbit8() */
 #define MACDBG "%02x:%02x:%02x:%02x:%02x:%02x"
 #define MAC2STRDBG(ea) (ea)[0], (ea)[1], (ea)[2], (ea)[3], (ea)[4], (ea)[5]
 #else
-#define MACDBG                         "%02x:%02x:%02x"
-#define MAC2STRDBG(ea) (ea)[0], (ea)[4], (ea)[5]
+#define MACDBG                         "%02x:xx:xx:xx:x%x:%02x"
+#define MAC2STRDBG(ea) (ea)[0], ((ea)[4] & 0xf), (ea)[5]
 #endif /* SIMPLE_MAC_PRINT */
 
+#define MACOUIDBG "%02x:%x:%02x"
+#define MACOUI2STRDBG(ea) (ea)[0], (ea)[1] & 0xf, (ea)[2]
+
+#define MACOUI "%02x:%02x:%02x"
+#define MACOUI2STR(ea) (ea)[0], (ea)[1], (ea)[2]
+
 /* bcm_format_flags() bit description structure */
 typedef struct bcm_bit_desc {
        uint32  bit;
@@ -991,6 +997,18 @@ C_bcm_count_leading_zeros(uint32 u32arg)
        return (32U - shifts);
 }
 
+#ifdef BCM_ASLR_HEAP
+
+#define BCM_NVRAM_OFFSET_TCM   4
+#define BCM_NVRAM_IMG_COMPRS_FACTOR    4
+#define BCM_RNG_SIGNATURE      0xFEEDC0DE
+
+typedef struct bcm_rand_metadata {
+       uint32 signature;       /* host fills it in, FW verfies before reading rand */
+       uint32 count;   /* number of 4byte wide random numbers */
+} bcm_rand_metadata_t;
+#endif /* BCM_ASLR_HEAP */
+
 #ifdef BCMDRIVER
 /*
  * Assembly instructions: Count Leading Zeros
index 84bfddabffddffec12c8856021ef2b4a359678b0..2f550daf080adbe2dbcda7fbe915a89c67e5cfb3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Definitions for nl80211 vendor command/event access to host driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 3a5141ab20947108191d337e5559af2f7213d303..f096a42013eec6c9480e56adce00aefe76a1a20d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Header file for DHD daemon to handle timeouts
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index cb51335914712dc1bc7b2de964bbe119e3bad105..e1f807bb23cd899513c11afbf1ace83f638fa5c4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -28,7 +28,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: dhdioctl.h 675190 2016-12-14 15:27:52Z $
+ * $Id: dhdioctl.h 727682 2017-10-23 04:45:57Z $
  */
 
 #ifndef _dhdioctl_h_
@@ -55,6 +55,12 @@ enum {
        BUS_TYPE_PCIE /* for PCIE dongles */
 };
 
+typedef enum {
+       DMA_XFER_SUCCESS = 0,
+       DMA_XFER_IN_PROGRESS,
+       DMA_XFER_FAILED
+} dma_xfer_status_t;
+
 
 /* per-driver magic numbers */
 #define DHD_IOCTL_MAGIC                0x00444944
@@ -111,6 +117,9 @@ enum {
 #define DHD_PKT_MON_VAL                0x2000000
 #define DHD_PKT_MON_DUMP_VAL   0x4000000
 #define DHD_ERROR_MEM_VAL      0x8000000
+#define DHD_DNGL_IOVAR_SET_VAL 0x10000000 /**< logs the setting of dongle iovars */
+#define DHD_LPBKDTDUMP_VAL     0x20000000
+#define DHD_ECNTR_VAL  0x40000000
 
 #ifdef SDTEST
 /* For pktgen iovar */
index 40a0047a6781c91964000f566ea35f852414b0bc..b45e0bc203950ec28b1cd115ebcafa68eb288989 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom Event  protocol definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 9d76f1cd081a9de601f670cb1fb6bcb8988e0143..680bb2520235dae5f1a3b081e44dd2db165c1e27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
 
 #define        EPI_MINOR_VERSION       77
 
-#define        EPI_RC_NUMBER           11
+#define        EPI_RC_NUMBER           67
 
 #define        EPI_INCREMENTAL_NUMBER  0
 
 #define        EPI_BUILD_NUMBER        0
 
-#define        EPI_VERSION             1, 77, 11, 0
+#define        EPI_VERSION             1, 77, 67, 0
 
-#define        EPI_VERSION_NUM         0x014d0b00
+#define        EPI_VERSION_NUM         0x014d4300
 
-#define EPI_VERSION_DEV                1.77.11
+#define EPI_VERSION_DEV                1.77.67
 
 /* Driver Version String, ASCII, 32 chars max */
-#define        EPI_VERSION_STR         "1.77.11 (r)"
+#define        EPI_VERSION_STR         "1.77.67 (r)"
 
 #endif /* _epivers_h_ */
index d3a2e97c26b0f00e87ba6edeffdda0c8462baae2..91fb6dca35ef6f0d155b7aeb84346255c0377d3b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * From FreeBSD 2.2.7: Fundamental constants relating to ethernet.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: ethernet.h 518342 2014-12-01 23:21:41Z $
+ * $Id: ethernet.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _NET_ETHERNET_H_       /* use native BSD ethernet.h when available */
index df378e31e9fe07c7fa26e7f3b8dcee38d19b037c..3b9e4ce108a567770f539c23bfed06e5ed1a5e63 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * EVENT_LOG system definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: event_log.h 676811 2016-12-24 20:48:46Z $
+ * $Id: event_log.h 711908 2017-07-20 10:37:34Z $
  */
 
 #ifndef _EVENT_LOG_H_
@@ -97,6 +97,8 @@ typedef struct event_log_block {
        uint32 extra_hdr_info;          /* LSB: 6 bits set id. MSB 24 bits reserved */
        uint32 event_logs;
 } event_log_block_t;
+#define EVENT_LOG_BLOCK_HDRLEN         8 /* pktlen 2 + count 2 + extra_hdr_info 4 */
+#define NAN_EVENT_LOG_MIN_LENGTH       2 /* Minimum length of Nan event */
 
 typedef enum {
        SET_DESTINATION_INVALID = -1,
index a14d33d47e3677223d78e120d760f88ba890465b..5d82747575138db11169f192e9ce992767d6459a 100644 (file)
@@ -4,7 +4,7 @@
  * This file describes the payloads of event log entries that are data buffers
  * rather than formatted string entries. The contents are generally XTLVs.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: event_log_payload.h 676796 2016-12-24 18:16:02Z $
+ * $Id: event_log_payload.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _EVENT_LOG_PAYLOAD_H_
index 3e0a129bbbd6b8c6e63f711c421650d51bf050e9..55cae96e1dc22aabbff9951d67a5a12ba3ba4059 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * EVENT_LOG system definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: event_log_set.h 585396 2015-09-10 09:04:56Z $
+ * $Id: event_log_set.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _EVENT_LOG_SET_H_
 #define EVENT_LOG_SET_PSM      2
 #define EVENT_LOG_SET_ERROR    3
 #define EVENT_LOG_SET_MEM_API  4
+/* Share the set with MEM_API for now to limit ROM invalidation.
+ * The above set is used in dingo only
+ * On trunk, MSCH should move to a different set.
+ */
+#define EVENT_LOG_SET_MSCH_PROFILER    4
 #define EVENT_LOG_SET_ECOUNTERS 5      /* Host to instantiate this for ecounters. */
+#define EVENT_LOG_SET_6        6       /* Instantiated by host for channel switch logs */
+#define EVENT_LOG_SET_7        7       /* Instantiated by host for AMPDU stats */
 
 #endif /* _EVENT_LOG_SET_H_ */
index de410dd1bb5eafa452b77f1f268cd6938069125b..9d43252800f16e52b818d05f61a18e3babe9864b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * EVENT_LOG system definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: event_log_tag.h 676145 2016-12-20 20:14:56Z $
+ * $Id: event_log_tag.h 700681 2017-05-20 16:37:38Z $
  */
 
 #ifndef _EVENT_LOG_TAG_H_
 #define EVENT_LOG_TAG_4WAYHANDSHAKE            143
 #define EVENT_LOG_TAG_MSCHPROFILE_TLV          144
 #define EVENT_LOG_TAG_ADPS                     145
-#define EVENT_LOG_TAG_MBO_DBG          146
-#define EVENT_LOG_TAG_MBO_INFO         147
-#define EVENT_LOG_TAG_MBO_ERR          148
-#define EVENT_LOG_TAG_TXDELAY          149
+#define EVENT_LOG_TAG_MBO_DBG                  146
+#define EVENT_LOG_TAG_MBO_INFO                 147
+#define EVENT_LOG_TAG_MBO_ERR                  148
+#define EVENT_LOG_TAG_TXDELAY                  149
 #define EVENT_LOG_TAG_BCNTRIM_INFO             150
 #define EVENT_LOG_TAG_BCNTRIM_TRACE            151
-#define EVENT_LOG_TAG_OPS_INFO         152
-#define EVENT_LOG_TAG_STATS    153
+#define EVENT_LOG_TAG_OPS_INFO                 152
+#define EVENT_LOG_TAG_STATS                    153
+#define EVENT_LOG_TAG_BAM                      154
+#define EVENT_LOG_TAG_TXFAIL                   155
+#define EVENT_LOG_TAG_AWDL_CONFIG_DBG          156
+#define EVENT_LOG_TAG_AWDL_SYNC_DBG            157
+#define EVENT_LOG_TAG_AWDL_PEER_DBG            158
+#define EVENT_LOG_TAG_RANDMAC_INFO             159
+#define EVENT_LOG_TAG_RANDMAC_DBG              160
+#define EVENT_LOG_TAG_RANDMAC_ERR              161
+#define EVENT_LOG_TAG_AWDL_DFSP_DBG            162
+#define EVENT_LOG_TAG_TPA_ERR                  163
+#define EVENT_LOG_TAG_TPA_INFO                 164
 
 /* EVENT_LOG_TAG_MAX   = Set to the same value of last tag, not last tag + 1 */
-#define EVENT_LOG_TAG_MAX                      153
+#define EVENT_LOG_TAG_MAX                      164
 /* Note: New event should be added/reserved in trunk before adding it to branches */
 
 
index cd24bdf28eab117f8eddd9eceb5cc526e6d1faff..8a288fe3b7a500f3729dd6ccfb4e8ab08a837e1f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Trace log blocks sent over HBUS
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index e7c005c6f1b3537cd89730f4f2dda13212b35250..cd93896a576fd6f80e38557c10a376422360f4cb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND arm trap handling.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 3470d6a91307852669b4a3eeb007d8fd64c658fa..2d3465be6bd670d55ed834a3df7af945b16a9ea3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Console support for RTE - for host use only.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 239e596e96af76775182550ebc3a10cd13b02f17..326e1cde34ff104f51cebb574ad8e99d87ceb8dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND Run Time Environment debug info area
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index e5d0eaa650fe9f55fde84e35c6bfa802d099cb56..de2ab534b37b7d0a7272dc1eefcf79f10b34938d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND generic packet pool operation primitives
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ad778da896e7f709674bc975b8ecfd82eba3c58a..eb478169639327642666f4a5888f0905d53a2c53 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND generic pktq operation primitives
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index bfc916693e1f3f0ce4950d064d6431bceceb5bda..7d24bd1c0cc37c6e71421f1e9994c966ad5d84d0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * HND SiliconBackplane PMU support.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index b35380ad57bf1de4e7d79be2b21318f8a15959c2..83ab579efa617acc22f00dd105b8f0a8989944ce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom HND chip & on-chip-interconnect-related definitions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 59905b6ad4b7c24c40893525283cdc597cad3ad5..2e9fa358f3fd0e5c348027fab3c122b2c7383d28 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux OS Independent Layer
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 271fe2fee96c7214bfb145953214c7a5d831346c..4fa656dc50ecb5f32a1344b2b4c6060ac13000fd 100644 (file)
@@ -2,7 +2,7 @@
  * Linux-specific abstractions to gain some independence from linux kernel versions.
  * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index a2da1d3c7967a9d176d08e93eb14d1d367f9965b..d8587936f7c28099ca1395e6b1cacaee1f49df02 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Trace messages sent over HBUS
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index d899141f7e56beaf80741a495a02f6b7e5a5823f..a2c2aaa9a7ec4ae5b457db297a22125ae6069e9d 100644 (file)
@@ -2,7 +2,7 @@
  * Fundamental types and constants relating to WFA NAN
  * (Neighbor Awareness Networking)
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
  * software in any way with any other Broadcom software provided under a license
  * other than the GPL, without Broadcom's express prior written consent.
  *
+ *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: nan.h 676796 2016-12-24 18:16:02Z $
+ * $Id: nan.h 700076 2017-05-17 14:42:22Z $
  */
 #ifndef _NAN_H_
 #define _NAN_H_
 #define NAN_ATTR_LEN_OFF       1
 #define NAN_ATTR_DATA_OFF      3
 
-#define NAN_ATTR_ID_LEN                 1      /* ID field length */
-#define NAN_ATTR_LEN_LEN        2      /* Length field length */
+#define NAN_ATTR_ID_LEN                 1u     /* ID field length */
+#define NAN_ATTR_LEN_LEN        2u     /* Length field length */
 #define NAN_ATTR_HDR_LEN        (NAN_ATTR_ID_LEN + NAN_ATTR_LEN_LEN)
 #define NAN_ENTRY_CTRL_LEN       1      /* Entry control field length from FAM attribute */
 #define NAN_MAP_ID_LEN           1     /* MAP ID length to signify band */
 #define NAN_OPERATING_CLASS_LEN  1     /* operating class field length from NAN FAM */
 #define NAN_CHANNEL_NUM_LEN      1     /* channel number field length 1 byte */
 
+/* NAN slot duration / period */
+#define NAN_MIN_TU             16
+#define NAN_TU_PER_DW          512
+#define NAN_MAX_DW             16
+#define NAN_MAX_TU             (NAN_MAX_DW * NAN_TU_PER_DW)
+
+#define NAN_SLOT_DUR_0TU       0
+#define NAN_SLOT_DUR_16TU      16
+#define NAN_SLOT_DUR_32TU      32
+#define NAN_SLOT_DUR_64TU      64
+#define NAN_SLOT_DUR_128TU     128
+#define NAN_SLOT_DUR_256TU     256
+#define NAN_SLOT_DUR_512TU     512
+#define NAN_SLOT_DUR_1024TU    1024
+#define NAN_SLOT_DUR_2048TU    2048
+#define NAN_SLOT_DUR_4096TU    4096
+#define NAN_SLOT_DUR_8192TU    8192
+
 #define NAN_MAP_ID_2G   2  /* NAN Further Avail Map ID for band 2.4G */
 #define NAN_MAP_ID_5G   5  /* NAN Further Avail Map ID for band 5G */
 #define NAN_MAP_NUM_IDS 2  /* Max number of NAN Further Avail Map IDs supported */
 
-/* map id is 4 bits */
-#define NAN_CMN_MAP_ID_LEN_BITS        4
-/* siz eof ndc id */
+/* size of ndc id */
 #define NAN_DATA_NDC_ID_SIZE 6
 
 #define NAN_AVAIL_ENTRY_LEN_RES0 7      /* Avail entry len in FAM attribute for resolution 16TU */
@@ -154,9 +171,16 @@ enum {
        NAN_ATTR_CIPHER_SUITE_INFO = 34,
        NAN_ATTR_SEC_CTX_ID_INFO = 35,
        NAN_ATTR_SHARED_KEY_DESC = 36,
+       NAN_ATTR_MCAST_SCHED_CHANGE = 37,
+       NAN_ATTR_MCAST_SCHED_OWNER_CHANGE = 38,
+       NAN_ATTR_PUBLIC_AVAILABILITY = 39,
+       NAN_ATTR_SUB_SVC_ID_LIST = 40,
+       /* change NAN_ATTR_MAX_ID to max ids + 1, excluding NAN_ATTR_VENDOR_SPECIFIC.
+        * This is used in nan_parse.c
+        */
+       NAN_ATTR_MAX_ID         = NAN_ATTR_SUB_SVC_ID_LIST + 1,
 
-       NAN_ATTR_VENDOR_SPECIFIC = 221,
-       NAN_ATTR_NAN_MGMT       = 222   /* NAN Mgmt Attr (TBD; not in spec yet) */
+       NAN_ATTR_VENDOR_SPECIFIC = 221
 };
 
 enum wifi_nan_avail_resolution {
@@ -383,6 +407,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_info_attr_s {
        uint16 last_movement;
 
 } BWL_POST_PACKED_STRUCT wifi_nan_ranging_info_attr_t;
+
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_setup_attr_hdr_s {
        uint8 id;                       /* 0x1B */
        uint16 len;                     /* length that follows */
@@ -395,28 +420,16 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_setup_attr_hdr_s {
        uint8 reason;
 } BWL_POST_PACKED_STRUCT wifi_nan_ranging_setup_attr_hdr_t;
 
-/* Common time structure used in NAN Availability, NDC, Immutable schedules */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_time_bitmap_s {
-       uint16 ctrl;            /* Time bitmap control */
-       uint8 len;              /* Time bitmap length */
-       uint8 bitmap[1];        /* Time bitmap */
-} BWL_POST_PACKED_STRUCT wifi_nan_time_bitmap_t;
-
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_time_bitmap_s {
-       uint8 map_id;                   /* Map ID to which this bit map corresponds */
-       wifi_nan_time_bitmap_t time_bmp;
-} BWL_POST_PACKED_STRUCT wifi_nan_ranging_time_bitmap_t;
-
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_setup_attr_s {
 
        wifi_nan_ranging_setup_attr_hdr_t setup_attr_hdr;
        /* Below fields not required when frm type = termination */
        uint8 ranging_ctrl; /* Bit 0: ranging report required or not */
        uint8 ftm_params[3];
-       wifi_nan_ranging_time_bitmap_t range_tbm; /* Ranging timebit map info */
+       uint8 data[];   /* schedule entry list */
 } BWL_POST_PACKED_STRUCT wifi_nan_ranging_setup_attr_t;
-#define NAN_RANGE_SETUP_ATTR_OFFSET_TBM_INFO (OFFSETOF(wifi_nan_ranging_setup_attr_t, range_tbm))
 
+#define NAN_RANGE_SETUP_ATTR_OFFSET_TBM_INFO (OFFSETOF(wifi_nan_ranging_setup_attr_t, data))
 
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_report_attr_s {
        uint8 id;                       /* 0x1C */
@@ -436,7 +449,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_report_attr_s {
 /* Ranging control flags */
 #define NAN_RNG_REPORT_REQUIRED                0x01
 #define NAN_RNG_FTM_PARAMS_PRESENT     0x02
-#define NAN_RNG_AVAIL_INFO_PRESENT     0X04
+#define NAN_RNG_SCHED_ENTRY_PRESENT    0X04
 
 /* Location info flags */
 #define NAN_RNG_LOCATION_FLAGS_LOCAL_CORD              0x1
@@ -496,6 +509,9 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ranging_report_attr_s {
 #define NAN_CONN_CAPABILITY_IBSS       0x0010
 #define NAN_CONN_CAPABILITY_MESH       0x0020
 
+#define NAN_DEFAULT_MAP_ID             0       /* nan default map id */
+#define NAN_DEFAULT_MAP_CTRL           0       /* nan default map control */
+
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_conn_cap_attr_s {
        /* Attribute ID - 0x04. */
        uint8 id;
@@ -504,15 +520,11 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_conn_cap_attr_s {
        uint16  conn_cap_bmp;   /* Connection capability bitmap */
 } BWL_POST_PACKED_STRUCT wifi_nan_conn_cap_attr_t;
 
-#define NAN_SLOT_RES_16TU 16
-#define NAN_SLOT_RES_32TU 32
-#define NAN_SLOT_RES_64TU 64
-#define NAN_SLOT_RES_128TU 128
-
 /* NAN Element container Attribute */
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_container_attr_s {
        uint8 id;       /* id - 0x20 */
        uint16 len;     /* Total length of following IEs */
+       uint8 map_id;   /* map id */
        uint8 data[1];  /* Data pointing to one or more IEs */
 } BWL_POST_PACKED_STRUCT wifi_nan_container_attr_t;
 
@@ -522,15 +534,23 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_container_attr_s {
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_avail_attr_s {
        uint8 id;       /* id - 0x12 */
        uint16 len;     /* total length */
+       uint8 seqid;    /* sequence id */
        uint16 ctrl;    /* attribute control */
        uint8 entry[1]; /* availability entry list */
 } BWL_POST_PACKED_STRUCT wifi_nan_avail_attr_t;
 
+/* for processing/building time bitmap info in nan_avail_entry */
+typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_time_bitmap_s {
+       uint16 ctrl;            /* Time bitmap control */
+       uint8 len;              /* Time bitmap length */
+       uint8 bitmap[]; /* Time bitmap */
+} BWL_POST_PACKED_STRUCT wifi_nan_time_bitmap_t;
+
 /* Availability Entry format */
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_avail_entry_attr_s {
        uint16 len;             /* Length */
        uint16 entry_cntrl;     /* Entry Control */
-       uint8 var[1];           /* Time bitmap fields and channel entry list */
+       uint8 var[];            /* Time bitmap and channel entry list */
 } BWL_POST_PACKED_STRUCT wifi_nan_avail_entry_attr_t;
 
 /* FAC Channel Entry  (section 10.7.19.1.5) */
@@ -541,16 +561,36 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_chan_entry_s {
        uint8 aux_chan[0];                      /* Auxiliary Channel bitmap */
 } BWL_POST_PACKED_STRUCT wifi_nan_chan_entry_t;
 
+/* Channel entry */
+typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_channel_entry_s {
+       uint8 opclass;          /* Operating class */
+       uint16 chan_bitmap;     /* Channel bitmap */
+       uint8 prim_bitmap;      /* Primary channel bitmap */
+       uint16 aux_bitmap;      /* Time bitmap length */
+} BWL_POST_PACKED_STRUCT wifi_nan_channel_entry_t;
+
+/* Type of  Availability: committed */
+#define NAN_ENTRY_CNTRL_TYPE_COMM_AVAIL_MASK   0x1
+/* Type of  Availability: potential */
+#define NAN_ENTRY_CNTRL_TYPE_POTEN_AVAIL_MASK  0x2
+/* Type of  Availability: conditional */
+#define NAN_ENTRY_CNTRL_TYPE_COND_AVAIL_MASK   0x4
+
 #define NAN_AVAIL_CTRL_MAP_ID_MASK             0x000F
 #define NAN_AVAIL_CTRL_MAP_ID(_ctrl)           ((_ctrl) & NAN_AVAIL_CTRL_MAP_ID_MASK)
 #define NAN_AVAIL_CTRL_COMM_CHANGED_MASK       0x0010
 #define NAN_AVAIL_CTRL_COMM_CHANGED(_ctrl)     ((_ctrl) & NAN_AVAIL_CTRL_COMM_CHANGED_MASK)
 #define NAN_AVAIL_CTRL_POTEN_CHANGED_MASK      0x0020
 #define NAN_AVAIL_CTRL_POTEN_CHANGED(_ctrl)    ((_ctrl) & NAN_AVAIL_CTRL_POTEN_CHANGED_MASK)
-#define NAN_AVAIL_CTRL_SEQ_ID_MASK             0xFF00
-#define NAN_AVAIL_CTRL_SEQ_ID_SHIFT            8
-#define NAN_AVAIL_CTRL_SEQ_ID(_ctrl)           (((_ctrl) & NAN_AVAIL_CTRL_SEQ_ID_MASK) \
-               >> NAN_AVAIL_CTRL_SEQ_ID_SHIFT)
+#define NAN_AVAIL_CTRL_PUBLIC_CHANGED_MASK     0x0040
+#define NAN_AVAIL_CTRL_PUBLIC_CHANGED(_ctrl)   ((_ctrl) & NAN_AVAIL_CTRL_PUBLIC_CHANGED_MASK)
+#define NAN_AVAIL_CTRL_NDC_CHANGED_MASK                0x0080
+#define NAN_AVAIL_CTRL_NDC_CHANGED(_ctrl)      ((_ctrl) & NAN_AVAIL_CTRL_NDC_CHANGED_MASK)
+#define NAN_AVAIL_CTRL_MCAST_CHANGED_MASK      0x0100
+#define NAN_AVAIL_CTRL_MCAST_CHANGED(_ctrl)    ((_ctrl) & NAN_AVAIL_CTRL_MCAST_CHANGED_MASK)
+#define NAN_AVAIL_CTRL_MCAST_CHG_CHANGED_MASK  0x0200
+#define NAN_AVAIL_CTRL_MCAST_CHG_CHANGED(_ctrl)        ((_ctrl) & NAN_AVAIL_CTRL_MCAST_CHG_CHANGED_MASK)
+#define NAN_AVAIL_CTRL_CHANGED_FLAGS_MASK      0x03f0
 
 #define NAN_AVAIL_ENTRY_CTRL_AVAIL_TYPE_MASK 0x07
 #define NAN_AVAIL_ENTRY_CTRL_AVAIL_TYPE(_flags) ((_flags) & NAN_AVAIL_ENTRY_CTRL_AVAIL_TYPE_MASK)
@@ -558,6 +598,10 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_chan_entry_s {
 #define NAN_AVAIL_ENTRY_CTRL_USAGE_SHIFT 3
 #define NAN_AVAIL_ENTRY_CTRL_USAGE(_flags) (((_flags) & NAN_AVAIL_ENTRY_CTRL_USAGE_MASK) \
        >> NAN_AVAIL_ENTRY_CTRL_USAGE_SHIFT)
+#define NAN_AVAIL_ENTRY_CTRL_UTIL_MASK 0x1E0
+#define NAN_AVAIL_ENTRY_CTRL_UTIL_SHIFT 5
+#define NAN_AVAIL_ENTRY_CTRL_UTIL(_flags) (((_flags) & NAN_AVAIL_ENTRY_CTRL_UTIL_MASK) \
+       >> NAN_AVAIL_ENTRY_CTRL_UTIL_SHIFT)
 #define NAN_AVAIL_ENTRY_CTRL_RX_NSS_MASK 0xF00
 #define NAN_AVAIL_ENTRY_CTRL_RX_NSS_SHIFT 8
 #define NAN_AVAIL_ENTRY_CTRL_RX_NSS(_flags) (((_flags) & NAN_AVAIL_ENTRY_CTRL_RX_NSS_MASK) \
@@ -714,19 +758,6 @@ enum
 #define NDL_ATTR_IM_TIME_BMP_CTRL_LEN  2
 #define NDL_ATTR_IM_TIME_BMP_LEN_LEN   1
 
-/* immutable schedule - as per r21 */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_im_sched_field_s {
-       uint8 no_of_im_entries;
-       uint8 var[];
-} BWL_POST_PACKED_STRUCT wifi_nan_ndl_im_sched_field_t;
-
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_im_sched_entry_s {
-       uint8 map_id;           /* map id */
-       uint16 tbmp_ctrl;       /* time bitmap control */
-       uint8 tbmp_len;         /* time bitmap len */
-       uint8 tbmp[];           /* time bitmap - Optional */
-} BWL_POST_PACKED_STRUCT wifi_nan_ndl_im_sched_entry_t;
-
 /*
  * NDL Control field - Table xx
  */
@@ -738,8 +769,22 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_im_sched_entry_s {
 #define NDL_ATTR_CTRL_NDC_ATTR_PRESENT_SHIFT   2
 #define NDL_ATTR_CTRL_QOS_ATTR_PRESENT_MASK            0x08
 #define NDL_ATTR_CTRL_QOS_ATTR_PRESENT_SHIFT   3
-
-#define NAN_NDL_TYPE_MASK      0x0F
+#define NDL_ATTR_CTRL_MAX_IDLE_PER_PRESENT_MASK                0x10    /* max idle period */
+#define NDL_ATTR_CTRL_MAX_IDLE_PER_PRESENT_SHIFT       4
+#define NDL_ATTR_CTRL_NDL_TYPE_MASK                            0x20    /* NDL type */
+#define NDL_ATTR_CTRL_NDL_TYPE_SHIFT                   5
+#define NDL_ATTR_CTRL_NDL_SETUP_REASON_MASK            0xC0    /* NDL Setup Reason */
+#define NDL_ATTR_CTRL_NDL_SETUP_REASON_SHIFT   6
+
+/* NDL setup Reason */
+#define NDL_ATTR_CTRL_NDL_TYPE_S_NDL   0x0     /* S-NDL */
+#define NDL_ATTR_CTRL_NDL_TYPE_P_NDL   0x1     /* P-NDL */
+
+/* NDL setup Reason */
+#define NDL_ATTR_CTRL_NDL_SETUP_REASON_NDP_RANG        0x0     /* NDP or Ranging */
+#define NDL_ATTR_CTRL_NDL_SETUP_REASON_FSD_GAS 0x1     /* FSD using GAS */
+
+#define NAN_NDL_TYPE_MASK                              0x0F
 #define NDL_ATTR_TYPE_STATUS_REQUEST   0x00
 #define NDL_ATTR_TYPE_STATUS_RESPONSE  0x01
 #define NDL_ATTR_TYPE_STATUS_CONFIRM   0x02
@@ -755,6 +800,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_im_sched_entry_s {
 #define NAN_NDL_CONFIRM(_ndl)          (((_ndl)->type_status & NAN_NDL_TYPE_MASK) == \
                                                                NDL_ATTR_TYPE_STATUS_CONFIRM)
 
+
 #define NAN_NDL_STATUS_SHIFT   4
 #define NAN_NDL_STATUS_MASK    0xF0
 #define NAN_NDL_CONT(_ndl)     (((_ndl)->type_status & NAN_NDL_STATUS_MASK) == \
@@ -769,8 +815,14 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_im_sched_entry_s {
 #define NDL_ATTR_CTRL_IMSCHED_PRESENT  (1 << NDL_ATTR_CTRL_IM_SCHED_PRESENT_SHIFT)
 #define NDL_ATTR_CTRL_NDC_PRESENT              (1 << NDL_ATTR_CTRL_NDC_ATTR_PRESENT_SHIFT)
 #define NDL_ATTR_CTRL_NDL_QOS_PRESENT  (1 << NDL_ATTR_CTRL_QOS_ATTR_PRESENT_SHIFT)
+#define NDL_ATTR_CTRL_MAX_IDLE_PER_PRESENT     (1 << NDL_ATTR_CTRL_MAX_IDLE_PER_PRESENT_SHIFT)
 
-#define NDL_ATTR_PEERID_LEN            1
+#define NA_NDL_IS_IMMUT_PRESENT(ndl) (((ndl)->ndl_ctrl) & NDL_ATTR_CTRL_IMSCHED_PRESENT)
+#define NA_NDL_IS_PEER_ID_PRESENT(ndl) (((ndl)->ndl_ctrl) & NDL_ATTR_CTRL_PEER_ID_PRESENT)
+#define NA_NDL_IS_MAX_IDLE_PER_PRESENT(ndl) (((ndl)->ndl_ctrl) & NDL_ATTR_CTRL_MAX_IDLE_PER_PRESENT)
+
+#define NDL_ATTR_PEERID_LEN                            1
+#define NDL_ATTR_MAX_IDLE_PERIOD_LEN   2
 
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_attr_s {
        uint8 id;               /* NAN_ATTR_NAN_NDL = 0x17 */
@@ -783,27 +835,32 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_attr_s {
 } BWL_POST_PACKED_STRUCT wifi_nan_ndl_attr_t;
 
 /*
- * NDL QoS Attribute  WFA Tech. Spec ver 1.0.r12 (section 10.7.19.4)
+ * NDL QoS Attribute  WFA Tech. Spec ver r26
  */
-#define NDL_QOS_ATTR_MAX_LATENCY_LEN        3
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_qos_attr_s {
        uint8 id;               /* NAN_ATTR_NAN_NDL_QOS = 24 */
        uint16 len;             /* Length of the attribute field following */
        uint8 min_slots;        /* Min. number of FAW slots needed per DW interval */
-       uint8 max_latency[NDL_QOS_ATTR_MAX_LATENCY_LEN];  /* Max interval between non-cont FAW */
+       uint16 max_latency;  /* Max interval between non-cont FAW */
 } BWL_POST_PACKED_STRUCT wifi_nan_ndl_qos_attr_t;
 
+/* no preference to min time slots */
+#define NAN_NDL_QOS_MIN_SLOT_NO_PREF   0
+/* no preference to no. of slots between two non-contiguous slots */
+#define NAN_NDL_QOS_MAX_LAT_NO_PREF            0xFFFF
+
 /* Device Capability Attribute */
 
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_dev_cap_s {
        uint8 id;               /* 0x0F */
        uint16 len;             /* Length */
+       uint8 map_id;           /* map id */
        uint16 commit_dw_info;  /* Committed DW Info */
        uint8 bands_supported;  /* Supported Bands */
        uint8 op_mode;          /* Operation Mode */
        uint8 num_antennas;     /* Bit 0-3 tx, 4-7 rx */
        uint16 chan_switch_time;        /* Max channel switch time in us */
-       uint8 capabilities;     /* Bit-0 is 1 if DFS Master, Bits 1-7 reserved */
+       uint8 capabilities;     /* DFS Master, Extended key id etc */
 } BWL_POST_PACKED_STRUCT wifi_nan_dev_cap_t;
 
 /* Awake DW Info field format */
@@ -821,11 +878,6 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_dev_cap_s {
 
 /* Device Capability Attribute Format */
 
-/* Operation Mode: HT */
-#define NAN_DEV_CAP_HT_OPER_MODE_MASK  0x01
-/* Operation Mode: VHT */
-#define NAN_DEV_CAP_VHT_OPER_MODE_MASK 0x02
-
 /* Committed DW Info field format */
 /* 2.4GHz DW */
 #define NAN_DEV_CAP_COMMIT_DW_2G_MASK  0x07
@@ -856,12 +908,22 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_dev_cap_s {
 #define NAN_DEV_CAP_TX_ANT_MASK                        0x0F
 #define NAN_DEV_CAP_RX_ANT_MASK                        0xF0
 
+/* Device capabilities */
+
+/* DFS master capability */
+#define NAN_DEV_CAP_DFS_MASTER_MASK            0x01
+#define NAN_DEV_CAP_DFS_MASTER_SHIFT   0
+/* extended iv cap */
+#define NAN_DEV_CAP_EXT_KEYID_MASK             0x02
+#define NAN_DEV_CAP_EXT_KEYID_SHIFT            1
+
 /* Band IDs */
 enum {
        NAN_BAND_ID_TVWS                = 0,
-       NAN_BAND_ID_SIG                 = 1,
-       NAN_BAND_ID_2G                  = 2,
-       NAN_BAND_ID_5G                  = 4,
+       NAN_BAND_ID_SIG                 = 1,    /* Sub 1 GHz */
+       NAN_BAND_ID_2G                  = 2,    /* 2.4 GHz */
+       NAN_BAND_ID_3G                  = 3,    /* 3.6 GHz */
+       NAN_BAND_ID_5G                  = 4,    /* 4.9 & 5 GHz */
        NAN_BAND_ID_60G                 = 5
 };
 typedef uint8 nan_band_id_t;
@@ -893,6 +955,9 @@ typedef uint8 nan_band_id_t;
 #define NAN_ULW_CTRL_TYPE_CHAN_NOAUX   1
 #define NAN_ULW_CTRL_TYPE_CHAN_AUX     2
 
+#define NAN_ULW_CNT_DOWN_NO_EXPIRE     0xFF    /* ULWs doen't end until next sched update */
+#define NAN_ULW_CNT_DOWN_CANCEL                0x0             /* cancel remaining ulws */
+
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ulw_attr_s {
        uint8 id;
        uint16 len;
@@ -967,6 +1032,11 @@ typedef BWL_PRE_PACKED_STRUCT struct nan2_pub_act_frame_s {
 #define NAN_REASON_FTM_PARAM_INCAP             0x4
 #define NAN_REASON_NO_MOVEMENT                 0x5
 #define NAN_REASON_INVALID_AVAIL               0x6
+#define NAN_REASON_IMMUT_UNACCEPT              0x7
+#define NAN_REASON_SEC_POLICY                  0x8
+#define NAN_REASON_QOS_UNACCEPT                        0x9
+#define NAN_REASON_NDP_REJECT                  0xa
+#define NAN_REASON_NDL_UNACCEPTABLE            0xb
 
 /* nan 2.0 qos (not attribute) */
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndp_qos_s {
@@ -978,7 +1048,6 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndp_qos_s {
 
 /* NDP control bitmap defines */
 #define NAN_NDP_CTRL_CONFIRM_REQUIRED          0x01
-#define NAN_NDP_CTRL_EXPLICIT_CONFIRM          0x02
 #define NAN_NDP_CTRL_SECURTIY_PRESENT          0x04
 #define NAN_NDP_CTRL_PUB_ID_PRESENT            0x08
 #define NAN_NDP_CTRL_RESP_NDI_PRESENT          0x10
@@ -1042,27 +1111,83 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndp_attr_s {
 #define NAN_RNG_REJECT(_rsua)  (((_rsua)->type_status & NAN_RNG_STATUS_MASK) == \
                                                                        NAN_RNG_STATUS_REJECT)
 
+/* schedule entry */
+typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_sched_entry_s {
+       uint8 map_id;           /* map id */
+       uint16 tbmp_ctrl;       /* time bitmap control */
+       uint8 tbmp_len;         /* time bitmap len */
+       uint8 tbmp[];           /* time bitmap - Optional */
+} BWL_POST_PACKED_STRUCT wifi_nan_sched_entry_t;
+
+#define NAN_SCHED_ENTRY_MIN_SIZE       OFFSETOF(wifi_nan_sched_entry_t, tbmp)
+#define NAN_SCHED_ENTRY_SIZE(_entry)   (NAN_SCHED_ENTRY_MIN_SIZE + (_entry)->tbmp_len)
+
+/* for dev cap, element container etc. */
+#define NAN_DEV_ELE_MAPID_CTRL_MASK            0x1
+#define NAN_DEV_ELE_MAPID_CTRL_SHIFT   0
+#define NAN_DEV_ELE_MAPID_MASK         0x1E
+#define NAN_DEV_ELE_MAPID_SHIFT                1
+
+#define NAN_DEV_ELE_MAPID_CTRL_SET(_mapid_field, value) \
+       do {(_mapid_field) &= ~NAN_DEV_ELE_MAPID_CTRL_MASK; \
+               (_mapid_field) |= ((value << NAN_DEV_ELE_MAPID_CTRL_SHIFT) & \
+               NAN_DEV_ELE_MAPID_CTRL_MASK); \
+       } while (0);
+
+#define NAN_DEV_ELE_MAPID_CTRL_GET(_mapid_field) \
+       (((_mapid_field) & NAN_DEV_ELE_MAPID_CTRL_MASK) >> \
+       NAN_DEV_ELE_MAPID_CTRL_SHIFT)
+
+#define NAN_DEV_ELE_MAPID_SET(_mapid_field, value) \
+       do {(_mapid_field) &= ~NAN_DEV_ELE_MAPID_MASK; \
+               (_mapid_field) |= ((value << NAN_DEV_ELE_MAPID_SHIFT) & \
+               NAN_DEV_ELE_MAPID_MASK); \
+       } while (0);
+
+#define NAN_DEV_ELE_MAPID_GET(_mapid_field) \
+       (((_mapid_field) & NAN_DEV_ELE_MAPID_MASK) >> \
+       NAN_DEV_ELE_MAPID_SHIFT)
+
+/* schedule entry map id handling */
+#define NAN_SCHED_ENTRY_MAPID_MASK             0x0F
+#define NAN_SCHED_ENTRY_MAPID_SHIFT            0
+
+#define NAN_SCHED_ENTRY_MAPID_SET(_mapid_field, value) \
+       do {(_mapid_field) &= ~NAN_SCHED_ENTRY_MAPID_MASK; \
+               (_mapid_field) |= ((value << NAN_SCHED_ENTRY_MAPID_SHIFT) & \
+               NAN_SCHED_ENTRY_MAPID_MASK); \
+       } while (0);
+
+#define NAN_SCHED_ENTRY_MAPID_GET(_mapid_field) \
+       (((_mapid_field) & NAN_SCHED_ENTRY_MAPID_MASK) >> \
+       NAN_SCHED_ENTRY_MAPID_SHIFT)
+
 /* NDC attribute */
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndc_attr_s {
        uint8 id;
        uint16 len;
        uint8 ndc_id[NAN_DATA_NDC_ID_SIZE];
-       uint8 sched_cntrl;
-       uint16 tbmp_ctrl;       /* time bitmap control */
-       uint8 tbmp_len;         /* time bitmap len */
-       uint8 tbmp[];           /* time bitmap - Optional */
+       uint8 attr_cntrl;
+       uint8 var[];
 } BWL_POST_PACKED_STRUCT wifi_nan_ndc_attr_t;
 
-/* Schedule control subfield of NDC attr */
-/* Schedule indication */
-#define NAN_NDC_ATTR_SCHED_IND_MASK    0x1E
-#define NAN_NDC_ATTR_SCHED_IND_SHIFT 1
+/* Attribute control subfield of NDC attr */
 /* Proposed NDC */
-#define NAN_NDC_ATTR_PROPOSED_NDC_MASK 0x40
-#define NAN_NDC_ATTR_PROPOSED_NDC_SHIFT 6
+#define NAN_NDC_ATTR_PROPOSED_NDC_MASK 0x1
+#define NAN_NDC_ATTR_PROPOSED_NDC_SHIFT 0
+
+/* get & set */
+#define NAN_NDC_GET_PROPOSED_FLAG(_attr)       \
+       (((_attr)->attr_cntrl & NAN_NDC_ATTR_PROPOSED_NDC_MASK) >>      \
+       NAN_NDC_ATTR_PROPOSED_NDC_SHIFT)
+#define NAN_NDC_SET_PROPOSED_FLAG(_attr, value) \
+       do {((_attr)->attr_cntrl &= ~NAN_NDC_ATTR_PROPOSED_NDC_MASK); \
+               ((_attr)->attr_cntrl |= \
+               (((value) << NAN_NDC_ATTR_PROPOSED_NDC_SHIFT) & NAN_NDC_ATTR_PROPOSED_NDC_MASK)); \
+       } while (0)
 
 /* Service descriptor extension attribute */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_svc_descriptor_ext_attr_t {
+typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_svc_desc_ext_attr_s {
        /* Attribute ID - 0x11 */
        uint8 id;
        /* Length of the following fields in the attribute */
@@ -1071,12 +1196,12 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_svc_descriptor_ext_attr_t {
        uint8 instance_id;
        /* SDE control field */
        uint16 control;
-       /* Range limit - ingress */
-       uint16 range_ingress;
-       /* Range limit - egress */
-       uint16 range_egress;
-} BWL_POST_PACKED_STRUCT wifi_nan_svc_descriptor_ext_attr_t;
-#define NAN_SDE_ATTR_LEN (sizeof(wifi_nan_svc_descriptor_ext_attr_t))
+       /* range limit, svc upd indicator etc. */
+       uint8 var[];
+} BWL_POST_PACKED_STRUCT wifi_nan_svc_desc_ext_attr_t;
+
+#define NAN_SDE_ATTR_MIN_LEN OFFSETOF(wifi_nan_svc_desc_ext_attr_t, var)
+
 /* SDEA control field bit definitions and access macros */
 #define NAN_SDE_CF_FSD_REQUIRED                (1 << 0)
 #define NAN_SDE_CF_FSD_GAS             (1 << 1)
@@ -1087,6 +1212,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_svc_descriptor_ext_attr_t {
 #define NAN_SDE_CF_SECURITY_REQUIRED   (1 << 6)
 #define NAN_SDE_CF_RANGING_REQUIRED    (1 << 7)
 #define NAN_SDE_CF_RANGE_PRESENT       (1 << 8)
+#define NAN_SDE_CF_SVC_UPD_IND_PRESENT (1 << 9)
 #define NAN_SDE_FSD_REQUIRED(_sde)     ((_sde)->control & NAN_SDE_CF_FSD_REQUIRED)
 #define NAN_SDE_FSD_GAS(_sde)          ((_sde)->control & NAN_SDE_CF_FSD_GAS)
 #define NAN_SDE_DP_REQUIRED(_sde)      ((_sde)->control & NAN_SDE_CF_DP_REQUIRED)
@@ -1096,6 +1222,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_svc_descriptor_ext_attr_t {
 #define NAN_SDE_SECURITY_REQUIRED(_sde)        ((_sde)->control & NAN_SDE_CF_SECURITY_REQUIRED)
 #define NAN_SDE_RANGING_REQUIRED(_sde) ((_sde)->control & NAN_SDE_CF_RANGING_REQUIRED)
 #define NAN_SDE_RANGE_PRESENT(_sde)    ((_sde)->control & NAN_SDE_CF_RANGE_PRESENT)
+#define NAN_SDE_SVC_UPD_IND_PRESENT(_sde)      ((_sde)->control & NAN_SDE_CF_SVC_UPD_IND_PRESENT)
 
 /* nan2 security */
 
@@ -1139,6 +1266,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_sec_cipher_suite_info_attr_s {
 
 /* nan2 security context identifier attribute field */
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_sec_ctx_id_field_s {
+       uint16 sec_ctx_id_type_len;     /* length of security ctx identifier */
        uint8 sec_ctx_id_type;
        uint8 inst_id;  /* Instance Id */
        uint8 var[];    /* security ctx identifier */
@@ -1261,8 +1389,9 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_sec_ncssk_key_desc_attr_s {
                NAN_SEC_NCSSK_DESC_KEY_SMK_MSG_MASK);} while (0)
 
 #define NAN_SEC_NCSSK_IEEE80211_KDESC_TYPE     2       /* IEEE 802.11 Key Descriptor Type */
-#define NAN_SEC_NCSSK_KEY_DESC_VER             0       /* NCSSK-128/256 */
+#define NAN_SEC_NCSSK_KEY_DESC_VER                     0       /* NCSSK-128/256 */
 #define NAN_SEC_NCSSK_KEY_TYPE_PAIRWISE                1       /* Pairwise */
+#define NAN_SEC_NCSSK_LIFETIME_KDE                     7       /* Lifetime KDE type */
 
 /* TODO include MTK related attributes */
 
@@ -1311,26 +1440,11 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_mcast_sched_attr_s {
        uint8 id; /* 0x16 */
        uint16 len;
        uint8 nmsg_id[NAN_NMSG_ID_LEN];
-       uint8 sched_cntrl;
-       uint8 var[0]; /* For Storing Time Bitmap */
+       uint8 attr_cntrl;
+       uint8 sched_own[ETHER_ADDR_LEN];
+       uint8 var[]; /* multicast sched entry list (schedule_entry_list) */
 } BWL_POST_PACKED_STRUCT wifi_nan_mcast_sched_attr_t;
 
-/* ********************************************
-* OBSOLETE/DUPLICATES - DO NOT USE BELOW
-**********************************************
-*/
-/* Time Bitmap Control field: Bit Duration - Incorrect. */
-typedef enum
-{
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_16TU = 0,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_32TU = 1,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_48TU = 2,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_64TU = 3,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_80TU = 4,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_96TU = 5,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_112TU = 6,
-       NAN_TIME_BMP_CTRL_BIT_DUR_DUR_128TU = 7
-} nan_time_bmp_ctrl_bit_dur_t;
 
 /* FAC Channel Entry  (section 10.7.19.1.5) */
 typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_fac_chan_entry_s {
@@ -1340,133 +1454,7 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_fac_chan_entry_s {
        uint16 aux_chan;                        /* Auxiliary Channel bitmap */
 } BWL_POST_PACKED_STRUCT wifi_nan_fac_chan_entry_t;
 
-/* Channel Entry List Present bit in Entry Control Filed is obsolete (WFA NAN Spec 1.0 r21) */
-#define NAN_AVAIL_ENTRY_CTRL_LIST_PRESENT_MASK 0x4000
-#define NAN_AVAIL_ENTRY_CTRL_LIST_PRESENT_SHIFT 14
-#define NAN_AVAIL_ENTRY_CTRL_LIST_PRESENT(_flags) (((_flags) & \
-       NAN_AVAIL_ENTRY_CTRL_LIST_PRESENT_MASK) >> NAN_AVAIL_ENTRY_CTRL_LIST_PRESENT_SHIFT)
-
-/* NDP Information Element (internal) */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndp_setup_s {
-       uint8 id;               /* 221 */
-       uint8 len;              /* Length */
-       uint8 oui[DOT11_OUI_LEN];       /* "\x00\x10\x18" BRCM OUI */
-       uint8 type;             /* NAN_OUI_TYPE 0x13 */
-       uint8 subtype;          /* NAN_DATA_NDP_SETUP */
-       uint8 msg_type;         /* NDP Req, NDP Resp etc. */
-       uint8 pub_inst_id;      /* publish instance id */
-       struct ether_addr peer_mac_addr; /* publisher mac addr (aka peer mgmt address) */
-       struct ether_addr data_if_addr; /* local data i/f address */
-       uint8 msg_status;
-       uint8 ndp_ctrl;
-       uint8 security;
-       wifi_nan_ndp_qos_t qos; /* qos info */
-       uint8 var[1];           /* NDP specific info */
-} BWL_POST_PACKED_STRUCT wifi_nan_ndp_setup_t;
-
-/* NAN mgmt information element */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_mgmt_setup_s {
-       uint8 id;               /* 221 */
-       uint8 len;              /* Length */
-       uint8 oui[DOT11_OUI_LEN];       /* "\x00\x10\x18" BRCM OUI */
-       uint8 type;             /* NAN_OUI_TYPE 0x13 */
-       uint8 subtype;          /* NAN_DATA_MGMT_SETUP */
-       uint8 msg_type;         /* Mgmt Req, Mgmt Resp etc. */
-       uint8 msg_status;
-} BWL_POST_PACKED_STRUCT wifi_nan_mgmt_setup_t;
-
-/* NAN Mgmt Request */
-#define NAN_MGMT_SETUP_MSG_REQ 1       /* don't use 0 */
-/* NAN Mgmt Response */
-#define NAN_MGMT_SETUP_MSG_RESP        2
-
-/* NAN Mgmt Setup Status */
-#define NAN_MGMT_SETUP_STATUS_OK       0
-#define NAN_MGMT_SETUP_STATUS_FAIL     1
-#define NAN_MGMT_SETUP_STATUS_REJECT   2
-
-/* NDL Schedule request */
-#define NAN_MGMT_FRM_SUBTYPE_NDL_UPDATE_REQ    17      /* Not part of spec. ver 1.0.r12 */
-/* NDL Schedule response */
-#define        NAN_MGMT_FRM_SUBTYPE_NDL_UPDATE_RESP    18      /* Not part of spec. ver 1.0.r12 */
-
-/* NAN2 Management */
-/* TODO: Remove this once nan_mgmt module is removed */
-#define NAN_MGMT_FRM_SUBTYPE_MGMT              0
-
-/* NAN 2.0 NDP Setup */
-#define NAN_DATA_NDP_SETUP  0   /* arbitrary value */
-/* NAN 2.0 Mgmt Setup */
-#define NAN_DATA_MGMT_SETUP 1   /* arbitrary value */
-/* NAN 2.0 NDL Setup */
-#define NAN_DATA_NDL_SETUP 2    /* arbitrary value */
-
-/*
- * Period
- * Indicate the repeat interval of the following bitmap.
- * when set to 0, the indicated bitmap is not repeated.
- * When set to non-zero, the repeat interval is:
- * 1:128 TU, 2: 256 TU, 3: 512 TU, 4: 1024 TU, 5: 2048 TU, 6: 4096 TU, 7: 8192 TU
-*/
-#define NAN_DATA_MAX_AVAIL_INTRVL      7       /* no. of period intervals supported */
-
-/* no. of peer devices supported TODO make it tunable */
-#define NAN_DATA_PEER_DEV_SUPPORT      8
-/* no. of instaces supported (ndp, mgmt) */
-#define NAN_DATA_NDP_INST_SUPPORT      16
-/* instaces supported (same as ndp) */
-#define NAN_DATA_MGMT_INST_SUPPORT     NAN_DATA_NDP_INST_SUPPORT
-#define NAN_DATA_NDL_INST_SUPPORT      NAN_DATA_PEER_DEV_SUPPORT
-/* ndc base schedule cannot be more than ndl instances */
-#define NAN_DATA_NDC_INST_SUPPORT      NAN_DATA_PEER_DEV_SUPPORT
-
-/* NAN 2.0 (section 5.7.18.2): NAN availability attribute */
-
-/* NAN Availability Attribute */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_availability_attr_s {
-       uint8 id;                               /* TBD */
-       uint16 len;                             /* length that follows */
-       uint8 attr_cntrl[3];                    /* attribute control */
-       uint8 avail_entry_list[1];              /* availability entry list */
-} BWL_POST_PACKED_STRUCT wifi_nan_availability_attr_t;
-
-/* Channel entry */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_channel_entry_s {
-       uint8 opclass;          /* Operating class */
-       uint16 chan_bitmap;     /* Channel bitmap */
-       uint8 prim_bitmap;      /* Primary channel bitmap */
-       uint16 aux_bitmap;      /* Time bitmap length */
-} BWL_POST_PACKED_STRUCT wifi_nan_channel_entry_t;
-
-/* GAS Sechdule Request */
-#define NAN_MGMT_FRM_SUBTYPE_GAS_SCHED_REQ     14      /* Not part of spec. ver 1.0.r12 */
-/* GAS Sechdule Response */
-#define NAN_MGMT_FRM_SUBTYPE_GAS_SCHED_RESP    15      /* Not part of spec. ver 1.0.r12 */
-
-/* DUPLICATES */
-/* Type of  Availability: committed */
-#define NAN_ENTRY_CNTRL_TYPE_COMM_AVAIL_MASK   0x1
-/* Type of  Availability: potential */
-#define NAN_ENTRY_CNTRL_TYPE_POTEN_AVAIL_MASK  0x2
-/* Type of  Availability: conditional */
-#define NAN_ENTRY_CNTRL_TYPE_COND_AVAIL_MASK   0x4
-
-/* Rx Nss */
-#define NAN_ENTRY_CNTRL_RX_NSS_MASK            0x1E00
-#define NAN_ENTRY_CNTRL_RX_NSS_SHIFT           9
-/* Paged Resource block */
-#define NAN_ENTRY_CNTRL_PAGED_RSC_BLK_MASK     0x2000
-#define NAN_ENTRY_CNTRL_PAGED_RSC_BLK_SHIFT    13
-/* Time Bitmap Present */
-#define NAN_ENTRY_CNTRL_TIME_BMP_PRSNT_MASK    0x4000
-#define NAN_ENTRY_CNTRL_TIME_BMP_PRSNT_SHIFT   14
-/* Channel Entry Present */
-#define NAN_ENTRY_CNTRL_CHAN_ENTRY_PRSNT_MASK  0x8000
-#define NAN_ENTRY_CNTRL_CHAN_ENTRY_PRSNT_SHIFT 15
-/* Reserved */
-#define NAN_ENTRY_CNTRL_RESERVED_MASK          0xFF0000
-#define NAN_ENTRY_CNTRL_RESERVED_SHIFT         16
-
+/* TODO move this from nan.h */
 #define NAN_ALL_NAN_MGMT_FRAMES (NAN_FRM_SCHED_AF | \
        NAN_FRM_NDP_AF | NAN_FRM_NDL_AF | \
        NAN_FRM_DISC_BCN | NAN_FRM_SYNC_BCN | \
@@ -1474,25 +1462,6 @@ typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_channel_entry_s {
        NAN_FRM_RNG_RESP_AF | NAN_FRM_RNG_REPORT_AF | \
        NAN_FRM_RNG_TERM_AF)
 
-/* obsoleted by spec r21 */
-typedef BWL_PRE_PACKED_STRUCT struct wifi_nan_ndl_im_sched_ctrl_s {
-       uint8 sched_ctrl;               /* Schedule control */
-       uint16 bitmap_ctrl;             /* Optional field */
-       uint8 time_bitmap_len;          /* Optional field */
-       uint8 time_bitmap[];            /* Optional field */
-} BWL_POST_PACKED_STRUCT wifi_nan_ndl_im_sched_ctrl_t;
-
-#define NDL_ATTR_IM_SCHED_CTRL_LEN             1
-#define NDL_ATTR_IM_SCHED_CTRL_SCHED_IND_MASK 0x1E
-#define NDL_ATTR_IM_SCHED_CTRL_SCHED_IND_SHIFT 1
-#define NDL_ATTR_IM_SCHED_CTRL_TIME_BMP_PRSNT_MASK     0x20
-#define NDL_ATTR_IM_SCHED_CTRL_TIME_BMP_PRSNT_SHIFT    5
-
-/* Attribute Control field */
-#define NAN_ATTR_CNTRL_MAP_ID_MASK     0x0F    /* Map Id */
-#define NAN_ATTR_CNTRL_RSVD_MASK       0xF0    /* Reserved */
-#define NAN_ATTR_CNTRL_SEQ_ID_MASK     0xFF    /* Seq Id */
-
 /* This marks the end of a packed structure section. */
 #include <packed_section_end.h>
 
index abdcf4518833f3c0deb058005506945685dc4c3c..80c8a012c4dc61262f7b67e585f9a5cfb2d69d5c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * OS Abstraction Layer
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 977a1ca46073e23193001c213f703e05584f5d54..4aaaaab8570c5265b5a2b5a11ec036f1c09aea80 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * osl forward declarations
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 2503f6a37a02fb18ca3d87e51a4173143c37fadb..84b9db18c52b53f9330c6fbbe3ffc683001e4a0f 100644 (file)
@@ -2,7 +2,7 @@
  * OS Abstraction Layer Extension - the APIs defined by the "extension" API
  * are only supported by a subset of all operating systems.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 09e4ef633f7f795d28aba1a7acef65cffeebeec8..7286b8ceeb0126660f6e4b0a80e630431b08d2d6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental types and constants relating to WFA P2P (aka WiFi Direct)
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: p2p.h 676796 2016-12-24 18:16:02Z $
+ * $Id: p2p.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _P2P_H_
index 4827c709af263dc06c9b20e3a879c94733c443bf..74b7d64c5529d86bb357c825b2c322ecf8dfbf51 100644 (file)
@@ -15,7 +15,7 @@
  * #include <packed_section_end.h>
  *
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 9beb45d5e0822cd3b8dd71c635e8bdbcdf30c862..68688bade559793361b2522cb0a8c84c663ad721 100644 (file)
@@ -15,7 +15,7 @@
  * #include <packed_section_end.h>
  *
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 98f22c3df918f5bca27e1ec2e325899eb55286d9..d96aac325c3ffbcecc398667b64986301a93cc8c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * pcicfg.h: PCI configuration constants and structures.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 463561d08440bc593e2c046991eb5471bc9f80dc..aa7724d082e386893a1095816e27803deae92885 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCM43XX PCIE core hardware definitions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ffec624c53dcca8eaa4f6f93b952a86dddf1975f..6fbb5b359c737c28dde7737dbb8a34bc5bb4c5c9 100644 (file)
@@ -7,7 +7,7 @@
  *
  * $Id: sbchipc.h 657872 2016-09-02 22:17:34Z $
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ad9c408cd3448f7a00c97d8f665b5b8578a287bb..80abdf87eade1158fb7472f31015dc566cee81a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom SiliconBackplane hardware register definitions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index f04232daca1a6dbca93b8ffb98c9a5ad64a449bc..07c0d38b66feb3ce953329e630d53514af52f2dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SiliconBackplane GCI core hardware definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 6d10d6ad3940aac1b5842ccbcc8ba1c31cd3b85f..1be6b65433ba70f72441834809d6c3fc7a07c538 100644 (file)
@@ -2,7 +2,7 @@
  * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
  * This supports the following chips: BCM42xx, 44xx, 47xx .
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 0ffc97be1a488dcf3e74e445efaa4ca7bee0a360..ae639784281f78ab68e33d29524a97c8741d544d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ede8b5e2104087f4f39b1c0dddfb494ace31025f..d3c28a6abfb1febf3b7fdff7733625e1cfe4a15c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * SDIO core support 1bit, 4 bit SDIO mode as well as SPI mode.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 8607d63579101eda22da45aa708175e4585329c9..1e9f7890465f67c63ddd5b1a8c9755f48378693f 100644 (file)
@@ -2,7 +2,7 @@
  * Broadcom SiliconBackplane SDIO/PCMCIA hardware-specific
  * device core support
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index b2c018839788572315fdb884babb931669652e89..2aded99286370e82757e0d37d1cc4420b7903a57 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * BCM47XX Sonics SiliconBackplane embedded ram core
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index df26399b2d6111a6f95f914929acded82bf6ba0c..4e721bb49f9e588ca87ff19577cfe56c31213798 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SiliconBackplane System Memory core
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 8f77e4150e76ebe5309753c8755da8d5c1696227..d72e09ed60c91f70a8ea11bec46f4d4f6fe4ae3d 100644 (file)
@@ -2,7 +2,7 @@
  * SDIO spec header file
  * Protocol and standard (common) device definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index f37c5f62aef7056b6e264604849687c43501c5a2..0bf267dd0650a541b3e9a7d05a0b4799f405e4be 100644 (file)
@@ -2,7 +2,7 @@
  * SDIO Host Controller Spec header file
  * Register map and definitions for the Standard Host Controller
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 09be5c6df78945eb033d93cc4a9e98f4dfdcbc3f..b50ea7d9d69fac673c62ac3701199eb3f7308986 100644 (file)
@@ -2,7 +2,7 @@
  * Structure used by apps whose drivers access SDIO drivers.
  * Pulled out separately so dhdu and wlu can both use it.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 2afca25492509c901e5899598202885cb2b6aa8c..71811fd441af8d1193308873b51f0130006a0943 100644 (file)
@@ -2,7 +2,7 @@
  * Misc utility routines for accessing the SOC Interconnects
  * of Broadcom HNBU chips.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index aed3ace9155305d5fbd94f95fa019c3e5c954ca3..941db6271a7c0be5bc8c5c64d9419229799aab85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 062119d1faf2f5bd37fe0b0b654e15debd03cac0..a21be01b07269b7e74c20fd1928e7076efb7027e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 802.1Q VLAN protocol definitions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: vlan.h 518342 2014-12-01 23:21:41Z $
+ * $Id: vlan.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _vlan_h_
index 121af90b664dacd945a21a9210ab1b1d46002077..433fbc6abbbc6216a00a69db70644aaf29ab1dcf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -22,7 +22,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wlfc_proto.h 675983 2016-12-19 23:18:49Z $
+ * $Id: wlfc_proto.h 735359 2017-12-08 10:56:04Z $
  *
  */
 
 #define WLFC_BREADCRUMB(x) do {if ((x) == NULL) \
        {printf("WLFC: %s():%d:caller:%p\n", \
        __FUNCTION__, __LINE__, CALL_SITE);}} while (0)
-#define WLFC_PRINTMAC(banner, ea) do {printf("%s MAC: [%02x:%02x:%02x:%02x:%02x:%02x]\n", \
-       banner, ea[0],  ea[1],  ea[2],  ea[3],  ea[4],  ea[5]); } while (0)
 #define WLFC_WHEREIS(s) printf("WLFC: at %s():%d, %s\n", __FUNCTION__, __LINE__, (s))
 #else
 #define WLFC_DBGMESG(x)
 #define WLFC_BREADCRUMB(x)
-#define WLFC_PRINTMAC(banner, ea)
 #define WLFC_WHEREIS(s)
-#endif
+#endif /* PROP_TXSTATUS_DEBUG */
 
 /* AMPDU host reorder packet flags */
 #define WLHOST_REORDERDATA_MAXFLOWS            256
index 3eeefebc0c381565eb6ffc27d3ffeec075975b26..182079a15050f0691a5d02f052c3c2b7778e8f30 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -27,7 +27,7 @@
  * other than the GPL, without Broadcom's express prior written consent.
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wlioctl.h 677952 2017-01-05 23:25:28Z $
+ * $Id: wlioctl.h 745037 2018-02-06 18:26:04Z $
  */
 
 #ifndef _wlioctl_h_
@@ -2609,7 +2609,9 @@ enum wl_cnt_xtlv_id {
        WL_CNT_XTLV_CNTV_LE10_UCODE = 0x200,    /**< wl counter ver < 11 UCODE MACSTAT */
        WL_CNT_XTLV_LT40_UCODE_V1 = 0x300,      /**< corerev < 40 UCODE MACSTAT */
        WL_CNT_XTLV_GE40_UCODE_V1 = 0x400,      /**< corerev >= 40 UCODE MACSTAT */
-       WL_CNT_XTLV_GE64_UCODEX_V1 = 0x800      /* corerev >= 64 UCODEX MACSTAT */
+       WL_CNT_XTLV_GE64_UCODEX_V1 = 0x800,     /* corerev >= 64 UCODEX MACSTAT */
+       WL_CNT_XTLV_GE80_UCODE_V1 = 0x900,      /* corerev >= 80 UCODEX MACSTAT */
+       WL_CNT_XTLV_GE80_TXFUNFL_UCODE_V1 = 0x1000      /* corerev >= 80 UCODEX MACSTAT */
 };
 
 /**
@@ -2619,6 +2621,8 @@ enum wl_cnt_xtlv_id {
 #define WL_CNT_MCST_VAR_NUM 64
 /* sizeof(wl_cnt_ge40mcst_v1_t), sizeof(wl_cnt_lt40mcst_v1_t), and sizeof(wl_cnt_v_le10_mcst_t) */
 #define WL_CNT_MCST_STRUCT_SZ ((uint32)sizeof(uint32) * WL_CNT_MCST_VAR_NUM)
+#define WL_CNT_REV80_MCST_STRUCT_SZ ((uint32)sizeof(wl_cnt_ge80mcst_v1_t))
+#define WL_CNT_REV80_MCST_TXFUNFlW_STRUCT_SZ ((uint32)sizeof(wl_cnt_ge80_txfunfl_v1_t))
 
 #define WL_CNT_MCXST_STRUCT_SZ ((uint32)sizeof(wl_cnt_ge64mcxst_v1_t))
 #define INVALID_CNT_VAL (uint32)(-1)
@@ -3070,6 +3074,116 @@ typedef struct {
        uint32  bphy_badplcp;   /**< number of bad PLCP reception on BPHY rate */
 } wl_cnt_lt40mcst_v1_t;
 
+/** MACSTAT counters for ucode (corerev >= 80) */
+typedef struct {
+       /* MAC counters: 32-bit version of d11.h's macstat_t */
+       /* Start of PSM2HOST stats(72) block */
+       uint32  txallfrm;       /**< total number of frames sent, incl. Data, ACK, RTS, CTS,
+                                * Control Management (includes retransmissions)
+                                */
+       uint32  txrtsfrm;       /**< number of RTS sent out by the MAC */
+       uint32  txctsfrm;       /**< number of CTS sent out by the MAC */
+       uint32  txackfrm;       /**< number of ACK frames sent out */
+       uint32  txdnlfrm;       /**< number of Null-Data transmission generated from template  */
+       uint32  txbcnfrm;       /**< beacons transmitted */
+       uint32  txampdu;        /**< number of AMPDUs transmitted */
+       uint32  txmpdu;         /**< number of MPDUs transmitted */
+       uint32  txtplunfl;      /**< Template underflows (mac was too slow to transmit ACK/CTS
+                                * or BCN)
+                                */
+       uint32  txphyerror;     /**< Transmit phy error, type of error is reported in tx-status for
+                                * driver enqueued frames
+                                */
+       uint32  pktengrxducast; /**< unicast frames rxed by the pkteng code */
+       uint32  pktengrxdmcast; /**< multicast frames rxed by the pkteng code */
+       uint32  rxfrmtoolong;   /**< Received frame longer than legal limit (2346 bytes) */
+       uint32  rxfrmtooshrt; /**< Received frame did not contain enough bytes for its frame type */
+       uint32  rxanyerr;       /**< Any RX error that is not counted by other counters. */
+       uint32  rxbadfcs;       /**< number of frames for which the CRC check failed in the MAC */
+       uint32  rxbadplcp;      /**< parity check of the PLCP header failed */
+       uint32  rxcrsglitch;    /**< PHY was able to correlate the preamble but not the header */
+       uint32  rxstrt;         /**< Number of received frames with a good PLCP
+                                * (i.e. passing parity check)
+                                */
+       uint32  rxdtucastmbss; /**< number of received DATA frames with good FCS and matching RA */
+       uint32  rxmgucastmbss; /**< number of received mgmt frames with good FCS and matching RA */
+       uint32  rxctlucast; /**< number of received CNTRL frames with good FCS and matching RA */
+       uint32  rxrtsucast;     /**< number of unicast RTS addressed to the MAC (good FCS) */
+       uint32  rxctsucast;     /**< number of unicast CTS addressed to the MAC (good FCS) */
+       uint32  rxackucast;     /**< number of ucast ACKS received (good FCS) */
+       uint32  rxdtocast; /**< number of received DATA frames (good FCS and not matching RA) */
+       uint32  rxmgocast; /**< number of received MGMT frames (good FCS and not matching RA) */
+       uint32  rxctlocast; /**< number of received CNTRL frame (good FCS and not matching RA) */
+       uint32  rxrtsocast;     /**< number of received RTS not addressed to the MAC */
+       uint32  rxctsocast;     /**< number of received CTS not addressed to the MAC */
+       uint32  rxdtmcast;      /**< number of RX Data multicast frames received by the MAC */
+       uint32  rxmgmcast;      /**< number of RX Management multicast frames received by the MAC */
+       uint32  rxctlmcast;     /**< number of RX Control multicast frames received by the MAC
+                                * (unlikely to see these)
+                                */
+       uint32  rxbeaconmbss;   /**< beacons received from member of BSS */
+       uint32  rxdtucastobss; /**< number of unicast frames addressed to the MAC from
+                                 * other BSS (WDS FRAME)
+                                 */
+       uint32  rxbeaconobss;   /**< beacons received from other BSS */
+       uint32  rxrsptmout;     /**< number of response timeouts for transmitted frames
+                                * expecting a response
+                                */
+       uint32  bcntxcancl;     /**< transmit beacons canceled due to receipt of beacon (IBSS) */
+       uint32  rxnodelim;      /**< number of no valid delimiter detected by ampdu parser */
+       uint32  missbcn_dbg;    /**< number of beacon missed to receive */
+       uint32  pmqovfl;        /**< number of PMQ overflows */
+       uint32  rxcgprqfrm;     /**< number of received Probe requests that made it into
+                                * the PRQ fifo
+                                */
+       uint32  rxcgprsqovfl;   /**< Rx Probe Request Que overflow in the AP */
+       uint32  txcgprsfail;    /**< Tx Probe Response Fail. AP sent probe response but did
+                                * not get ACK
+                                */
+       uint32  txcgprssuc;     /**< Tx Probe Response Success (ACK was received) */
+       uint32  prs_timeout;    /**< number of probe requests that were dropped from the PRQ
+                                * fifo because a probe response could not be sent out within
+                                * the time limit defined in M_PRS_MAXTIME
+                                */
+       uint32  txrtsfail;      /**< number of rts transmission failure that reach retry limit */
+       uint32  txucast;        /**< number of unicast tx expecting response other than cts/cwcts */
+       uint32  txinrtstxop;    /**< number of data frame transmissions during rts txop */
+       uint32  rxback;         /**< blockack rxcnt */
+       uint32  txback;         /**< blockack txcnt */
+       uint32  bphy_rxcrsglitch;       /**< PHY count of bphy glitches */
+       uint32  rxdrop20s;      /**< drop secondary cnt */
+       uint32  rxtoolate;      /**< receive too late */
+       uint32  bphy_badplcp;   /**< number of bad PLCP reception on BPHY rate */
+       uint32  rxtrig_myaid;   /* New counters added in 69 */
+       uint32  rxtrig_rand;
+       uint32  goodfcs;
+       uint32  colormiss;
+       uint32  txmampdu;
+       uint32  rxmtidback;
+       uint32  rxmstaback;
+       uint32  txfrag;
+       /* End of PSM2HOST stats block */
+       /* start of rxerror overflow counter(24) block which are modified/added in corerev 80 */
+       uint32  phyovfl;
+       uint32  rxf0ovfl;       /**< number of receive fifo 0 overflows */
+       uint32  rxf1ovfl;       /**< number of receive fifo 1 overflows */
+       uint32  lenfovfl;
+       uint32  weppeof;
+       uint32  badplcp;
+       uint32  msduthresh;
+       uint32  strmeof;
+       uint32  stsfifofull;
+       uint32  stsfifoerr;
+       uint32  PAD[6];
+       uint32  rxerr_stat;
+       uint32  ctx_fifo_full;
+       uint32  PAD[38]; /* PAD added for counter elements to be added soon */
+} wl_cnt_ge80mcst_v1_t;
+
+typedef struct {
+       uint32 txfunfl[NFIFO_EXT];
+} wl_cnt_ge80_txfunfl_v1_t;
+
 /** MACSTAT counters for "wl counter" version <= 10 */
 typedef struct {
        /* MAC counters: 32-bit version of d11.h's macstat_t */
@@ -11514,6 +11628,7 @@ typedef struct wnm_roam_trigger_cfg {
 
 /* Data structures for Interface Create/Remove  */
 
+#define WL_INTERFACE_CREATE_VER_0      0
 #define WL_INTERFACE_CREATE_VER_1      1
 #define WL_INTERFACE_CREATE_VER_2      2
 #define WL_INTERFACE_CREATE_VER_3      3
@@ -11579,6 +11694,12 @@ typedef enum wl_interface_type {
  */
 #define WL_INTERFACE_BSSID_INDEX_USE   (1 << 4)
 
+typedef struct wl_interface_create_v0 {
+       uint16  ver;                    /**< version of this struct */
+       uint32  flags;                  /**< flags that defines the operation */
+       struct  ether_addr   mac_addr;  /**< Optional Mac address */
+} wl_interface_create_v0_t;
+
 typedef struct wl_interface_create {
        uint16  ver;                    /**< version of this struct */
        uint8   pad1[2];                /**< Padding bytes */
@@ -11612,9 +11733,17 @@ typedef struct wl_interface_create_v3 {
        uint8   data[];                 /**< Optional application/Module specific data */
 } wl_interface_create_v3_t;
 
+#define WL_INTERFACE_INFO_VER_0                0
 #define WL_INTERFACE_INFO_VER_1                1
 #define WL_INTERFACE_INFO_VER_2                2
 
+typedef struct wl_interface_info_v0 {
+       uint16  ver;                    /**< version of this struct */
+       struct ether_addr    mac_addr;  /**< MAC address of the interface */
+       char    ifname[BCM_MSG_IFNAME_MAX]; /**< name of interface */
+       uint8   bsscfgidx;              /**< source bsscfg index */
+} wl_interface_info_v0_t;
+
 typedef struct wl_interface_info_v1 {
        uint16  ver;                    /**< version of this struct */
        struct ether_addr    mac_addr;  /**< MAC address of the interface */
@@ -13840,4 +13969,15 @@ typedef struct csa_event_data {
        uint8 PAD;
 } csa_event_data_t;
 
+/* Block Channel */
+#define WL_BLOCK_CHANNEL_VER_1 1u
+
+typedef struct wl_block_ch_v1 {
+       uint16 version;
+       uint16 len;
+       uint32 band;            /* Band select */
+       uint8 channel_num;      /* The number of block channels in the selected band */
+       uint8 padding[3];
+       uint8 channel[];        /* Channel to block, Variable Length */
+} wl_block_ch_v1_t;
 #endif /* _wlioctl_h_ */
index c7d9e0d5276735b21adeb21287d2f8a3f9affa98..0ffcd172a0cce7a729b70dd59e00e419e537d917 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Definitions subject to change without notice.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 797531cface763adb6411b925d2159422c037303..3d04e9b5edae0a478ba3590aa4f6eae803560dee 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Custom OID/ioctl related helper functions.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index b682568d2c3125aa60a661e91e923cab30ea1355..6b5a6e0e21fb964f03b1bdac7c1017cc955a413e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Fundamental types and constants relating to WPA
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wpa.h 677908 2017-01-05 18:59:06Z $
+ * $Id: wpa.h 700076 2017-05-17 14:42:22Z $
  */
 
 #ifndef _proto_wpa_h_
index 523a8b76dd1df07b3c027d19404f7cd68a578dfb..dd5a148b0acdc665d661a307c80c25449f4abc18 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux OS Independent Layer
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 63f955cb66937f3754fafbc2843aa09b2b737651..573c287067d4cf9b2641c2554e5963d4618850ee 100644 (file)
@@ -3,7 +3,7 @@
  * Contains PCIe related functions that are shared between different driver models (e.g. firmware
  * builds, DHD builds, BMAC builds), in order to avoid code duplication.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 975ee6afaf08f45ad61d2799c41148818f9b4626..01af942ee7b865c6a8b721f294d00a96fee7e742 100644 (file)
@@ -2,7 +2,7 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index f47cd07f652a70c4e703cc40013b8c48da6aeed1..7b13b25761270c3e5a953a0bd50ffe7443570e84 100644 (file)
@@ -2,7 +2,7 @@
  * Misc utility routines for accessing chip-specific features
  * of the SiliconBackplane-based Broadcom chips.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index ad57e215ce041bcc6a9f14c14ae8f48fa983acf9..87b50ee6f35795df02c860be02924dae9d22aa06 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Include file private to the SOC Interconnect support files.
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index c3f1a29dfa9877aec4423cbee96b3058680852e9..6c86860b8a51ce19ce2f18de8e94295f7a422abb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver - Android related functions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_android.c 684350 2017-02-13 05:30:25Z $
+ * $Id: wl_android.c 752839 2018-03-19 07:05:21Z $
  */
 
 #include <linux/module.h>
 #include <dhd_ip.h>
 #endif /* DHDTCPACK_SUPPRESS */
 #include <dhd_linux.h>
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+
+#if defined(STAT_REPORT)
+#include <wl_statreport.h>
+#endif /* STAT_REPORT */
 
 /*
  * Android private command strings, PLEASE define new private commands here
 #define CMD_OKC_SET_PMK         "SET_PMK"
 #define CMD_OKC_ENABLE          "OKC_ENABLE"
 
-#define ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS 100
-
 typedef struct android_wifi_reassoc_params {
        unsigned char bssid[18];
        int channel;
@@ -267,6 +272,11 @@ typedef struct android_wifi_af_params {
 #define CUSTOMER_HW4_EN_CONVERT(i)     (i += 1)
 #endif /* FCC_PWR_LIMIT_2G */
 
+#ifdef APSTA_RESTRICTED_CHANNEL
+#define CMD_SET_INDOOR_CHANNELS        "SET_INDOOR_CHANNELS"
+#define CMD_GET_INDOOR_CHANNELS        "GET_INDOOR_CHANNELS"
+#endif /* APSTA_RESTRICTED_CHANNEL */
+
 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
 
 #ifdef WLFBT
@@ -326,7 +336,11 @@ typedef struct android_wifi_af_params {
 #define CMD_TBOW_TEARDOWN "TBOW_TEARDOWN"
 #endif /* BT_WIFI_HANDOVER */
 
-#define CMD_MURX_BFE_CAP "MURX_BFE_CAP"
+#ifdef DYNAMIC_MUMIMO_CONTROL
+#define CMD_GET_MURX_BFE_CAP           "GET_MURX_BFE_CAP"
+#define CMD_SET_MURX_BFE_CAP           "SET_MURX_BFE_CAP"
+#define CMD_GET_BSS_SUPPORT_MUMIMO     "GET_BSS_SUPPORT_MUMIMO"
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 
 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
 #define CMD_SET_AP_BEACONRATE                          "SET_AP_BEACONRATE"
@@ -339,25 +353,23 @@ typedef struct android_wifi_af_params {
 #define CMD_SET_AP_RPS_PARAMS                          "SET_AP_RPS_PARAMS"
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
 
+#ifdef SUPPORT_RSSI_SUM_REPORT
+#define CMD_SET_RSSI_LOGGING                           "SET_RSSI_LOGGING"
+#define CMD_GET_RSSI_LOGGING                           "GET_RSSI_LOGGING"
+#define CMD_GET_RSSI_PER_ANT                           "GET_RSSI_PER_ANT"
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+
 #define CMD_GET_SNR                                                    "GET_SNR"
 
+#ifdef SUPPORT_SET_CAC
+#define CMD_ENABLE_CAC         "ENABLE_CAC"
+#endif /* SUPPORT_SET_CAC */
+
 /* miracast related definition */
 #define MIRACAST_MODE_OFF      0
 #define MIRACAST_MODE_SOURCE   1
 #define MIRACAST_MODE_SINK     2
 
-#ifndef MIRACAST_AMPDU_SIZE
-#define MIRACAST_AMPDU_SIZE    8
-#endif
-
-#ifndef MIRACAST_MCHAN_ALGO
-#define MIRACAST_MCHAN_ALGO     1
-#endif
-
-#ifndef MIRACAST_MCHAN_BW
-#define MIRACAST_MCHAN_BW       25
-#endif
-
 #ifdef CONNECTION_STATISTICS
 #define CMD_GET_CONNECTION_STATS       "GET_CONNECTION_STATS"
 
@@ -487,6 +499,31 @@ static const wl_natoe_sub_cmd_t natoe_cmd_list[] = {
 #define CMD_PCIE_IRQ_CORE      "PCIE_IRQ_CORE"
 #endif /* SET_PCIE_IRQ_CPU_CORE */
 
+#ifdef WLADPS_PRIVATE_CMD
+#define CMD_SET_ADPS   "SET_ADPS"
+#define CMD_GET_ADPS   "GET_ADPS"
+#endif /* WLADPS_PRIVATE_CMD */
+
+#ifdef DHD_PKT_LOGGING
+#define CMD_PKTLOG_FILTER_ENABLE       "PKTLOG_FILTER_ENABLE"
+#define CMD_PKTLOG_FILTER_DISABLE      "PKTLOG_FILTER_DISABLE"
+#define CMD_PKTLOG_FILTER_PATTERN_ENABLE       "PKTLOG_FILTER_PATTERN_ENABLE"
+#define CMD_PKTLOG_FILTER_PATTERN_DISABLE      "PKTLOG_FILTER_PATTERN_DISABLE"
+#define CMD_PKTLOG_FILTER_ADD  "PKTLOG_FILTER_ADD"
+#define CMD_PKTLOG_FILTER_INFO "PKTLOG_FILTER_INFO"
+#define CMD_PKTLOG_START       "PKTLOG_START"
+#define CMD_PKTLOG_STOP                "PKTLOG_STOP"
+#define CMD_PKTLOG_FILTER_EXIST "PKTLOG_FILTER_EXIST"
+#define CMD_PKTLOG_MINMIZE_ENABLE      "PKTLOG_MINMIZE_ENABLE"
+#define CMD_PKTLOG_MINMIZE_DISABLE     "PKTLOG_MINMIZE_DISABLE"
+#define CMD_PKTLOG_CHANGE_SIZE "PKTLOG_CHANGE_SIZE"
+#endif /* DHD_PKT_LOGGING */
+
+#if defined(STAT_REPORT)
+#define CMD_STAT_REPORT_GET_START      "STAT_REPORT_GET_START"
+#define CMD_STAT_REPORT_GET_NEXT       "STAT_REPORT_GET_NEXT"
+#endif /* STAT_REPORT */
+
 #ifdef WL_GENL
 static s32 wl_genl_handle_msg(struct sk_buff *skb, struct genl_info *info);
 static int wl_genl_init(void);
@@ -599,6 +636,11 @@ extern int set_roamscan_channel_list(struct net_device *dev, unsigned char n,
 extern void wl_update_roamscan_cache_by_band(struct net_device *dev, int band);
 #endif /* ROAM_CHANNEL_CACHE */
 
+#ifdef APSTA_RESTRICTED_CHANNEL
+extern s32 wl_cfg80211_set_indoor_channels(struct net_device *ndev, char *command, int total_len);
+extern s32 wl_cfg80211_get_indoor_channels(struct net_device *ndev, char *command, int total_len);
+#endif /* APSTA_RESTRICTED_CHANNEL */
+
 #ifdef ENABLE_4335BT_WAR
 extern int bcm_bt_lock(int cookie);
 extern void bcm_bt_unlock(int cookie);
@@ -607,6 +649,9 @@ static int lock_cookie_wifi = 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24;     /* cookie is "Wi
 
 extern bool ap_fw_loaded;
 extern char iface_name[IFNAMSIZ];
+#ifdef DHD_PM_CONTROL_FROM_FILE
+extern bool g_pm_control;
+#endif /* DHD_PM_CONTROL_FROM_FILE */
 
 /**
  * Local (static) functions and variables
@@ -919,7 +964,7 @@ int wl_android_get_assoclist(struct net_device *dev, char *command, int total_le
 
        assoc_maclist->count = htod32(MAX_NUM_OF_ASSOCLIST);
 
-       error = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf), false);
+       error = wldev_ioctl_get(dev, WLC_GET_ASSOCLIST, assoc_maclist, sizeof(mac_buf));
        if (error)
                return -1;
 
@@ -1068,8 +1113,8 @@ static int wl_android_set_roam_trigger(
        }
 
        roam_trigger[1] = WLC_BAND_ALL;
-       error = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
-               sizeof(roam_trigger), 1);
+       error = wldev_ioctl_set(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
+               sizeof(roam_trigger));
        if (error != BCME_OK) {
                WL_ERR(("failed to set roam trigger (%d)\n", error));
                return BCME_ERROR;
@@ -1126,8 +1171,8 @@ static int wl_android_get_roam_trigger(
                }
        } else {
                roam_trigger[1] = band;
-               error = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
-                       sizeof(roam_trigger), 0);
+               error = wldev_ioctl_get(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
+                       sizeof(roam_trigger));
                if (error != BCME_OK) {
                        WL_ERR(("failed to get roam trigger (%d)\n", error));
                        return BCME_ERROR;
@@ -1148,8 +1193,8 @@ int wl_android_set_roam_delta(
        sscanf(command, "%*s %10d", &roam_delta[0]);
        roam_delta[1] = WLC_BAND_ALL;
 
-       return wldev_ioctl(dev, WLC_SET_ROAM_DELTA, roam_delta,
-               sizeof(roam_delta), 1);
+       return wldev_ioctl_set(dev, WLC_SET_ROAM_DELTA, roam_delta,
+               sizeof(roam_delta));
 }
 
 static int wl_android_get_roam_delta(
@@ -1159,11 +1204,11 @@ static int wl_android_get_roam_delta(
        int roam_delta[2] = {0, 0};
 
        roam_delta[1] = WLC_BAND_2G;
-       if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta,
-               sizeof(roam_delta), 0)) {
+       if (wldev_ioctl_get(dev, WLC_GET_ROAM_DELTA, roam_delta,
+               sizeof(roam_delta))) {
                roam_delta[1] = WLC_BAND_5G;
-               if (wldev_ioctl(dev, WLC_GET_ROAM_DELTA, roam_delta,
-                       sizeof(roam_delta), 0))
+               if (wldev_ioctl_get(dev, WLC_GET_ROAM_DELTA, roam_delta,
+                                   sizeof(roam_delta)))
                        return -1;
        }
 
@@ -1179,8 +1224,8 @@ int wl_android_set_roam_scan_period(
        int roam_scan_period = 0;
 
        sscanf(command, "%*s %10d", &roam_scan_period);
-       return wldev_ioctl(dev, WLC_SET_ROAM_SCAN_PERIOD, &roam_scan_period,
-               sizeof(roam_scan_period), 1);
+       return wldev_ioctl_set(dev, WLC_SET_ROAM_SCAN_PERIOD, &roam_scan_period,
+               sizeof(roam_scan_period));
 }
 
 static int wl_android_get_roam_scan_period(
@@ -1189,8 +1234,8 @@ static int wl_android_get_roam_scan_period(
        int bytes_written;
        int roam_scan_period = 0;
 
-       if (wldev_ioctl(dev, WLC_GET_ROAM_SCAN_PERIOD, &roam_scan_period,
-               sizeof(roam_scan_period), 0))
+       if (wldev_ioctl_get(dev, WLC_GET_ROAM_SCAN_PERIOD, &roam_scan_period,
+               sizeof(roam_scan_period)))
                return -1;
 
        bytes_written = snprintf(command, total_len, "%s %d",
@@ -1342,9 +1387,9 @@ int wl_android_set_roam_scan_control(struct net_device *dev, char *command, int
 int wl_android_get_roam_scan_channels(struct net_device *dev, char *command, int total_len)
 {
        int bytes_written = 0;
-       unsigned char channels[ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS] = {0};
+       unsigned char channels[MAX_ROAM_CHANNEL] = {0};
        int channel_cnt = 0;
-       char channel_info[10 + (ANDROID_WIFI_MAX_ROAM_SCAN_CHANNELS * 3)] = {0};
+       char channel_info[10 + (MAX_ROAM_CHANNEL * 3)] = {0};
        int channel_info_len = 0;
        int i = 0;
 
@@ -1388,7 +1433,7 @@ int wl_android_get_scan_channel_time(struct net_device *dev, char *command, int
        int bytes_written = 0;
        int time = 0;
 
-       error = wldev_ioctl(dev, WLC_GET_SCAN_CHANNEL_TIME, &time, sizeof(time), 0);
+       error = wldev_ioctl_get(dev, WLC_GET_SCAN_CHANNEL_TIME, &time, sizeof(time));
        if (error) {
                DHD_ERROR(("%s: Failed to get Scan Channel Time, error = %d\n",
                __FUNCTION__, error));
@@ -1411,7 +1456,7 @@ int wl_android_set_scan_channel_time(struct net_device *dev, char *command, int
        }
 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
        wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_CHANNEL_TIME, time);
-       error = wldev_ioctl(dev, WLC_SET_SCAN_CHANNEL_TIME, &time, sizeof(time), 1);
+       error = wldev_ioctl_set(dev, WLC_SET_SCAN_CHANNEL_TIME, &time, sizeof(time));
 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
        if (error) {
                DHD_ERROR(("%s: Failed to set Scan Channel Time %d, error = %d\n",
@@ -1428,7 +1473,7 @@ int wl_android_get_scan_unassoc_time(struct net_device *dev, char *command, int
        int bytes_written = 0;
        int time = 0;
 
-       error = wldev_ioctl(dev, WLC_GET_SCAN_UNASSOC_TIME, &time, sizeof(time), 0);
+       error = wldev_ioctl_get(dev, WLC_GET_SCAN_UNASSOC_TIME, &time, sizeof(time));
        if (error) {
                DHD_ERROR(("%s: Failed to get Scan Unassoc Time, error = %d\n",
                        __FUNCTION__, error));
@@ -1451,7 +1496,7 @@ int wl_android_set_scan_unassoc_time(struct net_device *dev, char *command, int
        }
 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
        wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_UNASSOC_TIME, time);
-       error = wldev_ioctl(dev, WLC_SET_SCAN_UNASSOC_TIME, &time, sizeof(time), 1);
+       error = wldev_ioctl_set(dev, WLC_SET_SCAN_UNASSOC_TIME, &time, sizeof(time));
 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
        if (error) {
                DHD_ERROR(("%s: Failed to set Scan Unassoc Time %d, error = %d\n",
@@ -1468,7 +1513,7 @@ int wl_android_get_scan_passive_time(struct net_device *dev, char *command, int
        int bytes_written = 0;
        int time = 0;
 
-       error = wldev_ioctl(dev, WLC_GET_SCAN_PASSIVE_TIME, &time, sizeof(time), 0);
+       error = wldev_ioctl_get(dev, WLC_GET_SCAN_PASSIVE_TIME, &time, sizeof(time));
        if (error) {
                DHD_ERROR(("%s: Failed to get Scan Passive Time, error = %d\n",
                        __FUNCTION__, error));
@@ -1491,7 +1536,7 @@ int wl_android_set_scan_passive_time(struct net_device *dev, char *command, int
        }
 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
        wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_PASSIVE_TIME, time);
-       error = wldev_ioctl(dev, WLC_SET_SCAN_PASSIVE_TIME, &time, sizeof(time), 1);
+       error = wldev_ioctl_set(dev, WLC_SET_SCAN_PASSIVE_TIME, &time, sizeof(time));
 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
        if (error) {
                DHD_ERROR(("%s: Failed to set Scan Passive Time %d, error = %d\n",
@@ -1508,7 +1553,7 @@ int wl_android_get_scan_home_time(struct net_device *dev, char *command, int tot
        int bytes_written = 0;
        int time = 0;
 
-       error = wldev_ioctl(dev, WLC_GET_SCAN_HOME_TIME, &time, sizeof(time), 0);
+       error = wldev_ioctl_get(dev, WLC_GET_SCAN_HOME_TIME, &time, sizeof(time));
        if (error) {
                DHD_ERROR(("Failed to get Scan Home Time, error = %d\n", error));
                return -1;
@@ -1530,7 +1575,7 @@ int wl_android_set_scan_home_time(struct net_device *dev, char *command, int tot
        }
 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
        wl_cfg80211_custom_scan_time(dev, WL_CUSTOM_SCAN_HOME_TIME, time);
-       error = wldev_ioctl(dev, WLC_SET_SCAN_HOME_TIME, &time, sizeof(time), 1);
+       error = wldev_ioctl_set(dev, WLC_SET_SCAN_HOME_TIME, &time, sizeof(time));
 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
        if (error) {
                DHD_ERROR(("%s: Failed to set Scan Home Time %d, error = %d\n",
@@ -1587,7 +1632,7 @@ int wl_android_get_scan_nprobes(struct net_device *dev, char *command, int total
        int bytes_written = 0;
        int num = 0;
 
-       error = wldev_ioctl(dev, WLC_GET_SCAN_NPROBES, &num, sizeof(num), 0);
+       error = wldev_ioctl_get(dev, WLC_GET_SCAN_NPROBES, &num, sizeof(num));
        if (error) {
                DHD_ERROR(("%s: Failed to get Scan NProbes, error = %d\n", __FUNCTION__, error));
                return -1;
@@ -1608,7 +1653,7 @@ int wl_android_set_scan_nprobes(struct net_device *dev, char *command, int total
                return -1;
        }
 
-       error = wldev_ioctl(dev, WLC_SET_SCAN_NPROBES, &num, sizeof(num), 1);
+       error = wldev_ioctl_set(dev, WLC_SET_SCAN_NPROBES, &num, sizeof(num));
        if (error) {
                DHD_ERROR(("%s: Failed to set Scan NProbes %d, error = %d\n",
                __FUNCTION__, num, error));
@@ -1744,7 +1789,7 @@ int wl_android_send_action_frame(struct net_device *dev, char *command, int tota
 
        params = (android_wifi_af_params_t *)(command + strlen(CMD_SENDACTIONFRAME) + 1);
 
-       if (params->len > ANDROID_WIFI_ACTION_FRAME_SIZE) {
+       if ((uint16)params->len > ANDROID_WIFI_ACTION_FRAME_SIZE) {
                DHD_ERROR(("%s: Requested action frame len was out of range(%d)\n",
                        __FUNCTION__, params->len));
                goto send_action_frame_out;
@@ -1768,7 +1813,7 @@ int wl_android_send_action_frame(struct net_device *dev, char *command, int tota
        if (bcm_ether_atoe((const char *)params->bssid, (struct ether_addr *)&tmp_bssid) == 0) {
                memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
 
-               error = wldev_ioctl(dev, WLC_GET_BSSID, &tmp_bssid, ETHER_ADDR_LEN, false);
+               error = wldev_ioctl_get(dev, WLC_GET_BSSID, &tmp_bssid, ETHER_ADDR_LEN);
                if (error) {
                        memset(&tmp_bssid, 0, ETHER_ADDR_LEN);
                        DHD_ERROR(("%s: failed to get bssid, error=%d\n", __FUNCTION__, error));
@@ -1778,7 +1823,8 @@ int wl_android_send_action_frame(struct net_device *dev, char *command, int tota
 
        if (params->channel < 0) {
                struct channel_info ci;
-               error = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci), false);
+               memset(&ci, 0, sizeof(ci));
+               error = wldev_ioctl_get(dev, WLC_GET_CHANNEL, &ci, sizeof(ci));
                if (error) {
                        DHD_ERROR(("%s: failed to get channel, error=%d\n", __FUNCTION__, error));
                        goto send_action_frame_out;
@@ -1797,7 +1843,7 @@ int wl_android_send_action_frame(struct net_device *dev, char *command, int tota
 
        action_frame->packetId = 0;
        memcpy(&action_frame->da, &tmp_bssid, ETHER_ADDR_LEN);
-       action_frame->len = params->len;
+       action_frame->len = (uint16)params->len;
        memcpy(action_frame->data, params->data, action_frame->len);
 
        error = wldev_iovar_setbuf(dev, "actframe", af_params,
@@ -1864,7 +1910,7 @@ int wl_android_reassoc(struct net_device *dev, char *command, int total_len)
 #endif /* D11AC_IOTYPES */
        params_size = WL_REASSOC_PARAMS_FIXED_SIZE + sizeof(chanspec_t);
 
-       error = wldev_ioctl(dev, WLC_REASSOC, &reassoc_params, params_size, true);
+       error = wldev_ioctl_set(dev, WLC_REASSOC, &reassoc_params, params_size);
        if (error) {
                DHD_ERROR(("%s: failed to reassoc, error=%d\n", __FUNCTION__, error));
        }
@@ -2087,6 +2133,12 @@ wl_cfg80211_get_sta_info(struct net_device *dev, char* command, int total_len)
        str = bcmstrtok(&pcmd, " ", NULL);
        if (str) {
                str = bcmstrtok(&pcmd, " ", NULL);
+               /* If GETSTAINFO subcmd name is not provided, return error */
+               if (str == NULL) {
+                       WL_ERR(("GETSTAINFO subcmd not provided %s\n", __FUNCTION__));
+                       goto error;
+               }
+
                memset(&mac, 0, ETHER_ADDR_LEN);
                if ((bcm_ether_atoe((str), &mac))) {
                        /* get the sta info */
@@ -2184,8 +2236,8 @@ static int wl_android_wbtext(struct net_device *dev, char *command, int total_le
                        /* reset legacy roam trigger when wbtext is off */
                        roam_trigger[0] = DEFAULT_ROAM_TRIGGER_VALUE;
                        roam_trigger[1] = WLC_BAND_ALL;
-                       if ((error = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
-                               sizeof(roam_trigger), 1)) != BCME_OK) {
+                       if ((error = wldev_ioctl_set(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
+                                       sizeof(roam_trigger))) != BCME_OK) {
                                DHD_ERROR(("%s: Failed to reset roam trigger = %d\n",
                                        __FUNCTION__, error));
                                return error;
@@ -2423,7 +2475,7 @@ static int wl_android_set_pno_setup(struct net_device *dev, char *command, int t
                str_ptr += sizeof(cmd_tlv_t);
                tlv_size_left -= sizeof(cmd_tlv_t);
 
-               if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
+               if ((nssid = wl_parse_ssid_list_tlv(&str_ptr, ssids_local,
                        MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
                        DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid));
                        goto exit_proc;
@@ -2593,21 +2645,21 @@ wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *
        struct maclist *assoc_maclist = (struct maclist *)mac_buf;
 
        /* set filtering mode */
-       if ((ret = wldev_ioctl(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode), true)) != 0) {
+       if ((ret = wldev_ioctl_set(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode)) != 0)) {
                DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__, ret));
                return ret;
        }
        if (macmode != MACLIST_MODE_DISABLED) {
                /* set the MAC filter list */
-               if ((ret = wldev_ioctl(dev, WLC_SET_MACLIST, maclist,
-                       sizeof(int) + sizeof(struct ether_addr) * maclist->count, true)) != 0) {
+               if ((ret = wldev_ioctl_set(dev, WLC_SET_MACLIST, maclist,
+                       sizeof(int) + sizeof(struct ether_addr) * maclist->count)) != 0) {
                        DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__, ret));
                        return ret;
                }
                /* get the current list of associated STAs */
                assoc_maclist->count = MAX_NUM_OF_ASSOCLIST;
-               if ((ret = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist,
-                       sizeof(mac_buf), false)) != 0) {
+               if ((ret = wldev_ioctl_get(dev, WLC_GET_ASSOCLIST, assoc_maclist,
+                       sizeof(mac_buf))) != 0) {
                        DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__, ret));
                        return ret;
                }
@@ -2636,9 +2688,9 @@ wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *
                                        scbval.val = htod32(1);
                                        memcpy(&scbval.ea, &assoc_maclist->ea[i],
                                                ETHER_ADDR_LEN);
-                                       if ((ret = wldev_ioctl(dev,
+                                       if ((ret = wldev_ioctl_set(dev,
                                                WLC_SCB_DEAUTHENTICATE_FOR_REASON,
-                                               &scbval, sizeof(scb_val_t), true)) != 0)
+                                               &scbval, sizeof(scb_val_t))) != 0)
                                                DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n",
                                                        __FUNCTION__, ret));
                                }
@@ -2830,7 +2882,6 @@ wl_chanim_stats(struct net_device *dev, u8 *chan_idle)
        chanim_stats_t *stats;
 
        memset(&param, 0, sizeof(param));
-       memset(result, 0, sizeof(result));
 
        param.buflen = htod32(sizeof(wl_chanim_stats_t));
        param.count = htod32(WL_CHANIM_COUNT_ONE);
@@ -3666,6 +3717,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
        u8 *reqbuf = NULL;
        uint32 band = WLC_BAND_2G;
        uint32 buf_size;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
 
        if (cmd_str) {
                WL_INFORM(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str)));
@@ -3696,23 +3748,26 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
        }
        WL_INFORM(("HAPD_AUTO_CHANNEL = %d, band=%d \n", channel, band));
 
-       if ((ret = wldev_ioctl(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect), false)) < 0) {
-               WL_ERR(("ACS: error getting the spect\n"));
+       /* If STA is connected, return is STA channel, else ACS can be issued,
+        * set spect to 0 and proceed with ACS
+        */
+       channel = wl_cfg80211_get_sta_channel(cfg);
+       if (channel) {
+               channel = (channel <= CH_MAX_2G_CHANNEL) ?
+                       channel : APCS_DEFAULT_2G_CH;
+               goto done2;
+       }
+
+       ret = wldev_ioctl_get(dev, WLC_GET_SPECT_MANAGMENT, &spect, sizeof(spect));
+       if (ret) {
+               WL_ERR(("ACS: error getting the spect, ret=%d\n", ret));
                goto done;
        }
 
        if (spect > 0) {
-               /* If STA is connected, return is STA channel, else ACS can be issued,
-                * set spect to 0 and proceed with ACS
-                */
-               channel = wl_cfg80211_get_sta_channel(dev);
-               if (channel) {
-                       channel = (channel <= CH_MAX_2G_CHANNEL) ? channel : APCS_DEFAULT_2G_CH;
-                       goto done2;
-               }
-
-               if ((ret = wl_cfg80211_set_spect(dev, 0) < 0)) {
-                       WL_ERR(("ACS: error while setting spect\n"));
+               ret = wl_cfg80211_set_spect(dev, 0);
+               if (ret < 0) {
+                       WL_ERR(("ACS: error while setting spect, ret=%d\n", ret));
                        goto done;
                }
        }
@@ -3748,8 +3803,8 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
        }
 
        buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE;
-       ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf,
-               buf_size, true);
+       ret = wldev_ioctl_set(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf,
+               buf_size);
        if (ret < 0) {
                WL_ERR(("can't start auto channel scan, err = %d\n", ret));
                channel = 0;
@@ -3769,8 +3824,8 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str,
 
        retry = APCS_MAX_RETRY;
        while (retry--) {
-               ret = wldev_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen,
-                       sizeof(chosen), false);
+               ret = wldev_ioctl_get(dev, WLC_GET_CHANNEL_SEL, &chosen,
+                       sizeof(chosen));
                if (ret < 0) {
                        chosen = 0;
                } else {
@@ -3840,8 +3895,9 @@ wl_android_set_max_num_sta(struct net_device *dev, const char* string_num)
        int max_assoc;
 
        max_assoc = bcm_atoi(string_num);
-       DHD_INFO(("%s : HAPD_MAX_NUM_STA = %d\n", __FUNCTION__, max_assoc));
+       WL_INFORM(("HAPD_MAX_NUM_STA = %d\n", max_assoc));
        wldev_iovar_setint(dev, "maxassoc", max_assoc);
+       WL_INFORM(("Conigured maxassoc = %d\n", max_assoc));
        return 1;
 }
 
@@ -3858,7 +3914,7 @@ wl_android_set_ssid(struct net_device *dev, const char* hapd_ssid)
        }
        bcm_strncpy_s(ssid.SSID, sizeof(ssid.SSID), hapd_ssid, ssid.SSID_len);
        DHD_INFO(("%s: HAPD_SSID = %s\n", __FUNCTION__, ssid.SSID));
-       ret = wldev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t), true);
+       ret = wldev_ioctl_set(dev, WLC_SET_SSID, &ssid, sizeof(wlc_ssid_t));
        if (ret < 0) {
                DHD_ERROR(("%s : WLC_SET_SSID Error:%d\n", __FUNCTION__, ret));
        }
@@ -3901,8 +3957,8 @@ wl_android_sta_diassoc(struct net_device *dev, const char* straddr)
        DHD_ERROR(("%s: deauth STA: "MACDBG " scb_val.val %d\n", __FUNCTION__,
                MAC2STRDBG(scbval.ea.octet), scbval.val));
 
-       error = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
-               sizeof(scb_val_t), true);
+       error = wldev_ioctl_set(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval,
+               sizeof(scb_val_t));
        if (error) {
                DHD_ERROR(("Fail to DEAUTH station, error = %d\n", error));
        }
@@ -3921,13 +3977,13 @@ wl_android_set_lpc(struct net_device *dev, const char* string_num)
        lpc_enabled = bcm_atoi(string_num);
        DHD_INFO(("%s : HAPD_LPC_ENABLED = %d\n", __FUNCTION__, lpc_enabled));
 
-       ret = wldev_ioctl(dev, WLC_DOWN, &val, sizeof(s32), true);
+       ret = wldev_ioctl_set(dev, WLC_DOWN, &val, sizeof(s32));
        if (ret < 0)
                DHD_ERROR(("WLC_DOWN error %d\n", ret));
 
        wldev_iovar_setint(dev, "lpc", lpc_enabled);
 
-       ret = wldev_ioctl(dev, WLC_UP, &val, sizeof(s32), true);
+       ret = wldev_ioctl_set(dev, WLC_UP, &val, sizeof(s32));
        if (ret < 0)
                DHD_ERROR(("WLC_UP error %d\n", ret));
 
@@ -3946,11 +4002,11 @@ wl_android_ch_res_rl(struct net_device *dev, bool change)
                srl = 4;
                lrl = 2;
        }
-       error = wldev_ioctl(dev, WLC_SET_SRL, &srl, sizeof(s32), true);
+       error = wldev_ioctl_set(dev, WLC_SET_SRL, &srl, sizeof(s32));
        if (error) {
                DHD_ERROR(("Failed to set SRL, error = %d\n", error));
        }
-       error = wldev_ioctl(dev, WLC_SET_LRL, &lrl, sizeof(s32), true);
+       error = wldev_ioctl_set(dev, WLC_SET_LRL, &lrl, sizeof(s32));
        if (error) {
                DHD_ERROR(("Failed to set LRL, error = %d\n", error));
        }
@@ -4226,8 +4282,17 @@ int wl_android_set_ibss_beacon_ouidata(struct net_device *dev, char *command, in
                return -EINVAL;
        }
 
+       if (total_len < (strlen(CMD_SETIBSSBEACONOUIDATA) + 1)) {
+               WL_ERR(("error. total_len:%d\n", total_len));
+               return -EINVAL;
+       }
+
        pcmd = command + strlen(CMD_SETIBSSBEACONOUIDATA) + 1;
        for (idx = 0; idx < DOT11_OUI_LEN; idx++) {
+               if (*pcmd == '\0') {
+                       WL_ERR(("error while parsing OUI.\n"));
+                       return -EINVAL;
+               }
                hex[0] = *pcmd++;
                hex[1] = *pcmd++;
                ie_buf[idx] =  (uint8)simple_strtoul(hex, NULL, 16);
@@ -4239,6 +4304,12 @@ int wl_android_set_ibss_beacon_ouidata(struct net_device *dev, char *command, in
                ie_buf[idx++] =  (uint8)simple_strtoul(hex, NULL, 16);
                datalen++;
        }
+
+       if (datalen <= 0) {
+               WL_ERR(("error. vndr ie len:%d\n", datalen));
+               return -EINVAL;
+       }
+
        tot_len = (int)(sizeof(vndr_ie_setbuf_t) + (datalen - 1));
        vndr_ie = (vndr_ie_setbuf_t *) kzalloc(tot_len, kflags);
        if (!vndr_ie) {
@@ -4470,13 +4541,13 @@ wl_android_iolist_add(struct net_device *dev, struct list_head *head, struct io_
                        ret = -ENOMEM;
                        goto error;
                }
-               ret = wldev_ioctl(dev, config->ioctl, resume_cfg->arg, config->len, false);
+               ret = wldev_ioctl_get(dev, config->ioctl, resume_cfg->arg, config->len);
                if (ret) {
                        DHD_ERROR(("%s: Failed to get ioctl %d\n", __FUNCTION__,
                                config->ioctl));
                        goto error;
                }
-               ret = wldev_ioctl(dev, config->ioctl + 1, config->arg, config->len, true);
+               ret = wldev_ioctl_set(dev, config->ioctl + 1, config->arg, config->len);
                if (ret) {
                        DHD_ERROR(("%s: Failed to set %s to %d\n", __FUNCTION__,
                                config->iovar, config->param));
@@ -4519,8 +4590,8 @@ wl_android_iolist_resume(struct net_device *dev, struct list_head *head)
                                        config->param);
                } else {
                        if (!ret)
-                               ret = wldev_ioctl(dev, config->ioctl + 1,
-                                       config->arg, config->len, true);
+                               ret = wldev_ioctl_set(dev, config->ioctl + 1,
+                                       config->arg, config->len);
                        if (config->ioctl + 1 == WLC_SET_PM)
                                wl_cfg80211_update_power_mode(dev);
                        kfree(config->arg);
@@ -4591,10 +4662,11 @@ wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
 
        switch (mode) {
        case MIRACAST_MODE_SOURCE:
+#ifdef MIRACAST_MCHAN_ALGO
                /* setting mchan_algo to platform specific value */
                config.iovar = "mchan_algo";
 
-               ret = wldev_ioctl(dev, WLC_GET_BCNPRD, &val, sizeof(int), false);
+               ret = wldev_ioctl_get(dev, WLC_GET_BCNPRD, &val, sizeof(int));
                if (!ret && val > 100) {
                        config.param = 0;
                        DHD_ERROR(("%s: Connected station's beacon interval: "
@@ -4607,7 +4679,9 @@ wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
                if (ret) {
                        goto resume;
                }
+#endif /* MIRACAST_MCHAN_ALGO */
 
+#ifdef MIRACAST_MCHAN_BW
                /* setting mchan_bw to platform specific value */
                config.iovar = "mchan_bw";
                config.param = MIRACAST_MCHAN_BW;
@@ -4615,7 +4689,9 @@ wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
                if (ret) {
                        goto resume;
                }
+#endif /* MIRACAST_MCHAN_BW */
 
+#ifdef MIRACAST_AMPDU_SIZE
                /* setting apmdu to platform specific value */
                config.iovar = "ampdu_mpdu";
                config.param = MIRACAST_AMPDU_SIZE;
@@ -4623,6 +4699,7 @@ wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
                if (ret) {
                        goto resume;
                }
+#endif /* MIRACAST_AMPDU_SIZE */
                /* FALLTROUGH */
                /* Source mode shares most configurations with sink mode.
                 * Fall through here to avoid code duplication
@@ -4637,7 +4714,7 @@ wl_android_set_miracast(struct net_device *dev, char *command, int total_len)
                }
 
                /* tunr off pm */
-               ret = wldev_ioctl(dev, WLC_GET_PM, &val, sizeof(val), false);
+               ret = wldev_ioctl_get(dev, WLC_GET_PM, &val, sizeof(val));
                if (ret) {
                        goto resume;
                }
@@ -5066,22 +5143,16 @@ int wl_android_set_ibss_antenna(struct net_device *dev, char *command, int total
 
 int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len)
 {
-       char                            buf[256];
-       const char                      *str;
        wl_mkeep_alive_pkt_t    mkeep_alive_pkt;
-       wl_mkeep_alive_pkt_t    *mkeep_alive_pktp;
-       int                                     buf_len;
-       int                                     str_len;
-       int res                                 = -1;
+       int ret;
        uint period_msec = 0;
+       char *buf;
 
-       if (extra == NULL)
-       {
+       if (extra == NULL) {
                 DHD_ERROR(("%s: extra is NULL\n", __FUNCTION__));
                 return -1;
        }
-       if (sscanf(extra, "%d", &period_msec) != 1)
-       {
+       if (sscanf(extra, "%d", &period_msec) != 1) {
                 DHD_ERROR(("%s: sscanf error. check period_msec value\n", __FUNCTION__));
                 return -EINVAL;
        }
@@ -5089,36 +5160,27 @@ int wl_keep_alive_set(struct net_device *dev, char* extra, int total_len)
 
        memset(&mkeep_alive_pkt, 0, sizeof(wl_mkeep_alive_pkt_t));
 
-       str = "mkeep_alive";
-       str_len = strlen(str);
-       strncpy(buf, str, str_len);
-       buf[ str_len ] = '\0';
-       mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (buf + str_len + 1);
        mkeep_alive_pkt.period_msec = period_msec;
-       buf_len = str_len + 1;
        mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION);
        mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
 
        /* Setup keep alive zero for null packet generation */
        mkeep_alive_pkt.keep_alive_id = 0;
        mkeep_alive_pkt.len_bytes = 0;
-       buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
-       /* Keep-alive attributes are set in local       variable (mkeep_alive_pkt), and
-        * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no
-        * guarantee that the buffer is properly aligned.
-        */
-       memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN);
 
-       if ((res = wldev_ioctl(dev, WLC_SET_VAR, buf, buf_len, TRUE)) < 0)
-       {
-               DHD_ERROR(("%s:keep_alive set failed. res[%d]\n", __FUNCTION__, res));
+       buf = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL);
+       if (!buf) {
+               DHD_ERROR(("%s: buffer alloc failed\n", __FUNCTION__));
+               return BCME_NOMEM;
        }
+       ret = wldev_iovar_setbuf(dev, "mkeep_alive", (char *)&mkeep_alive_pkt,
+                       WL_MKEEP_ALIVE_FIXED_LEN, buf, WLC_IOCTL_SMLEN, NULL);
+       if (ret < 0)
+               DHD_ERROR(("%s:keep_alive set failed:%d\n", __FUNCTION__, ret));
        else
-       {
-               DHD_ERROR(("%s:keep_alive set ok. res[%d]\n", __FUNCTION__, res));
-       }
-
-       return res;
+               DHD_TRACE(("%s:keep_alive set ok\n", __FUNCTION__));
+       kfree(buf);
+       return ret;
 }
 #ifdef P2PRESP_WFDIE_SRC
 static int wl_android_get_wfdie_resp(struct net_device *dev, char *command, int total_len)
@@ -5213,7 +5275,7 @@ static int wl_android_get_link_status(struct net_device *dev, char *command,
 
        /* get BSS information */
        *(u32 *) buf = htod32(datalen);
-       error = wldev_ioctl(dev, WLC_GET_BSS_INFO, (void *)buf, datalen, false);
+       error = wldev_ioctl_get(dev, WLC_GET_BSS_INFO, (void *)buf, datalen);
        if (unlikely(error)) {
                WL_ERR(("Could not get bss info %d\n", error));
                return -1;
@@ -5346,47 +5408,51 @@ wl_cfg80211_p2plo_offload(struct net_device *dev, char *cmd, char* buf, int len)
 }
 #endif /* P2P_LISTEN_OFFLOADING */
 
-#ifdef BCM4359_CHIP
+#ifdef DYNAMIC_MUMIMO_CONTROL
 int
-wl_android_murx_bfe_cap(struct net_device *dev, int val)
+wl_android_get_murx_bfe_cap(struct net_device *dev, char *command, int total_len)
 {
-       int err = BCME_OK;
-       int iface_count = wl_cfg80211_iface_count(dev);
-       struct ether_addr bssid;
-       wl_reassoc_params_t params;
+       int err = 0;
+       int cap = 0;
+       int bytes_written = 0;
 
-       if (iface_count > 1) {
-               WL_ERR(("murx_bfe_cap change is not allowed when "
-                               "there are multiple interfaces\n"));
-               return -EINVAL;
-       }
        /* Now there is only single interface */
-       err = wldev_iovar_setint(dev, "murx_bfe_cap", val);
+       err = wl_get_murx_bfe_cap(dev, &cap);
        if (unlikely(err)) {
-               WL_ERR(("Failed to set murx_bfe_cap IOVAR to %d,"
-                               "error %d\n", val, err));
+               WL_ERR(("Failed to get murx_bfe_cap, error = %d\n", err));
                return err;
        }
 
-       /* If successful intiate a reassoc */
-       if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false)) < 0) {
-               WL_ERR(("Failed to get bssid, error=%d\n", err));
-               return err;
-       }
+       bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_MURX_BFE_CAP, cap);
 
-       bzero(&params, sizeof(wl_reassoc_params_t));
-       memcpy(&params.bssid, &bssid, ETHER_ADDR_LEN);
+       return bytes_written;
+}
 
-       if ((err = wldev_ioctl(dev, WLC_REASSOC, &params,
-               sizeof(wl_reassoc_params_t), true)) < 0) {
-               WL_ERR(("reassoc failed err:%d \n", err));
-       } else {
-               WL_DBG(("reassoc issued successfully\n"));
+int
+wl_android_set_murx_bfe_cap(struct net_device *dev, int val)
+{
+       int err = BCME_OK;
+
+       err = wl_set_murx_bfe_cap(dev, val, TRUE);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to set murx_bfe_cap to %d, error = %d\n", val, err));
        }
 
        return err;
 }
-#endif /* BCM4359_CHIP */
+
+int
+wl_android_get_bss_support_mumimo(struct net_device *dev, char *command, int total_len)
+{
+       int val = 0;
+       int bytes_written = 0;
+
+       val = wl_check_bss_support_mumimo(dev);
+       bytes_written = snprintf(command, total_len, "%s %d", CMD_GET_BSS_SUPPORT_MUMIMO, val);
+
+       return bytes_written;
+}
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 
 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
 int
@@ -5592,6 +5658,185 @@ wl_android_set_ap_rps_params(struct net_device *dev, char *command, int total_le
 }
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
 
+#ifdef SUPPORT_RSSI_SUM_REPORT
+int
+wl_android_get_rssi_per_ant(struct net_device *dev, char *command, int total_len)
+{
+       wl_rssi_ant_mimo_t rssi_ant_mimo;
+       char *ifname = NULL;
+       char *peer_mac = NULL;
+       char *mimo_cmd = "mimo";
+       char *pos, *token;
+       int err = BCME_OK;
+       int bytes_written = 0;
+       bool mimo_rssi = FALSE;
+
+       memset(&rssi_ant_mimo, 0, sizeof(wl_rssi_ant_mimo_t));
+       /*
+        * STA I/F: DRIVER GET_RSSI_PER_ANT <ifname> <mimo>
+        * AP/GO I/F: DRIVER GET_RSSI_PER_ANT <ifname> <Peer MAC addr> <mimo>
+        */
+       pos = command;
+
+       /* drop command */
+       token = bcmstrtok(&pos, " ", NULL);
+
+       /* get the interface name */
+       token = bcmstrtok(&pos, " ", NULL);
+       if (!token) {
+               WL_ERR(("Invalid arguments\n"));
+               return -EINVAL;
+       }
+       ifname = token;
+
+       /* Optional: Check the MIMO RSSI mode or peer MAC address */
+       token = bcmstrtok(&pos, " ", NULL);
+       if (token) {
+               /* Check the MIMO RSSI mode */
+               if (strncmp(token, mimo_cmd, strlen(mimo_cmd)) == 0) {
+                       mimo_rssi = TRUE;
+               } else {
+                       peer_mac = token;
+               }
+       }
+
+       /* Optional: Check the MIMO RSSI mode - RSSI sum across antennas */
+       token = bcmstrtok(&pos, " ", NULL);
+       if (token && strncmp(token, mimo_cmd, strlen(mimo_cmd)) == 0) {
+               mimo_rssi = TRUE;
+       }
+
+       err = wl_get_rssi_per_ant(dev, ifname, peer_mac, &rssi_ant_mimo);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to get RSSI info, err=%d\n", err));
+               return err;
+       }
+
+       /* Parse the results */
+       WL_DBG(("ifname %s, version %d, count %d, mimo rssi %d\n",
+               ifname, rssi_ant_mimo.version, rssi_ant_mimo.count, mimo_rssi));
+       if (mimo_rssi) {
+               WL_DBG(("MIMO RSSI: %d\n", rssi_ant_mimo.rssi_sum));
+               bytes_written = snprintf(command, total_len, "%s MIMO %d",
+                       CMD_GET_RSSI_PER_ANT, rssi_ant_mimo.rssi_sum);
+       } else {
+               int cnt;
+               bytes_written = snprintf(command, total_len, "%s PER_ANT ", CMD_GET_RSSI_PER_ANT);
+               for (cnt = 0; cnt < rssi_ant_mimo.count; cnt++) {
+                       WL_DBG(("RSSI[%d]: %d\n", cnt, rssi_ant_mimo.rssi_ant[cnt]));
+                       bytes_written = snprintf(command, total_len, "%d ",
+                               rssi_ant_mimo.rssi_ant[cnt]);
+               }
+       }
+
+       return bytes_written;
+}
+
+int
+wl_android_set_rssi_logging(struct net_device *dev, char *command, int total_len)
+{
+       rssilog_set_param_t set_param;
+       char *pos, *token;
+       int err = BCME_OK;
+
+       memset(&set_param, 0, sizeof(rssilog_set_param_t));
+       /*
+        * DRIVER SET_RSSI_LOGGING <enable/disable> <RSSI Threshold> <Time Threshold>
+        */
+       pos = command;
+
+       /* drop command */
+       token = bcmstrtok(&pos, " ", NULL);
+
+       /* enable/disable */
+       token = bcmstrtok(&pos, " ", NULL);
+       if (!token) {
+               WL_ERR(("Invalid arguments\n"));
+               return -EINVAL;
+       }
+       set_param.enable = bcm_atoi(token);
+
+       /* RSSI Threshold */
+       token = bcmstrtok(&pos, " ", NULL);
+       if (!token) {
+               WL_ERR(("Invalid arguments\n"));
+               return -EINVAL;
+       }
+       set_param.rssi_threshold = bcm_atoi(token);
+
+       /* Time Threshold */
+       token = bcmstrtok(&pos, " ", NULL);
+       if (!token) {
+               WL_ERR(("Invalid arguments\n"));
+               return -EINVAL;
+       }
+       set_param.time_threshold = bcm_atoi(token);
+
+       WL_DBG(("enable %d, RSSI threshold %d, Time threshold %d\n", set_param.enable,
+               set_param.rssi_threshold, set_param.time_threshold));
+
+       err = wl_set_rssi_logging(dev, (void *)&set_param);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to configure RSSI logging: enable %d, RSSI Threshold %d,"
+                       " Time Threshold %d\n", set_param.enable, set_param.rssi_threshold,
+                       set_param.time_threshold));
+       }
+
+       return err;
+}
+
+int
+wl_android_get_rssi_logging(struct net_device *dev, char *command, int total_len)
+{
+       rssilog_get_param_t get_param;
+       int err = BCME_OK;
+       int bytes_written = 0;
+
+       err = wl_get_rssi_logging(dev, (void *)&get_param);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to get RSSI logging info\n"));
+               return BCME_ERROR;
+       }
+
+       WL_DBG(("report_count %d, enable %d, rssi_threshold %d, time_threshold %d\n",
+               get_param.report_count, get_param.enable, get_param.rssi_threshold,
+               get_param.time_threshold));
+
+       /* Parse the parameter */
+       if (!get_param.enable) {
+               WL_DBG(("RSSI LOGGING: Feature is disables\n"));
+               bytes_written = snprintf(command, total_len,
+                       "%s FEATURE DISABLED\n", CMD_GET_RSSI_LOGGING);
+       } else if (get_param.enable &
+               (RSSILOG_FLAG_FEATURE_SW | RSSILOG_FLAG_REPORT_READY)) {
+               if (!get_param.report_count) {
+                       WL_DBG(("[PASS] RSSI difference across antennas is within"
+                               " threshold limits\n"));
+                       bytes_written = snprintf(command, total_len, "%s PASS\n",
+                               CMD_GET_RSSI_LOGGING);
+               } else {
+                       WL_DBG(("[FAIL] RSSI difference across antennas found "
+                               "to be greater than %3d dB\n", get_param.rssi_threshold));
+                       WL_DBG(("[FAIL] RSSI difference check have failed for "
+                               "%d out of %d times\n", get_param.report_count,
+                               get_param.time_threshold));
+                       WL_DBG(("[FAIL] RSSI difference is being monitored once "
+                               "per second, for a %d secs window\n", get_param.time_threshold));
+                       bytes_written = snprintf(command, total_len, "%s FAIL - RSSI Threshold "
+                               "%d dBm for %d out of %d times\n", CMD_GET_RSSI_LOGGING,
+                               get_param.rssi_threshold, get_param.report_count,
+                               get_param.time_threshold);
+               }
+       } else {
+               WL_DBG(("[BUSY] Reprot is not ready\n"));
+               bytes_written = snprintf(command, total_len, "%s BUSY - NOT READY\n",
+                       CMD_GET_RSSI_LOGGING);
+       }
+
+       return bytes_written;
+}
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+
 #ifdef SET_PCIE_IRQ_CPU_CORE
 void
 wl_android_set_irq_cpucore(struct net_device *net, int set)
@@ -5669,7 +5914,463 @@ wl_android_get_snr(struct net_device *dev, char *command, int total_len)
        DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command));
        return bytes_written;
 }
+#ifdef WLADPS_PRIVATE_CMD
+static int
+wl_android_set_adps_mode(struct net_device *dev, const char* string_num)
+{
+       int err = 0, adps_mode;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+#ifdef DHD_PM_CONTROL_FROM_FILE
+       if (g_pm_control) {
+               return -EPERM;
+       }
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+
+       adps_mode = bcm_atoi(string_num);
+
+       if ((adps_mode < 0) && (1 < adps_mode)) {
+               WL_ERR(("%s: Invalid value %d.\n", __FUNCTION__, adps_mode));
+               return -EINVAL;
+       }
+
+       err = dhd_enable_adps(dhdp, adps_mode);
+       if (err != BCME_OK) {
+               WL_ERR(("failed to set adps mode %d, error = %d\n", adps_mode, err));
+               return -EIO;
+       }
+       return err;
+}
+static int
+wl_android_get_adps_mode(
+       struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written, err = 0;
+       int len;
+       char buf[WLC_IOCTL_SMLEN];
+
+       bcm_iov_buf_t iov_buf;
+       bcm_iov_buf_t *ptr = NULL;
+       wl_adps_params_v1_t *data = NULL;
+
+       uint8 *pdata = NULL;
+       uint8 band, mode = 0;
+
+       memset(&iov_buf, 0, sizeof(iov_buf));
+
+       len = OFFSETOF(bcm_iov_buf_t, data) + sizeof(*data);
+
+       iov_buf.version = WL_ADPS_IOV_VER;
+       iov_buf.len = sizeof(band);
+       iov_buf.id = WL_ADPS_IOV_MODE;
+
+       pdata = (uint8 *)&iov_buf.data;
+
+       for (band = 1; band <= MAX_BANDS; band++) {
+               pdata[0] = band;
+               err = wldev_iovar_getbuf(dev, "adps", &iov_buf, len,
+                       buf, WLC_IOCTL_SMLEN, NULL);
+               if (err != BCME_OK) {
+                       WL_ERR(("%s fail to get adps band %d(%d).\n",
+                                       __FUNCTION__, band, err));
+                       return -EIO;
+               }
+               ptr = (bcm_iov_buf_t *) buf;
+               data = (wl_adps_params_v1_t *) ptr->data;
+               mode = data->mode;
+               if (mode != OFF) {
+                       break;
+               }
+       }
+
+       bytes_written = snprintf(command, total_len, "%s %d",
+               CMD_GET_ADPS, mode);
+       return bytes_written;
+}
+#endif /* WLADPS_PRIVATE_CMD */
+
+#ifdef DHD_PKT_LOGGING
+static int
+wl_android_pktlog_filter_enable(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       int err = BCME_OK;
 
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       err = dhd_pktlog_filter_enable(filter, PKTLOG_TXPKT_CASE, TRUE);
+       err = dhd_pktlog_filter_enable(filter, PKTLOG_TXSTATUS_CASE, TRUE);
+       err = dhd_pktlog_filter_enable(filter, PKTLOG_RXPKT_CASE, TRUE);
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog filter enable success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog filter enable fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_filter_disable(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       int err = BCME_OK;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       err = dhd_pktlog_filter_enable(filter, PKTLOG_TXPKT_CASE, FALSE);
+       err = dhd_pktlog_filter_enable(filter, PKTLOG_TXSTATUS_CASE, FALSE);
+       err = dhd_pktlog_filter_enable(filter, PKTLOG_RXPKT_CASE, FALSE);
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog filter disable success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog filter disable fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_filter_pattern_enable(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       int err = BCME_OK;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       if (strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE) + 1 > total_len) {
+               return BCME_ERROR;
+       }
+
+       err = dhd_pktlog_filter_pattern_enable(filter,
+                       command + strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE) + 1, TRUE);
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog filter pattern enable success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog filter pattern enable fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_filter_pattern_disable(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       int err = BCME_OK;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       if (strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE) + 1 > total_len) {
+               return BCME_ERROR;
+       }
+
+       err = dhd_pktlog_filter_pattern_enable(filter,
+                       command + strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE) + 1, FALSE);
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog filter pattern disable success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog filter pattern disable fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_filter_add(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       int err = BCME_OK;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       if (strlen(CMD_PKTLOG_FILTER_ADD) + 1 > total_len) {
+               return BCME_ERROR;
+       }
+
+       err = dhd_pktlog_filter_add(filter, command + strlen(CMD_PKTLOG_FILTER_ADD) + 1);
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog filter add success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog filter add fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_filter_info(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       int err = BCME_OK;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       err = dhd_pktlog_filter_info(filter);
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog filter info success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog filter info fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_start(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring || !dhdp->pktlog->rx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
+                       __FUNCTION__, dhdp->pktlog->tx_pktlog_ring, dhdp->pktlog->rx_pktlog_ring));
+               return -EINVAL;
+       }
+
+       dhdp->pktlog->tx_pktlog_ring->start = TRUE;
+       dhdp->pktlog->rx_pktlog_ring->start = TRUE;
+
+       bytes_written = snprintf(command, total_len, "OK");
+
+       DHD_ERROR(("%s: pktlog start success\n", __FUNCTION__));
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_stop(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring || !dhdp->pktlog->rx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
+                       __FUNCTION__, dhdp->pktlog->tx_pktlog_ring, dhdp->pktlog->rx_pktlog_ring));
+               return -EINVAL;
+       }
+
+       dhdp->pktlog->tx_pktlog_ring->start = FALSE;
+       dhdp->pktlog->rx_pktlog_ring->start = FALSE;
+
+       bytes_written = snprintf(command, total_len, "OK");
+
+       DHD_ERROR(("%s: pktlog stop success\n", __FUNCTION__));
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_filter_exist(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       dhd_pktlog_filter_t *filter;
+       uint32 id;
+       bool exist = FALSE;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       filter = dhdp->pktlog->pktlog_filter;
+
+       if (strlen(CMD_PKTLOG_FILTER_EXIST) + 1 > total_len) {
+               return BCME_ERROR;
+       }
+
+       exist = dhd_pktlog_filter_existed(filter, command + strlen(CMD_PKTLOG_FILTER_EXIST) + 1,
+                       &id);
+
+       if (exist) {
+               bytes_written = snprintf(command, total_len, "TRUE");
+               DHD_ERROR(("%s: pktlog filter pattern id: %d is existed\n", __FUNCTION__, id));
+       } else {
+               bytes_written = snprintf(command, total_len, "FALSE");
+               DHD_ERROR(("%s: pktlog filter pattern id: %d is not existed\n", __FUNCTION__, id));
+       }
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_minmize_enable(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring || !dhdp->pktlog->rx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
+                       __FUNCTION__, dhdp->pktlog->tx_pktlog_ring, dhdp->pktlog->rx_pktlog_ring));
+               return -EINVAL;
+       }
+
+       dhdp->pktlog->tx_pktlog_ring->pktlog_minmize = TRUE;
+       dhdp->pktlog->rx_pktlog_ring->pktlog_minmize = TRUE;
+
+       bytes_written = snprintf(command, total_len, "OK");
+
+       DHD_ERROR(("%s: pktlog pktlog_minmize enable\n", __FUNCTION__));
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_minmize_disable(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (!dhdp->pktlog->tx_pktlog_ring || !dhdp->pktlog->rx_pktlog_ring) {
+               DHD_PKT_LOG(("%s(): tx_pktlog_ring=%p rx_pktlog_ring=%p\n",
+                       __FUNCTION__, dhdp->pktlog->tx_pktlog_ring, dhdp->pktlog->rx_pktlog_ring));
+               return -EINVAL;
+       }
+
+       dhdp->pktlog->tx_pktlog_ring->pktlog_minmize = FALSE;
+       dhdp->pktlog->rx_pktlog_ring->pktlog_minmize = FALSE;
+
+       bytes_written = snprintf(command, total_len, "OK");
+
+       DHD_ERROR(("%s: pktlog pktlog_minmize disable\n", __FUNCTION__));
+
+       return bytes_written;
+}
+
+static int
+wl_android_pktlog_change_size(struct net_device *dev, char *command, int total_len)
+{
+       int bytes_written = 0;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(dev);
+       int err = BCME_OK;
+       int size;
+
+       if (!dhdp || !dhdp->pktlog) {
+               DHD_PKT_LOG(("%s(): dhdp=%p pktlog=%p\n",
+                       __FUNCTION__, dhdp, (dhdp ? dhdp->pktlog : NULL)));
+               return -EINVAL;
+       }
+
+       if (strlen(CMD_PKTLOG_CHANGE_SIZE) + 1 > total_len) {
+               return BCME_ERROR;
+       }
+
+       size = bcm_strtoul(command + strlen(CMD_PKTLOG_CHANGE_SIZE) + 1, NULL, 0);
+
+       dhdp->pktlog->tx_pktlog_ring =
+               dhd_pktlog_ring_change_size(dhdp->pktlog->tx_pktlog_ring, size);
+       if (!dhdp->pktlog->tx_pktlog_ring) {
+               err = BCME_ERROR;
+       }
+
+       dhdp->pktlog->rx_pktlog_ring =
+               dhd_pktlog_ring_change_size(dhdp->pktlog->rx_pktlog_ring, size);
+       if (!dhdp->pktlog->tx_pktlog_ring) {
+               err = BCME_ERROR;
+       }
+
+       if (err == BCME_OK) {
+               bytes_written = snprintf(command, total_len, "OK");
+               DHD_ERROR(("%s: pktlog change size success\n", __FUNCTION__));
+       } else {
+               DHD_ERROR(("%s: pktlog change size fail\n", __FUNCTION__));
+               return BCME_ERROR;
+       }
+
+       return bytes_written;
+}
+#endif /* DHD_PKT_LOGGING */
 
 int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
 {
@@ -5887,7 +6588,7 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
                        bytes_written = wldev_set_band(net, band);
                }
 #else
-               bytes_written = wldev_set_band(net, band);
+               bytes_written = wl_cfg80211_set_if_band(net, band);
 #endif /* WL_HOST_BAND_MGMT */
 #ifdef ROAM_CHANNEL_CACHE
                wl_update_roamscan_cache_by_band(net, band);
@@ -5909,19 +6610,25 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
                char *country_code = command + strlen(CMD_COUNTRY) + 1;
                char *rev_info_delim = country_code + 2; /* 2 bytes of country code */
                int revinfo = -1;
-#if defined(DHD_BLOB_EXISTENCE_CHECK)
+               struct wireless_dev *wdev = ndev_to_wdev(net);
+               struct wiphy *wiphy = wdev->wiphy;
                dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(net);
 
-               if (dhdp->is_blob) {
+               BCM_REFERENCE(dhdp);
+               if (CHECK_IS_BLOB(dhdp) && !CHECK_IS_MULT_REGREV(dhdp)) {
                        revinfo = 0;
-               } else
-#endif /* DHD_BLOB_EXISTENCE_CHECK */
-               if ((rev_info_delim) &&
-                       (strnicmp(rev_info_delim, CMD_COUNTRY_DELIMITER,
-                       strlen(CMD_COUNTRY_DELIMITER)) == 0) &&
-                       (rev_info_delim + 1)) {
+               } else if ((rev_info_delim) &&
+                               (strnicmp(rev_info_delim, CMD_COUNTRY_DELIMITER,
+                               strlen(CMD_COUNTRY_DELIMITER)) == 0) &&
+                               (rev_info_delim + 1)) {
                        revinfo  = bcm_atoi(rev_info_delim + 1);
                }
+
+               if (wl_check_dongle_idle(wiphy) != TRUE) {
+                       DHD_ERROR(("FW is busy to check dongle idle\n"));
+                       return 0;
+               }
+
                bytes_written = wldev_set_country(net, country_code, true, true, revinfo);
 #ifdef CUSTOMER_HW4_PRIVATE_CMD
 #ifdef FCC_PWR_LIMIT_2G
@@ -6444,15 +7151,21 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
                bytes_written = wl_cfg80211_get_sta_info(net, command, priv_cmd.total_len);
        }
 #endif /* CUSTOMER_HW4_PRIVATE_CMD */
-       else if (strnicmp(command, CMD_MURX_BFE_CAP,
-                       strlen(CMD_MURX_BFE_CAP)) == 0) {
-#ifdef BCM4359_CHIP
-               uint val = *(command + strlen(CMD_MURX_BFE_CAP) + 1) - '0';
-               bytes_written = wl_android_murx_bfe_cap(net, val);
-#else
-               return BCME_UNSUPPORTED;
-#endif /* BCM4359_CHIP */
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       else if (strnicmp(command, CMD_GET_MURX_BFE_CAP,
+               strlen(CMD_GET_MURX_BFE_CAP)) == 0) {
+               bytes_written = wl_android_get_murx_bfe_cap(net, command, priv_cmd.total_len);
        }
+       else if (strnicmp(command, CMD_SET_MURX_BFE_CAP,
+               strlen(CMD_SET_MURX_BFE_CAP)) == 0) {
+               uint val = *(command + strlen(CMD_SET_MURX_BFE_CAP) + 1) - '0';
+               bytes_written = wl_android_set_murx_bfe_cap(net, val);
+       }
+       else if (strnicmp(command, CMD_GET_BSS_SUPPORT_MUMIMO,
+               strlen(CMD_GET_BSS_SUPPORT_MUMIMO)) == 0) {
+               bytes_written = wl_android_get_bss_support_mumimo(net, command, priv_cmd.total_len);
+       }
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
        else if (strnicmp(command, CMD_GET_AP_BASICRATE, strlen(CMD_GET_AP_BASICRATE)) == 0) {
                bytes_written = wl_android_get_ap_basicrate(net, command, priv_cmd.total_len);
@@ -6472,6 +7185,17 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
                bytes_written = wl_android_get_ap_rps(net, command, priv_cmd.total_len);
        }
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
+#ifdef SUPPORT_RSSI_SUM_REPORT
+       else if (strnicmp(command, CMD_SET_RSSI_LOGGING, strlen(CMD_SET_RSSI_LOGGING)) == 0) {
+               bytes_written = wl_android_set_rssi_logging(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_GET_RSSI_LOGGING, strlen(CMD_GET_RSSI_LOGGING)) == 0) {
+               bytes_written = wl_android_get_rssi_logging(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_GET_RSSI_PER_ANT, strlen(CMD_GET_RSSI_PER_ANT)) == 0) {
+               bytes_written = wl_android_get_rssi_per_ant(net, command, priv_cmd.total_len);
+       }
+#endif /* SUPPORT_RSSI_SUM_REPORT */
 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
        else if (strnicmp(command, CMD_GET_BSS_INFO, strlen(CMD_GET_BSS_INFO)) == 0) {
                bytes_written = wl_cfg80211_get_bss_info(net, command, priv_cmd.total_len);
@@ -6507,10 +7231,13 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
                strlen(CMD_NEW_DEBUG_PRINT_DUMP)) == 0) {
                dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(net);
                dhd_schedule_log_dump(dhdp);
-#if defined(DHD_DEBUG) && defined(BCMPCIE) && defined(DHD_FW_COREDUMP)
+#if defined(DHD_DEBUG) && defined(DHD_FW_COREDUMP)
                dhdp->memdump_type = DUMP_TYPE_BY_SYSDUMP;
                dhd_bus_mem_dump(dhdp);
 #endif /* DHD_DEBUG && BCMPCIE && DHD_FW_COREDUMP */
+#ifdef DHD_PKT_LOGGING
+               dhd_schedule_pktlog_dump(dhdp);
+#endif /* DHD_PKT_LOGGING */
        }
 #endif /* DHD_LOG_DUMP */
 #ifdef SET_PCIE_IRQ_CPU_CORE
@@ -6539,6 +7266,88 @@ wl_handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
        else if (strnicmp(command, CMD_GET_SNR, strlen(CMD_GET_SNR)) == 0) {
                bytes_written = wl_android_get_snr(net, command, priv_cmd.total_len);
        }
+#ifdef WLADPS_PRIVATE_CMD
+       else if (strnicmp(command, CMD_SET_ADPS, strlen(CMD_SET_ADPS)) == 0) {
+               int skip = strlen(CMD_SET_ADPS) + 1;
+               bytes_written = wl_android_set_adps_mode(net, (const char*)command+skip);
+       }
+       else if (strnicmp(command, CMD_GET_ADPS, strlen(CMD_GET_ADPS)) == 0) {
+               bytes_written = wl_android_get_adps_mode(net, command, priv_cmd.total_len);
+       }
+#endif /* WLADPS_PRIVATE_CMD */
+#ifdef DHD_PKT_LOGGING
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_ENABLE,
+               strlen(CMD_PKTLOG_FILTER_ENABLE)) == 0) {
+               bytes_written = wl_android_pktlog_filter_enable(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_DISABLE,
+               strlen(CMD_PKTLOG_FILTER_DISABLE)) == 0) {
+               bytes_written = wl_android_pktlog_filter_disable(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_PATTERN_ENABLE,
+               strlen(CMD_PKTLOG_FILTER_PATTERN_ENABLE)) == 0) {
+               bytes_written =
+                       wl_android_pktlog_filter_pattern_enable(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_PATTERN_DISABLE,
+               strlen(CMD_PKTLOG_FILTER_PATTERN_DISABLE)) == 0) {
+               bytes_written =
+                       wl_android_pktlog_filter_pattern_disable(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_ADD, strlen(CMD_PKTLOG_FILTER_ADD)) == 0) {
+               bytes_written = wl_android_pktlog_filter_add(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_INFO, strlen(CMD_PKTLOG_FILTER_INFO)) == 0) {
+               bytes_written = wl_android_pktlog_filter_info(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_START, strlen(CMD_PKTLOG_START)) == 0) {
+               bytes_written = wl_android_pktlog_start(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_STOP, strlen(CMD_PKTLOG_STOP)) == 0) {
+               bytes_written = wl_android_pktlog_stop(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_FILTER_EXIST, strlen(CMD_PKTLOG_FILTER_EXIST)) == 0) {
+               bytes_written = wl_android_pktlog_filter_exist(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_MINMIZE_ENABLE,
+               strlen(CMD_PKTLOG_MINMIZE_ENABLE)) == 0) {
+               bytes_written = wl_android_pktlog_minmize_enable(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_MINMIZE_DISABLE,
+               strlen(CMD_PKTLOG_MINMIZE_DISABLE)) == 0) {
+               bytes_written = wl_android_pktlog_minmize_disable(net, command, priv_cmd.total_len);
+       }
+       else if (strnicmp(command, CMD_PKTLOG_CHANGE_SIZE,
+               strlen(CMD_PKTLOG_CHANGE_SIZE)) == 0) {
+               bytes_written = wl_android_pktlog_change_size(net, command, priv_cmd.total_len);
+       }
+#endif /* DHD_PKT_LOGGING */
+#if defined(STAT_REPORT)
+       else if (strnicmp(command, CMD_STAT_REPORT_GET_START,
+               strlen(CMD_STAT_REPORT_GET_START)) == 0) {
+               bytes_written = wl_android_stat_report_get_start(net, command, priv_cmd.total_len);
+       } else if (strnicmp(command, CMD_STAT_REPORT_GET_NEXT,
+               strlen(CMD_STAT_REPORT_GET_NEXT)) == 0) {
+               bytes_written = wl_android_stat_report_get_next(net, command, priv_cmd.total_len);
+       }
+#endif /* STAT_REPORT */
+#ifdef APSTA_RESTRICTED_CHANNEL
+       else if (strnicmp(command, CMD_GET_INDOOR_CHANNELS,
+               strlen(CMD_GET_INDOOR_CHANNELS)) == 0) {
+               bytes_written = wl_cfg80211_get_indoor_channels(net, command, priv_cmd.total_len);
+               DHD_INFO(("Selected Indoor Channels - %s\n", command));
+       }
+       else if (strnicmp(command, CMD_SET_INDOOR_CHANNELS,
+               strlen(CMD_SET_INDOOR_CHANNELS)) == 0) {
+               bytes_written = wl_cfg80211_set_indoor_channels(net, command, priv_cmd.total_len);
+       }
+#endif /* APSTA_RESTRICTED_CHANNEL */
+#ifdef SUPPORT_SET_CAC
+       else if (strnicmp(command, CMD_ENABLE_CAC, strlen(CMD_ENABLE_CAC)) == 0) {
+               int enable = *(command + strlen(CMD_ENABLE_CAC) + 1) - '0';
+               bytes_written = wl_cfg80211_enable_cac(net, enable);
+       }
+#endif /* SUPPORT_SET_CAC */
        else {
                DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
                bytes_written = scnprintf(command, sizeof("FAIL"), "FAIL");
@@ -6559,6 +7368,10 @@ int wl_android_init(void)
                bcm_strncpy_s(iface_name, IFNAMSIZ, "wlan", IFNAMSIZ);
        }
 
+#ifdef CUSTOMER_HW4_DEBUG
+       g_assert_type = 1;
+#endif /* CUSTOMER_HW4_DEBUG */
+
 #ifdef WL_GENL
        wl_genl_init();
 #endif
index fc376ec6a9d468873a5a3231779a67a0c013e923..6587da36f13bb8ef48014a9a8f1e6e6fe406d32c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver - Android related functions
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index adacdeb74a7e6f64aacea68719b4f6716f1fe9b4..5fbff5348349bf18be737d4797a458d7851182b7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_cfg80211.c 689676 2017-03-13 06:07:58Z $
+ * $Id: wl_cfg80211.c 750863 2018-03-08 09:19:36Z $
  */
 /* */
 #include <typedefs.h>
 #include <wl_cfgvendor.h>
 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 14, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */
 
+#if defined(STAT_REPORT)
+#include <wl_statreport.h>
+#endif /* STAT_REPORT */
+
 
 #ifdef PROP_TXSTATUS
 #include <dhd_wlfc.h>
@@ -208,6 +212,14 @@ enum rmc_event_type {
 };
 #endif /* WL_RELMCAST */
 
+#ifdef WL_LASTEVT
+typedef struct wl_last_event {
+       uint32 current_time;            /* current tyime */
+       uint32 timestamp;               /* event timestamp */
+       wl_event_msg_t event;   /* Encapsulated event */
+} wl_last_event_t;
+#endif /* WL_LASTEVT */
+
 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
  * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
  * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
@@ -432,6 +444,24 @@ wl_find_vndr_ies_specific_vender(struct bcm_cfg80211 *cfg,
 static s32 wl_set_adps_mode(struct bcm_cfg80211 *cfg, struct net_device *ndev, uint8 enable_mode);
 #endif /* WLADPS_SEAK_AP_WAR */
 
+#define MAX_VNDR_OUI_STR_LEN   256
+#define VNDR_OUI_STR_LEN       10
+static const uchar *exclude_vndr_oui_list[] = {
+       "\x00\x50\xf2",                 /* Microsoft */
+       "\x00\x00\xf0",                 /* Samsung Elec */
+       WFA_OUI,                        /* WFA */
+       NULL
+};
+
+typedef struct wl_vndr_oui_entry {
+       uchar oui[DOT11_OUI_LEN];
+       struct list_head list;
+} wl_vndr_oui_entry_t;
+
+static int wl_vndr_ies_get_vendor_oui(struct bcm_cfg80211 *cfg,
+               struct net_device *ndev, char *vndr_oui, u32 vndr_oui_len);
+static void wl_vndr_ies_clear_vendor_oui_list(struct bcm_cfg80211 *cfg);
+
 /*
  * cfg80211_ops api/callback list
  */
@@ -591,10 +621,12 @@ s32 wl_cfg80211_add_del_bss(struct bcm_cfg80211 *cfg,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) || defined(WL_COMPAT_WIRELESS)
 static s32 wl_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev);
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
+#ifdef GTK_OFFLOAD_SUPPORT
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
 static s32 wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
        struct cfg80211_gtk_rekey_data *data);
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) */
+#endif /* GTK_OFFLOAD_SUPPORT */
 chanspec_t wl_chspec_driver_to_host(chanspec_t chanspec);
 chanspec_t wl_chspec_host_to_driver(chanspec_t chanspec);
 #ifdef WL11ULB
@@ -744,7 +776,7 @@ static s32 wl_mrg_ie(struct bcm_cfg80211 *cfg, u8 *ie_stream, u16 ie_size);
 static s32 wl_cp_ie(struct bcm_cfg80211 *cfg, u8 *dst, u16 dst_size);
 static u32 wl_get_ielen(struct bcm_cfg80211 *cfg);
 #ifdef MFP
-static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa);
+static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8** rsn_cap);
 #endif
 
 #ifdef WL11U
@@ -796,7 +828,15 @@ static __used bool wl_is_ibssstarter(struct bcm_cfg80211 *cfg);
  */
 static s32 __wl_cfg80211_up(struct bcm_cfg80211 *cfg);
 static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg);
+
+#ifdef WL_LASTEVT
+static bool wl_is_linkdown(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e, void *data);
+#define WL_IS_LINKDOWN(cfg, e, data) wl_is_linkdown(cfg, e, data)
+#else
 static bool wl_is_linkdown(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e);
+#define WL_IS_LINKDOWN(cfg, e, data) wl_is_linkdown(cfg, e)
+#endif /* WL_LASTEVT */
+
 static bool wl_is_linkup(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e,
        struct net_device *ndev);
 static bool wl_is_nonetwork(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e);
@@ -845,8 +885,8 @@ int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
 int init_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver);
 void reset_roam_cache(struct bcm_cfg80211 *cfg);
 void add_roam_cache(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi);
-int  get_roam_channel_list(int target_chan,
-       chanspec_t *channels, const wlc_ssid_t *ssid, int ioctl_ver);
+int  get_roam_channel_list(int target_chan, chanspec_t *channels,
+       int n_channels, const wlc_ssid_t *ssid, int ioctl_ver);
 void print_roam_cache(struct bcm_cfg80211 *cfg);
 void set_roam_band(int band);
 void update_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver);
@@ -862,6 +902,10 @@ extern uint dhd_master_mode;
 extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
 #endif /* PKT_FILTER_SUPPORT */
 
+#ifdef SUPPORT_SET_CAC
+static void wl_cfg80211_set_cac(struct bcm_cfg80211 *cfg, int enable);
+#endif /* SUPPORT_SET_CAC */
+
 static int wl_cfg80211_delayed_roam(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        const struct ether_addr *bssid);
 static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify);
@@ -875,6 +919,7 @@ static int bw2cap[] = { 0, 0, WLC_BW_CAP_20MHZ, WLC_BW_CAP_40MHZ, WLC_BW_CAP_80M
        cfg80211_disconnected(dev, reason, ie, len, loc_gen, gfp);
 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0))
 #define CFG80211_DISCONNECTED(dev, reason, ie, len, loc_gen, gfp) \
+       BCM_REFERENCE(loc_gen); \
        cfg80211_disconnected(dev, reason, ie, len, gfp);
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) */
 
@@ -905,6 +950,10 @@ static s32 wl_rssi_offset(s32 rssi)
                                 (akm) == RSN_AKM_UNSPECIFIED ||        \
                                 (akm) == RSN_AKM_PSK)
 
+#ifdef WL_IRQSET
+static void wl_irq_set_work_handler(struct work_struct *work);
+#define IRQ_SET_DURATION 23000
+#endif /* WL_IRQSET */
 
 extern int dhd_wait_pend8021x(struct net_device *dev);
 #ifdef PROP_TXSTATUS_VSDB
@@ -937,37 +986,6 @@ struct chan_info {
 #define CFG80211_PUT_BSS(wiphy, bss) cfg80211_put_bss(bss);
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */
 
-#if (WL_DBG_LEVEL > 0)
-#define WL_DBG_ESTR_MAX        50
-static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
-       "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
-       "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
-       "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
-       "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
-       "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
-       "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
-       "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
-       "PFN_NET_LOST",
-       "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
-       "IBSS_ASSOC",
-       "RADIO", "PSM_WATCHDOG",
-       "WLC_E_XXX_ASSOC_START", "WLC_E_XXX_ASSOC_ABORT",
-       "PROBREQ_MSG",
-       "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
-       "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
-       "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
-       "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
-       "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
-       "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
-       "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
-       "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
-       "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
-       "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
-       "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE",
-       "WLC_E_ALLOW_CREDIT_BORROW"
-};
-#endif                         /* WL_DBG_LEVEL */
-
 #define CHAN2G(_channel, _freq, _flags) {                      \
        .band                   = IEEE80211_BAND_2GHZ,          \
        .center_freq            = (_freq),                      \
@@ -1177,7 +1195,7 @@ static void wl_add_remove_pm_enable_work(struct bcm_cfg80211 *cfg,
         * work getting scheduled.
         */
        if (delayed_work_pending(&cfg->pm_enable_work)) {
-               cancel_delayed_work_sync(&cfg->pm_enable_work);
+               cancel_delayed_work(&cfg->pm_enable_work);
                DHD_PM_WAKE_UNLOCK(cfg->pub);
        }
 
@@ -1544,7 +1562,7 @@ s32 wl_set_tx_power(struct net_device *dev,
        /* Make sure radio is off or on as far as software is concerned */
        disable = WL_RADIO_SW_DISABLE << 16;
        disable = htod32(disable);
-       err = wldev_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable), true);
+       err = wldev_ioctl_set(dev, WLC_SET_RADIO, &disable, sizeof(disable));
        if (unlikely(err)) {
                WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
                return err;
@@ -1601,14 +1619,17 @@ static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
        struct ether_addr bssid;
        struct wl_bss_info *bss = NULL;
        s32 bssidx = 0; /* Explicitly set to primary bssidx */
+       char *buf;
 
-       if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
+       memset(&bssid, 0, sizeof(bssid));
+       if ((err = wldev_ioctl_get(dev, WLC_GET_BSSID, &bssid, sizeof(bssid)))) {
                /* STA interface is not associated. So start the new interface on a temp
                 * channel . Later proper channel will be applied by the above framework
                 * via set_channel (cfg80211 API).
                 */
                WL_DBG(("Not associated. Return a temp channel. \n"));
-               err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band, sizeof(int), false);
+               cur_band = 0;
+               err = wldev_ioctl_get(dev, WLC_GET_BAND, &cur_band, sizeof(int));
                if (unlikely(err)) {
                        WL_ERR(("Get band failed\n"));
                        return wl_ch_host_to_driver(cfg, bssidx, WL_P2P_TEMP_CHAN);
@@ -1619,19 +1640,26 @@ static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
                        return wl_ch_host_to_driver(cfg, bssidx, WL_P2P_TEMP_CHAN);
        }
 
+       buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+       if (!buf) {
+               WL_ERR(("buf alloc failed. use temp channel\n"));
+               return wl_ch_host_to_driver(cfg, bssidx, WL_P2P_TEMP_CHAN);
+       }
 
-       *(u32 *) cfg->extra_buf = htod32(WL_EXTRA_BUF_MAX);
-       if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, cfg->extra_buf,
-               WL_EXTRA_BUF_MAX, false))) {
+       *(u32 *)buf = htod32(WL_EXTRA_BUF_MAX);
+       if ((err = wldev_ioctl_get(dev, WLC_GET_BSS_INFO, buf,
+               WL_EXTRA_BUF_MAX))) {
                        WL_ERR(("Failed to get associated bss info, use temp channel \n"));
                        chspec = wl_ch_host_to_driver(cfg, bssidx, WL_P2P_TEMP_CHAN);
        }
        else {
-                       bss = (struct wl_bss_info *) (cfg->extra_buf + 4);
+                       bss = (struct wl_bss_info *) (buf + 4);
                        chspec =  bss->chanspec;
 
                        WL_DBG(("Valid BSS Found. chanspec:%d \n", chspec));
        }
+
+       kfree(buf);
        return chspec;
 }
 
@@ -1675,9 +1703,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
        struct net_device *primary_ndev;
        struct net_device *new_ndev;
        struct ether_addr primary_mac;
-#ifdef WL_VIRTUAL_APSTA
        bcm_struct_cfgdev *new_cfgdev;
-#endif /* WL_VIRTUAL_APSTA */
 #ifdef PROP_TXSTATUS_VSDB
 #if defined(BCMSDIO)
        s32 up = 1;
@@ -1710,11 +1736,14 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
        wl_cfg80211_tdls_config(cfg, TDLS_STATE_IF_CREATE, false);
 #endif /* WLTDLS */
 
+       mutex_lock(&cfg->if_sync);
        WL_DBG(("if name: %s, type: %d\n", name, type));
        switch (type) {
        case NL80211_IFTYPE_ADHOC:
 #ifdef WLAIBSS_MCHAN
-               return bcm_cfg80211_add_ibss_if(wiphy, (char *)name);
+               new_cfgdev = bcm_cfg80211_add_ibss_if(wiphy, (char *)name);
+               mutex_unlock(&cfg->if_sync);
+               return new_cfgdev;
 #endif /* WLAIBSS_MCHAN */
        case NL80211_IFTYPE_AP_VLAN:
        case NL80211_IFTYPE_WDS:
@@ -1724,11 +1753,15 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                err = -EINVAL;
                goto fail;
        case NL80211_IFTYPE_MONITOR:
-               return wl_cfg80211_add_monitor_if(name);
+               new_cfgdev = wl_cfg80211_add_monitor_if(name);
+               mutex_unlock(&cfg->if_sync);
+               return new_cfgdev;
 #if defined(WL_CFG80211_P2P_DEV_IF)
        case NL80211_IFTYPE_P2P_DEVICE:
                cfg->down_disc_if = FALSE;
-               return wl_cfgp2p_add_p2p_disc_if(cfg);
+               new_cfgdev = wl_cfgp2p_add_p2p_disc_if(cfg);
+               mutex_unlock(&cfg->if_sync);
+               return new_cfgdev;
 #endif /* WL_CFG80211_P2P_DEV_IF */
        case NL80211_IFTYPE_STATION:
 #ifdef WL_VIRTUAL_APSTA
@@ -1753,6 +1786,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                        err = -ENOMEM;
                        goto fail;
                 } else {
+                       mutex_unlock(&cfg->if_sync);
                        return new_cfgdev;
                }
 #endif /* WL_VIRTUAL_APSTA */
@@ -1773,6 +1807,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                        err = -ENOMEM;
                        goto fail;
                } else {
+                       mutex_unlock(&cfg->if_sync);
                        return new_cfgdev;
                }
 #endif /* WL_VIRTUAL_APSTA */
@@ -1819,7 +1854,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                        if (!enabled && dhd->op_mode != DHD_FLAG_HOSTAP_MODE &&
                                dhd->op_mode != DHD_FLAG_IBSS_MODE) {
                                dhd_wlfc_init(dhd);
-                               err = wldev_ioctl(primary_ndev, WLC_UP, &up, sizeof(s32), true);
+                               err = wldev_ioctl_set(primary_ndev, WLC_UP, &up, sizeof(s32));
                                if (err < 0)
                                        WL_ERR(("WLC_UP return err:%d\n", err));
                        }
@@ -1846,6 +1881,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                /* For P2P mode, use P2P-specific driver features to create the
                 * bss: "cfg p2p_ifadd"
                 */
+               if (wl_check_dongle_idle(wiphy) != TRUE) {
+                       WL_ERR(("FW is busy to add interface"));
+                       return ERR_PTR(-ENOMEM);
+               }
                wl_set_p2p_status(cfg, IF_ADDING);
                memset(&cfg->if_event_info, 0, sizeof(cfg->if_event_info));
                cfg_type = wl_cfgp2p_get_conn_idx(cfg);
@@ -1964,7 +2003,11 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                        INIT_COMPLETION(cfg->iface_disable);
 #else
                        init_completion(&cfg->iface_disable);
-#endif
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
+#ifdef SUPPORT_SET_CAC
+                       wl_cfg80211_set_cac(cfg, 0);
+#endif /* SUPPORT_SET_CAC */
+                       mutex_unlock(&cfg->if_sync);
                        return ndev_to_cfgdev(new_ndev);
                } else {
                        wl_clr_p2p_status(cfg, IF_ADDING);
@@ -1993,6 +2036,9 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
                                        WL_ERR(("IFDEL didn't complete properly\n"));
                                }
                                err = -ENODEV;
+#ifdef SUPPORT_SET_CAC
+                               wl_cfg80211_set_cac(cfg, 1);
+#endif /* SUPPORT_SET_CAC */
                        } else {
                                WL_ERR(("IFDEL operation failed, error code = %d\n", err));
                        }
@@ -2013,6 +2059,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
        }
 
 fail:
+       mutex_unlock(&cfg->if_sync);
        if (err) {
 #ifdef WLTDLS
                /* Enable back TDLS on failure */
@@ -2062,14 +2109,17 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev)
        if (!(dhd->chan_isvht80))
                dhd_set_cpucore(dhd, FALSE);
 #endif /* CUSTOM_SET_CPUCORE */
+       mutex_lock(&cfg->if_sync);
 #ifdef WL_CFG80211_P2P_DEV_IF
        if (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
                if (dhd_download_fw_on_driverload) {
-                       return wl_cfgp2p_del_p2p_disc_if(cfgdev, cfg);
+                       ret = wl_cfgp2p_del_p2p_disc_if(cfgdev, cfg);
                } else {
                        cfg->down_disc_if = TRUE;
-                       return 0;
+                       ret = 0;
                }
+               mutex_unlock(&cfg->if_sync);
+               return ret;
        }
 #endif /* WL_CFG80211_P2P_DEV_IF */
        dev = cfgdev_to_wlc_ndev(cfgdev, cfg);
@@ -2086,6 +2136,12 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev)
                ret = -ENODEV;
                goto done;
        }
+
+       if (wl_check_dongle_idle(wiphy) != TRUE) {
+               WL_ERR(("FW is busy to add interface"));
+               return BCME_ERROR;
+       }
+
        if ((cfg->p2p_supported) && index && (wl_cfgp2p_find_type(cfg, index, &type) == BCME_OK)) {
                /* Handle P2P Interace del */
                memcpy(p2p_mac.octet, wl_to_p2p_bss_macaddr(cfg, type).octet, ETHER_ADDR_LEN);
@@ -2143,10 +2199,11 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev)
                        ret = wl_cfgp2p_ifdel(cfg, &p2p_mac);
 #if defined(DHD_HANG_SEND_UP_TEST)
                        if (ret != BCME_OK ||
-                               dhd->req_hang_type == HANG_REASON_IFACE_OP_FAILURE) {
+                               dhd->req_hang_type == HANG_REASON_IFACE_OP_FAILURE)
 #else /* DHD_HANG_SEND_UP_TEST */
-                       if (ret != BCME_OK) {
+                       if (ret != BCME_OK)
 #endif /* DHD_HANG_SEND_UP_TEST */
+                       {
                                struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg);
                                dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
 
@@ -2177,6 +2234,9 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev)
                                } else {
                                        WL_ERR(("IFDEL didn't complete properly\n"));
                                }
+#ifdef SUPPORT_SET_CAC
+                               wl_cfg80211_set_cac(cfg, 1);
+#endif /* SUPPORT_SET_CAC */
                        }
 
                        ret = dhd_del_monitor(dev);
@@ -2194,6 +2254,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev)
        }
 
 done:
+       mutex_unlock(&cfg->if_sync);
 #ifdef WLTDLS
        if (ret == BCME_OK) {
                /* If interface del is success, try enabling back TDLS */
@@ -2219,6 +2280,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
        dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
 
+       mutex_lock(&cfg->if_sync);
        WL_DBG(("Enter type %d\n", type));
        switch (type) {
        case NL80211_IFTYPE_MONITOR:
@@ -2234,6 +2296,23 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                break;
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_P2P_CLIENT:
+               if (ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
+                       s32 bssidx = wl_get_bssidx_by_wdev(cfg, ndev->ieee80211_ptr);
+                       if (bssidx < 0) {
+                               /* validate bssidx */
+                               WL_ERR(("Wrong bssidx! \n"));
+                               err = -EINVAL;
+                               goto error;
+                       }
+                       WL_DBG(("del interface. bssidx:%d", bssidx));
+                       /* Downgrade role from AP to STA */
+                       if ((err = wl_cfg80211_add_del_bss(cfg, ndev,
+                                       bssidx, NL80211_IFTYPE_STATION, 0, NULL)) < 0) {
+                               WL_ERR(("AP-STA Downgrade failed \n"));
+                               err = -EINVAL;
+                               goto error;
+                       }
+               }
                mode = WL_MODE_BSS;
                break;
        case NL80211_IFTYPE_AP:
@@ -2245,16 +2324,29 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                ap = 1;
                break;
        default:
-               return -EINVAL;
+               err = -EINVAL;
+               goto error;
+       }
+
+       if (!dhd) {
+               err = -EINVAL;
+               goto error;
+       }
+
+       /* If any scan is going on, abort it */
+       if (wl_abort_scan_and_check(cfg) != TRUE) {
+               wl_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true);
        }
 
-       if (!dhd)
-               return -EINVAL;
        if (ap) {
                wl_set_mode_by_netdev(cfg, ndev, mode);
                if (is_p2p_group_iface(ndev->ieee80211_ptr) &&
                        cfg->p2p && wl_cfgp2p_vif_created(cfg)) {
                        WL_DBG(("p2p_vif_created p2p_on (%d)\n", p2p_on(cfg)));
+                       if (wl_check_dongle_idle(wiphy) != TRUE) {
+                               WL_ERR(("FW is busy to add interface"));
+                               return -EINVAL;
+                       }
                        wl_notify_escan_complete(cfg, ndev, true, true);
 
                        /* Dual p2p doesn't support multiple P2PGO interfaces,
@@ -2264,7 +2356,8 @@ 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 "));
-                               return BCME_ERROR;
+                               err = BCME_ERROR;
+                               goto error;
                        }
                        /* In concurrency case, STA may be already associated in a particular
                         * channel. so retrieve the current channel of primary interface and
@@ -2274,10 +2367,13 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                        index = wl_get_bssidx_by_wdev(cfg, ndev->ieee80211_ptr);
                        if (index < 0) {
                                WL_ERR(("Find p2p index from ndev(%p) failed\n", ndev));
-                               return BCME_ERROR;
+                               err = BCME_ERROR;
+                               goto error;
+                       }
+                       if (wl_cfgp2p_find_type(cfg, index, &conn_idx) != BCME_OK) {
+                               err = BCME_ERROR;
+                               goto error;
                        }
-                       if (wl_cfgp2p_find_type(cfg, index, &conn_idx) != BCME_OK)
-                               return BCME_ERROR;
 
                        wlif_type = WL_P2P_IF_GO;
                        WL_DBG(("%s : ap (%d), infra_ibss (%d), iftype (%d) conn_idx (%d)\n",
@@ -2302,11 +2398,12 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                        err = wl_cfg80211_set_ap_role(cfg, ndev);
                        if (unlikely(err)) {
                                WL_ERR(("set ap role failed!\n"));
-                               return err;
+                               goto error;
                        }
                } else {
                        WL_ERR(("Cannot change the interface for GO or SOFTAP\n"));
-                       return -EINVAL;
+                       err = -EINVAL;
+                       goto error;
                }
        } else {
                /* P2P GO interface deletion is handled on the basis of role type (AP).
@@ -2317,15 +2414,18 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
                WL_DBG(("Change_virtual_iface for transition from GO/AP to client/STA"));
        }
 
-       err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra_ibss, sizeof(s32), true);
+       err = wldev_ioctl_set(ndev, WLC_SET_INFRA, &infra_ibss, sizeof(s32));
        if (err < 0) {
                WL_ERR(("SET INFRA/IBSS  error %d\n", err));
-               return -EINVAL;
+               err = -EINVAL;
+               goto error;
        }
 
        WL_DBG(("Setting iftype to %d \n", type));
        ndev->ieee80211_ptr->iftype = type;
-       return 0;
+error:
+       mutex_unlock(&cfg->if_sync);
+       return err;
 }
 
 s32
@@ -2673,7 +2773,7 @@ wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
        memset(valid_chan_list, 0, size);
        list = (wl_uint32_list_t *)(void *) valid_chan_list;
        list->count = htod32(WL_NUMCHANNELS);
-       err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false);
+       err = wldev_ioctl_get(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size);
        if (err != 0) {
                WL_ERR(("get channels failed with %d\n", err));
        }
@@ -2852,6 +2952,13 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev,
 #endif /* P2P_SKIP_DFS */
                                list = (wl_uint32_list_t *) chan_buf;
                                n_valid_chan = dtoh32(list->count);
+                               if (n_valid_chan > WL_NUMCHANNELS) {
+                                       WL_ERR(("wrong n_valid_chan:%d\n", n_valid_chan));
+                                       kfree(default_chan_list);
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
+
                                for (i = 0; i < num_chans; i++)
                                {
 #ifdef WL_HOST_BAND_MGMT
@@ -2964,9 +3071,9 @@ wl_do_escan(struct bcm_cfg80211 *cfg, struct wiphy *wiphy, struct net_device *nd
        struct cfg80211_scan_request *request)
 {
        s32 err = BCME_OK;
-       s32 passive_scan;
-       s32 passive_scan_time;
-       s32 passive_scan_time_org;
+       s32 passive_scan = 0;
+       s32 passive_scan_time = 0;
+       s32 passive_scan_time_org = 0;
        wl_scan_results_t *results;
        WL_SCAN(("Enter \n"));
 
@@ -2979,8 +3086,8 @@ wl_do_escan(struct bcm_cfg80211 *cfg, struct wiphy *wiphy, struct net_device *nd
        cfg->escan_info.wiphy = wiphy;
        cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
        passive_scan = cfg->active_scan ? 0 : 1;
-       err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
-               &passive_scan, sizeof(passive_scan), true);
+       err = wldev_ioctl_set(ndev, WLC_SET_PASSIVE_SCAN,
+                             &passive_scan, sizeof(passive_scan));
        if (unlikely(err)) {
                WL_ERR(("error (%d)\n", err));
                goto exit;
@@ -2988,8 +3095,8 @@ wl_do_escan(struct bcm_cfg80211 *cfg, struct wiphy *wiphy, struct net_device *nd
 
        if (passive_channel_skip) {
 
-               err = wldev_ioctl(ndev, WLC_GET_SCAN_PASSIVE_TIME,
-                       &passive_scan_time_org, sizeof(passive_scan_time_org), false);
+               err = wldev_ioctl_get(ndev, WLC_GET_SCAN_PASSIVE_TIME,
+                       &passive_scan_time_org, sizeof(passive_scan_time_org));
                if (unlikely(err)) {
                        WL_ERR(("== error (%d)\n", err));
                        goto exit;
@@ -2998,8 +3105,8 @@ wl_do_escan(struct bcm_cfg80211 *cfg, struct wiphy *wiphy, struct net_device *nd
                WL_SCAN(("PASSIVE SCAN time : %d \n", passive_scan_time_org));
 
                passive_scan_time = 0;
-               err = wldev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME,
-                       &passive_scan_time, sizeof(passive_scan_time), true);
+               err = wldev_ioctl_set(ndev, WLC_SET_SCAN_PASSIVE_TIME,
+                       &passive_scan_time, sizeof(passive_scan_time));
                if (unlikely(err)) {
                        WL_ERR(("== error (%d)\n", err));
                        goto exit;
@@ -3012,8 +3119,8 @@ wl_do_escan(struct bcm_cfg80211 *cfg, struct wiphy *wiphy, struct net_device *nd
        err = wl_run_escan(cfg, ndev, request, WL_SCAN_ACTION_START);
 
        if (passive_channel_skip) {
-               err = wldev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME,
-                       &passive_scan_time_org, sizeof(passive_scan_time_org), true);
+               err = wldev_ioctl_set(ndev, WLC_SET_SCAN_PASSIVE_TIME,
+                       &passive_scan_time_org, sizeof(passive_scan_time_org));
                if (unlikely(err)) {
                        WL_ERR(("== error (%d)\n", err));
                        goto exit;
@@ -3217,7 +3324,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
                ssids = this_ssid;
        }
 
-       if (request && cfg->p2p_supported && !p2p_scan(cfg)) {
+       if (request && cfg->p2p_supported) {
                WL_TRACE_HW4(("START SCAN\n"));
                DHD_OS_SCAN_WAKE_LOCK_TIMEOUT((dhd_pub_t *)(cfg->pub),
                        SCAN_WAKE_LOCK_TIMEOUT);
@@ -3294,8 +3401,8 @@ scan_out:
 #endif /* DHD_DEBUG && DHD_FW_COREDUMP */
 
                        bzero(&bssid, sizeof(bssid));
-                       if ((ret = wldev_ioctl(ndev, WLC_GET_BSSID,
-                               &bssid, ETHER_ADDR_LEN, false)) == 0)
+                       if ((ret = wldev_ioctl_get(ndev, WLC_GET_BSSID,
+                               &bssid, ETHER_ADDR_LEN)) == 0)
                                WL_ERR(("FW is connected with " MACDBG "/n",
                                        MAC2STRDBG(bssid.octet)));
                        else
@@ -3406,7 +3513,7 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
        u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
 
        retry = htod32(retry);
-       err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), true);
+       err = wldev_ioctl_set(dev, cmd, &retry, sizeof(retry));
        if (unlikely(err)) {
                WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
                return err;
@@ -3472,14 +3579,15 @@ channel_to_chanspec(struct wiphy *wiphy, struct net_device *dev, u32 channel, u3
                WL_ERR(("buf memory alloc failed\n"));
                goto exit;
        }
-       list = (wl_uint32_list_t *)(void *)buf;
-       list->count = htod32(WL_NUMCHANSPECS);
+
        err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL,
                0, buf, LOCAL_BUF_SIZE, 0, &cfg->ioctl_buf_sync);
        if (err != BCME_OK) {
                WL_ERR(("get chanspecs failed with %d\n", err));
                goto exit;
        }
+
+       list = (wl_uint32_list_t *)(void *)buf;
        for (i = 0; i < dtoh32(list->count); i++) {
                c = dtoh32(list->element[i]);
                if (channel <= CH_MAX_2G_CHANNEL) {
@@ -3702,18 +3810,41 @@ fail:
 }
 #endif /* WLAIBSS_MCHAN */
 
+bool
+wl_check_interface_create_v0(struct bcm_cfg80211 *cfg)
+{
+       int ret = FALSE;
+#if defined(BCMSDIO) || defined(BCMPCIE)
+       u32 chipid, chiprevid;
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+
+       chipid = dhd_get_chip_id(dhdp);
+       chiprevid = dhd_get_chiprev_id(dhdp);
+       WL_DBG(("chipid=0x%x, chiprevid=%x\n", chipid, chiprevid));
+
+       if (chipid == BCM4359_CHIP_ID &&
+               (chiprevid == 5 || chiprevid == 9)) {
+               ret = TRUE;
+       }
+#endif /* BCMSDIO || BCMPCIE */
+
+       return ret;
+}
+
 s32
 wl_cfg80211_interface_ops(struct bcm_cfg80211 *cfg,
        struct net_device *ndev, s32 bsscfg_idx,
        enum nl80211_iftype iface_type, s32 del, u8 *addr)
 {
        s32 ret;
-       struct wl_interface_create_v2 iface;
+       wl_interface_create_v2_t iface;
        wl_interface_create_v3_t iface_v3;
-       struct wl_interface_info_v1 *info;
+       wl_interface_info_v0_t *info_v0;
+       wl_interface_info_v1_t *info;
        wl_interface_info_v2_t *info_v2;
        enum wl_interface_type iftype;
        uint32 ifflags;
+       bool use_iface_info_v0 = false;
        bool use_iface_info_v2 = false;
        u8 ioctl_buf[WLC_IOCTL_SMLEN];
 
@@ -3727,6 +3858,7 @@ wl_cfg80211_interface_ops(struct bcm_cfg80211 *cfg,
 
        /* Interface create */
        bzero(&iface, sizeof(iface));
+
        /*
         * flags field is still used along with iftype inorder to support the old version of the
         * FW work with the latest app changes.
@@ -3742,38 +3874,55 @@ wl_cfg80211_interface_ops(struct bcm_cfg80211 *cfg,
                ifflags |= WL_INTERFACE_MAC_USE;
        }
 
-       /* Pass ver = 0 for fetching the interface_create iovar version */
-       ret = wldev_iovar_getbuf(ndev, "interface_create",
-               &iface, sizeof(struct wl_interface_create_v2),
-               ioctl_buf, sizeof(ioctl_buf), NULL);
-       if (ret == BCME_UNSUPPORTED) {
-               WL_ERR(("interface_create iovar not supported\n"));
-               return ret;
-       } else if ((ret == 0) && *((uint32 *)ioctl_buf) == WL_INTERFACE_CREATE_VER_3) {
-               WL_DBG(("interface_create version 3\n"));
-               use_iface_info_v2 = true;
-               bzero(&iface_v3, sizeof(wl_interface_create_v3_t));
-               iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
-               iface_v3.iftype = iftype;
-               iface_v3.flags = ifflags;
+       /* BCM4359B0/C0 chips are using the iovar version 0 */
+       if (wl_check_interface_create_v0(cfg)) {
+               wl_interface_create_v0_t iface_v0;
+
+               WL_DBG(("interface_create version 0\n"));
+               bzero(&iface_v0, sizeof(iface_v0));
+               use_iface_info_v0 = true;
+               iface_v0.ver = WL_INTERFACE_CREATE_VER_0;
+               iface_v0.flags = ifflags;
                if (addr) {
-                       memcpy(&iface_v3.mac_addr.octet, addr, ETH_ALEN);
+                       memcpy(&iface_v0.mac_addr.octet, addr, ETH_ALEN);
                }
                ret = wldev_iovar_getbuf(ndev, "interface_create",
-                       &iface_v3, sizeof(wl_interface_create_v3_t),
+                       &iface_v0, sizeof(wl_interface_create_v0_t),
                        ioctl_buf, sizeof(ioctl_buf), NULL);
        } else {
-               /* On any other error, attempt with iovar version 2 */
-               WL_DBG(("interface_create version 2. get_ver:%d\n", ret));
-               iface.ver = WL_INTERFACE_CREATE_VER_2;
-               iface.iftype = iftype;
-               iface.flags = ifflags;
-               if (addr) {
-                       memcpy(&iface.mac_addr.octet, addr, ETH_ALEN);
-               }
+               /* Pass ver = 0 for fetching the interface_create iovar version */
                ret = wldev_iovar_getbuf(ndev, "interface_create",
                        &iface, sizeof(struct wl_interface_create_v2),
                        ioctl_buf, sizeof(ioctl_buf), NULL);
+               if (ret == BCME_UNSUPPORTED) {
+                       WL_ERR(("interface_create iovar not supported\n"));
+                       return ret;
+               } else if ((ret == 0) && *((uint32 *)ioctl_buf) == WL_INTERFACE_CREATE_VER_3) {
+                       WL_DBG(("interface_create version 3\n"));
+                       use_iface_info_v2 = true;
+                       bzero(&iface_v3, sizeof(wl_interface_create_v3_t));
+                       iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
+                       iface_v3.iftype = iftype;
+                       iface_v3.flags = ifflags;
+                       if (addr) {
+                               memcpy(&iface_v3.mac_addr.octet, addr, ETH_ALEN);
+                       }
+                       ret = wldev_iovar_getbuf(ndev, "interface_create",
+                               &iface_v3, sizeof(wl_interface_create_v3_t),
+                               ioctl_buf, sizeof(ioctl_buf), NULL);
+               } else {
+                       /* On any other error, attempt with iovar version 2 */
+                       WL_DBG(("interface_create version 2. get_ver:%d\n", ret));
+                       iface.ver = WL_INTERFACE_CREATE_VER_2;
+                       iface.iftype = iftype;
+                       iface.flags = ifflags;
+                       if (addr) {
+                               memcpy(&iface.mac_addr.octet, addr, ETH_ALEN);
+                       }
+                       ret = wldev_iovar_getbuf(ndev, "interface_create",
+                               &iface, sizeof(struct wl_interface_create_v2),
+                               ioctl_buf, sizeof(ioctl_buf), NULL);
+               }
        }
 
        if (unlikely(ret)) {
@@ -3785,6 +3934,10 @@ wl_cfg80211_interface_ops(struct bcm_cfg80211 *cfg,
        if (use_iface_info_v2 == true) {
                info_v2 = (wl_interface_info_v2_t *)ioctl_buf;
                ret = info_v2->bsscfgidx;
+       } else if (use_iface_info_v0 == true) {
+               /* Use v0 struct */
+               info_v0 = (wl_interface_info_v0_t *)ioctl_buf;
+               ret = info_v0->bsscfgidx;
        } else {
                /* Use v1 struct */
                info = (struct wl_interface_info_v1 *)ioctl_buf;
@@ -3805,7 +3958,7 @@ wl_customer6_legacy_chip_check(struct bcm_cfg80211 *cfg,
 
        /* Get the device rev info */
        memset(&revinfo, 0, sizeof(revinfo));
-       ret = wldev_ioctl(ndev, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE);
+       ret = wldev_ioctl_get(ndev, WLC_GET_REVINFO, &revinfo, sizeof(revinfo));
        if (ret < 0) {
                WL_ERR(("%s: GET revinfo FAILED. ret:%d\n", __FUNCTION__, ret));
                ASSERT(0);
@@ -3828,7 +3981,8 @@ void
 wl_bss_iovar_war(struct bcm_cfg80211 *cfg,
        struct net_device *ndev, s32 *val)
 {
-       if (wl_customer6_legacy_chip_check(cfg, ndev)) {
+       if (wl_customer6_legacy_chip_check(cfg, ndev) ||
+               wl_check_interface_create_v0(cfg)) {
                /* Few firmware branches have issues in bss iovar handling and
                 * that can't be changed since they are in production.
                 */
@@ -4241,6 +4395,12 @@ wl_cfg80211_create_iface(struct wiphy *wiphy,
 #pragma GCC diagnostic pop
 #endif
        }
+
+       /* If any scan is going on, abort it */
+       if (wl_abort_scan_and_check(cfg) != TRUE) {
+               return NULL;
+       }
+
        primary_ndev = bcmcfg_to_prmry_ndev(cfg);
 
        if (likely(!mac_addr)) {
@@ -4256,7 +4416,7 @@ wl_cfg80211_create_iface(struct wiphy *wiphy,
 
        if ((iface_type != NL80211_IFTYPE_STATION) && (iface_type != NL80211_IFTYPE_AP)) {
                WL_ERR(("IFACE type:%d not supported. STA "
-                                       "or AP IFACE is only supported\n", iface_type));
+                       "or AP IFACE is only supported\n", iface_type));
                return NULL;
        }
 
@@ -4507,8 +4667,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        join_params.ssid.SSID_len = htod32(params->ssid_len);
        if (params->bssid) {
                memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN);
-               err = wldev_ioctl(dev, WLC_SET_DESIRED_BSSID, &join_params.params.bssid,
-                       ETHER_ADDR_LEN, true);
+               err = wldev_ioctl_set(dev, WLC_SET_DESIRED_BSSID, &join_params.params.bssid,
+                       ETHER_ADDR_LEN);
                if (unlikely(err)) {
                        WL_ERR(("Error (%d)\n", err));
                        return err;
@@ -4519,8 +4679,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        if (IBSS_INITIAL_SCAN_ALLOWED == FALSE) {
                scan_suppress = TRUE;
                /* Set the SCAN SUPPRESS Flag in the firmware to skip join scan */
-               err = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS,
-                       &scan_suppress, sizeof(int), true);
+               err = wldev_ioctl_set(dev, WLC_SET_SCANSUPPRESS,
+                       &scan_suppress, sizeof(int));
                if (unlikely(err)) {
                        WL_ERR(("Scan Suppress Setting Failed (%d)\n", err));
                        return err;
@@ -4536,8 +4696,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        wldev_iovar_setint(dev, "wpa_auth", WPA_AUTH_DISABLED);
        wldev_iovar_setint(dev, "wsec", 0);
 
-       err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
-               join_params_size, true);
+       err = wldev_ioctl_set(dev, WLC_SET_SSID, &join_params,
+               join_params_size);
        if (unlikely(err)) {
                WL_ERR(("Error (%d)\n", err));
                return err;
@@ -4546,8 +4706,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
        if (IBSS_INITIAL_SCAN_ALLOWED == FALSE) {
                scan_suppress = FALSE;
                /* Reset the SCAN SUPPRESS Flag */
-               err = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS,
-                       &scan_suppress, sizeof(int), true);
+               err = wldev_ioctl_set(dev, WLC_SET_SCANSUPPRESS,
+                       &scan_suppress, sizeof(int));
                if (unlikely(err)) {
                        WL_ERR(("Reset Scan Suppress Flag Failed (%d)\n", err));
                        return err;
@@ -4579,8 +4739,8 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
        wl_set_drv_status(cfg, DISCONNECTING, dev);
        scbval.val = 0;
        memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
-       err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
-               sizeof(scb_val_t), true);
+       err = wldev_ioctl_set(dev, WLC_DISASSOC, &scbval,
+               sizeof(scb_val_t));
        if (unlikely(err)) {
                wl_clr_drv_status(cfg, DISCONNECTING, dev);
                WL_ERR(("error(%d)\n", err));
@@ -4594,7 +4754,7 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 }
 
 #ifdef MFP
-static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa)
+static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8** rsn_cap)
 {
        u16 suite_count;
        wpa_suite_mcast_t *mcast;
@@ -4622,8 +4782,7 @@ static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa)
        if ((suite_count > NL80211_MAX_NR_CIPHER_SUITES) ||
                (len -= (WPA_IE_SUITE_COUNT_LEN +
                (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) {
-               capa[0] = *(u8 *)&mgmt->list[suite_count];
-               capa[1] = *((u8 *)&mgmt->list[suite_count] + 1);
+               rsn_cap[0] = (u8 *)&mgmt->list[suite_count];
        } else
                return BCME_BADLEN;
 
@@ -4905,9 +5064,12 @@ wl_cfg80211_set_mfp(struct bcm_cfg80211 *cfg,
        s32 mfp = WL_MFP_NONE;
        s32 current_mfp = WL_MFP_NONE;
        bcm_tlv_t *wpa2_ie;
-       u8 rsn_cap[2] = {0};
+       u8* rsn_cap = NULL;
        bool fw_support = false;
-       int err;
+       int err, count = 0;
+       u8 *eptr = NULL, *ptr = NULL;
+       u8* group_mgmt_cs = NULL;
+       wpa_pmkid_list_t* pmkid = NULL;
 
        if (!sme) {
                /* No connection params from userspace, Do nothing. */
@@ -4922,18 +5084,39 @@ wl_cfg80211_set_mfp(struct bcm_cfg80211 *cfg,
 
        /* Parse the wpa2ie to decode the MFP capablity */
        if (((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
-               DOT11_MNG_RSN_ID)) != NULL) &&
-               (wl_cfg80211_get_rsn_capa(wpa2_ie, rsn_cap) == 0)) {
-                       /* Check for MFP cap in the RSN capability field */
-                       if (rsn_cap[0] & RSN_CAP_MFPR) {
-                               mfp = WL_MFP_REQUIRED;
-                       } else if (rsn_cap[0] & RSN_CAP_MFPC) {
-                               mfp = WL_MFP_CAPABLE;
+                       DOT11_MNG_RSN_ID)) != NULL) &&
+                       (wl_cfg80211_get_rsn_capa(wpa2_ie, &rsn_cap) == 0) && rsn_cap) {
+               WL_DBG(("rsn_cap 0x%x%x\n", rsn_cap[0], rsn_cap[1]));
+               /* Check for MFP cap in the RSN capability field */
+               if (rsn_cap[0] & RSN_CAP_MFPR) {
+                       mfp = WL_MFP_REQUIRED;
+               } else if (rsn_cap[0] & RSN_CAP_MFPC) {
+                       mfp = WL_MFP_CAPABLE;
+               }
+
+               /*
+                * eptr --> end/last byte addr of wpa2_ie
+                * ptr --> to keep track of current/required byte addr
+                */
+               eptr = (u8*)wpa2_ie + (wpa2_ie->len + TLV_HDR_LEN);
+               /* pointing ptr to the next byte after rns_cap */
+               ptr = (u8*)rsn_cap + RSN_CAP_LEN;
+               if (mfp && (eptr - ptr) >= WPA2_PMKID_COUNT_LEN) {
+                       /* pmkid now to point to 1st byte addr of pmkid in wpa2_ie */
+                       pmkid = (wpa_pmkid_list_t*)ptr;
+                       count = pmkid->count.low | (pmkid->count.high << 8);
+                       /* ptr now to point to last byte addr of pmkid */
+                       ptr = (u8*)pmkid + (count * WPA2_PMKID_LEN
+                               + WPA2_PMKID_COUNT_LEN);
+                       if ((eptr - ptr) >= WPA_SUITE_LEN) {
+                               /* group_mgmt_cs now to point to first byte addr of bip */
+                               group_mgmt_cs = ptr;
                        }
+               }
        }
 
-       WL_DBG((" mfp:%d wpa2_ie ptr:%p rsn_cap 0x%x%x fw mfp support:%d\n",
-               mfp, wpa2_ie, rsn_cap[0], rsn_cap[1], fw_support));
+       WL_DBG((" mfp:%d wpa2_ie ptr:%p rsn_cap %p fw_support:%d\n",
+               mfp, wpa2_ie, rsn_cap, fw_support));
 
        if (fw_support == false) {
                if (mfp) {
@@ -4958,6 +5141,22 @@ wl_cfg80211_set_mfp(struct bcm_cfg80211 *cfg,
                WL_DBG(("mfp set to 0x%x \n", mfp));
        }
 
+       if (group_mgmt_cs && bcmp((const uint8 *)WPA2_OUI,
+                       group_mgmt_cs, (WPA_SUITE_LEN - 1)) == 0) {
+               WL_DBG(("BIP is found\n"));
+               err = wldev_iovar_setbuf(dev, "bip",
+                               group_mgmt_cs, WPA_SUITE_LEN, cfg->ioctl_buf,
+                               WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
+               /*
+                * Dont return failure for unsupported cases
+                * of bip iovar for backward compatibility
+                */
+               if (err != BCME_UNSUPPORTED && err < 0) {
+                       WL_ERR(("bip set error (%d)\n", err));
+                       return err;
+               }
+       }
+
        return 0;
 }
 #endif /* MFP */
@@ -5179,11 +5378,6 @@ static u8 connect_req_bssid[6];
 static u8 broad_bssid[6];
 #endif /* ESCAN_RESULT_PATCH */
 
-
-#ifdef ROAM_CHANNEL_CACHE
-#define MAX_ROAM_CACHE_NUM 100
-#endif /* ROAM_CHANNEL_CACHE */
-
 #if defined(CUSTOM_SET_CPUCORE) || defined(CONFIG_TCPACK_FASTTX)
 static bool wl_get_chan_isvht80(struct net_device *net, dhd_pub_t *dhd)
 {
@@ -5213,8 +5407,8 @@ int wl_cfg80211_cleanup_mismatch_status(struct net_device *dev, struct bcm_cfg80
                scbval.val = DOT11_RC_DISASSOC_LEAVING;
                scbval.val = htod32(scbval.val);
 
-               err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
-                               sizeof(scb_val_t), true);
+               err = wldev_ioctl_set(dev, WLC_DISASSOC, &scbval,
+                               sizeof(scb_val_t));
                if (unlikely(err)) {
                        wl_clr_drv_status(cfg, DISCONNECTING, dev);
                        WL_ERR(("error (%d)\n", err));
@@ -5268,7 +5462,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        struct ether_addr bssid;
        s32 bssidx = -1;
 #ifdef ROAM_CHANNEL_CACHE
-       chanspec_t chanspec_list[MAX_ROAM_CACHE_NUM];
+       chanspec_t chanspec_list[MAX_ROAM_CHANNEL];
 #endif /* ROAM_CHANNEL_CACHE */
 #if (defined(BCM4334_CHIP) || defined(BCM4359_CHIP) || !defined(ESCAN_RESULT_PATCH))
        int wait_cnt;
@@ -5278,7 +5472,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        BCM_REFERENCE(dhdp);
 
 #ifdef ROAM_CHANNEL_CACHE
-       memset(chanspec_list, 0, (sizeof(chanspec_t) * MAX_ROAM_CACHE_NUM));
+       memset(chanspec_list, 0, (sizeof(chanspec_t) * MAX_ROAM_CHANNEL));
 #endif /* ROAM_CHANNEL_CACHE */
 #if defined(SUPPORT_RANDOM_MAC_SCAN)
        wl_cfg80211_set_random_mac(dev, FALSE);
@@ -5366,7 +5560,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                err = wl_cfg80211_cleanup_mismatch_status(dev, cfg, FALSE);
        } else if (!wl_get_drv_status(cfg, CONNECTED, dev)) {
                /* DHD previous status is not connected and FW connected */
-               if (wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false) == 0) {
+               if (wldev_ioctl_get(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN) == 0) {
                        /* set nested connect bit to identify the context */
                        wl_set_drv_status(cfg, NESTED_CONNECT, dev);
                        err = wl_cfg80211_cleanup_mismatch_status(dev, cfg, TRUE);
@@ -5394,6 +5588,12 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                        wl_cfg80211_set_mgmt_vndr_ies(cfg, ndev_to_cfgdev(dev), bssidx,
                                VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
        } else if (dev == bcmcfg_to_prmry_ndev(cfg)) {
+               if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) {
+                       WL_ERR(("Find wlan index from wdev(%p) failed\n", dev->ieee80211_ptr));
+                       err = BCME_ERROR;
+                       goto exit;
+               }
+
                /* find the RSN_IE */
                if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
                        DOT11_MNG_RSN_ID)) != NULL) {
@@ -5422,12 +5622,6 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                                goto exit;
                        }
                }
-
-               if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) {
-                       WL_ERR(("Find p2p index from wdev(%p) failed\n", dev->ieee80211_ptr));
-                       err = BCME_ERROR;
-                       goto exit;
-               }
                err = wl_cfg80211_set_mgmt_vndr_ies(cfg, ndev_to_cfgdev(dev), bssidx,
                        VNDR_IE_ASSOCREQ_FLAG, (const u8 *)sme->ie, sme->ie_len);
                if (unlikely(err)) {
@@ -5439,18 +5633,18 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                bool is_roamtrig_reset = TRUE;
                bool is_roam_env_ok = (wldev_iovar_setint(dev, "roam_env_detection",
                        AP_ENV_DETECT_NOT_USED) == BCME_OK);
-#ifdef CUSTOMER_HW4
+#ifdef KEEP_CUSTOM_ROAM_TRIGGER
                roam_trigger[1] = WLC_BAND_2G;
                is_roamtrig_reset =
-                       (wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
-                       sizeof(roam_trigger), 0) == BCME_OK) &&
+                       (wldev_ioctl_get(dev, WLC_GET_ROAM_TRIGGER, roam_trigger,
+                       sizeof(roam_trigger)) == BCME_OK) &&
                        (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER-10);
-#endif /* CUSTOMER_HW4 */
+#endif /* KEEP_CUSTOM_ROAM_TRIGGER */
                if (is_roamtrig_reset && is_roam_env_ok) {
                        roam_trigger[0] = WL_AUTO_ROAM_TRIGGER;
                        roam_trigger[1] = WLC_BAND_ALL;
-               err = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
-                       sizeof(roam_trigger), true);
+               err = wldev_ioctl_set(dev, WLC_SET_ROAM_TRIGGER, roam_trigger,
+                       sizeof(roam_trigger));
                if (unlikely(err)) {
                                WL_ERR((" failed to restore roam_trigger for auto env"
                                        " detection\n"));
@@ -5488,7 +5682,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                memcpy(ssid.SSID, sme->ssid, sme->ssid_len);
                ssid.SSID_len = sme->ssid_len;
                chan_cnt = get_roam_channel_list(cfg->channel, chanspec_list,
-                       &ssid, ioctl_version);
+                       MAX_ROAM_CHANNEL, &ssid, ioctl_version);
                WL_DBG(("Using roam cache channel set. channel count:%d \n", chan_cnt));
        }
 #endif /* ROAM_CHANNEL_CACHE */
@@ -5616,13 +5810,19 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
                cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync);
 
        if (cfg->rcc_enabled) {
-               WL_ERR(("Connecting with" MACDBG " ssid \"%s\", len (%d) with rcc channels \n\n",
-                       MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)),
+               WL_ERR_KERN(("Connecting with" MACDBG " ssid \"%s\", len (%d) with rcc "
+                       "channels \n\n", MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)),
                        ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len));
+               WL_ERR_MEM(("Connecting with " MACDBG " ssid \"%s\", len (%d) with rcc "
+                       "channels \n\n", MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)),
+                       "*****", ext_join_params->ssid.SSID_len));
        } else {
-               WL_ERR(("Connecting with" MACDBG " ssid \"%s\", len (%d) channel=%d\n\n",
+               WL_ERR_KERN(("Connecting with" MACDBG " ssid \"%s\", len (%d) channel=%d\n\n",
                        MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)),
                        ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len, cfg->channel));
+               WL_ERR_MEM(("Connecting with " MACDBG " ssid \"%s\", len (%d) channel=%d\n\n",
+                       MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)),
+                       "*****", ext_join_params->ssid.SSID_len, cfg->channel));
        }
 
        kfree(ext_join_params);
@@ -5662,7 +5862,7 @@ set_ssid:
                WL_INFORM(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
                        join_params.ssid.SSID_len));
        }
-       err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
+       err = wldev_ioctl_set(dev, WLC_SET_SSID, &join_params, join_params_size);
 exit:
        if (err) {
                WL_ERR(("error (%d)\n", err));
@@ -5745,8 +5945,8 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
                                scbval.val = reason_code;
                                memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
                                scbval.val = htod32(scbval.val);
-                               err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
-                                               sizeof(scb_val_t), true);
+                               err = wldev_ioctl_set(dev, WLC_DISASSOC, &scbval,
+                                               sizeof(scb_val_t));
                                if (unlikely(err)) {
                                        wl_clr_drv_status(cfg, DISCONNECTING, dev);
                                        WL_ERR(("error (%d)\n", err));
@@ -5862,8 +6062,8 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
                /* Just select a new current key */
                index = (u32) key_idx;
                index = htod32(index);
-               err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
-                       sizeof(index), true);
+               err = wldev_ioctl_set(dev, WLC_SET_KEY_PRIMARY, &index,
+                       sizeof(index));
                if (unlikely(err)) {
                        WL_ERR(("error (%d)\n", err));
                }
@@ -6203,7 +6403,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                bcopy(keystring, pmk.key, len);
                pmk.flags = htod16(WSEC_PASSPHRASE);
 
-               err = wldev_ioctl(dev, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk), true);
+               err = wldev_ioctl_set(dev, WLC_SET_WSEC_PMK, &pmk, sizeof(pmk));
                if (err)
                        return err;
        } break;
@@ -6397,11 +6597,13 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 #endif
 {
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
-       scb_val_t scb_val;
        s32 rssi;
        s32 rate;
        s32 err = 0;
        sta_info_t *sta;
+#ifdef SUPPORT_RSSI_SUM_REPORT
+       wl_rssi_ant_mimo_t rssi_ant_mimo;
+#endif /* SUPPORT_RSSI_SUM_REPORT */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) || defined(WL_COMPAT_WIRELESS)
        s8 eabuf[ETHER_ADDR_STR_LEN];
 #endif
@@ -6443,7 +6645,8 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 
                if (cfg->roam_offload) {
                        struct ether_addr bssid;
-                       err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+                       memset(&bssid, 0, sizeof(bssid));
+                       err = wldev_ioctl_get(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN);
                        if (err) {
                                WL_ERR(("Failed to get current BSSID\n"));
                        } else {
@@ -6502,7 +6705,8 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                }
 
                /* Report the current tx rate */
-               err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
+               rate = 0;
+               err = wldev_ioctl_get(dev, WLC_GET_RATE, &rate, sizeof(rate));
                if (err) {
                        WL_ERR(("Could not get rate (%d)\n", err));
                } else {
@@ -6530,15 +6734,29 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
 #endif
                }
 
-               memset(&scb_val, 0, sizeof(scb_val));
-               scb_val.val = 0;
-               err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
-                       sizeof(scb_val_t), false);
-               if (err) {
-                       WL_ERR(("Could not get rssi (%d)\n", err));
+#ifdef SUPPORT_RSSI_SUM_REPORT
+               /* Query RSSI sum across antennas */
+               memset(&rssi_ant_mimo, 0, sizeof(rssi_ant_mimo));
+               err = wl_get_rssi_per_ant(dev, dev->name, NULL, &rssi_ant_mimo);
+               if (err && err != BCME_UNSUPPORTED) {
+                       WL_ERR(("Could not get rssi sum (%d)\n", err));
                        goto get_station_err;
                }
-               rssi = wl_rssi_offset(dtoh32(scb_val.val));
+               rssi = rssi_ant_mimo.rssi_sum;
+               if (rssi == 0)
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+               {
+                       scb_val_t scb_val;
+                       memset(&scb_val, 0, sizeof(scb_val));
+                       scb_val.val = 0;
+                       err = wldev_ioctl_get(dev, WLC_GET_RSSI, &scb_val,
+                               sizeof(scb_val_t));
+                       if (err) {
+                               WL_ERR(("Could not get rssi (%d)\n", err));
+                               goto get_station_err;
+                       }
+                       rssi = wl_rssi_offset(dtoh32(scb_val.val));
+               }
                sinfo->filled |= STA_INFO_BIT(INFO_SIGNAL);
                sinfo->signal = rssi;
                WL_DBG(("RSSI %d dBm\n", rssi));
@@ -6556,15 +6774,16 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                        sinfo->rx_packets = (uint32)dtoh64(if_stats->rxframe);
                        sinfo->rx_dropped_misc = 0;
                        sinfo->tx_packets = (uint32)dtoh64(if_stats->txfrmsnt);
-                       sinfo->tx_failed = (uint32)dtoh64(if_stats->txerror) +
+                       sinfo->tx_failed = (uint32)dtoh64(if_stats->txnobuf) +
+                               (uint32)dtoh64(if_stats->txrunt) +
                                (uint32)dtoh64(if_stats->txfail);
                } else {
                        WL_ERR(("%s: if_counters not supported ret=%d\n",
                                __FUNCTION__, err));
 #endif /* DHD_SUPPORT_IF_CNTS */
 
-                       err = wldev_ioctl(dev, WLC_GET_PKTCNTS, &pktcnt,
-                               sizeof(pktcnt), false);
+                       err = wldev_ioctl_get(dev, WLC_GET_PKTCNTS, &pktcnt,
+                               sizeof(pktcnt));
                        if (err) {
                                WL_ERR(("Could not get WLC_GET_PKTCNTS (%d)\n", err));
                                goto get_station_err;
@@ -6587,7 +6806,7 @@ get_station_err:
                        /* Disconnect due to zero BSSID or error to get RSSI */
                        scb_val_t scbval;
                        scbval.val = htod32(DOT11_RC_DISASSOC_LEAVING);
-                       err = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
+                       err = wldev_ioctl_set(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));
                        if (unlikely(err)) {
                                WL_ERR(("disassoc error (%d)\n", err));
                        }
@@ -6647,7 +6866,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        rtt_status = GET_RTTSTATE(dhd);
        if (rtt_status->status != RTT_ENABLED) {
 #endif /* RTT_SUPPORT */
-       err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
+               err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm));
                if (unlikely(err)) {
                        if (err == -ENODEV)
                                WL_DBG(("net_device is not ready yet\n"));
@@ -6666,7 +6885,7 @@ void wl_cfg80211_update_power_mode(struct net_device *dev)
 {
        int err, pm = -1;
 
-       err = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), true);
+       err = wldev_ioctl_get(dev, WLC_GET_PM, &pm, sizeof(pm));
        if (err)
                WL_ERR(("%s:error (%d)\n", __FUNCTION__, err));
        else if (pm != -1 && dev->ieee80211_ptr)
@@ -7792,6 +8011,10 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
 
        WL_DBG(("Enter \n"));
 
+       if (len > ACTION_FRAME_SIZE) {
+               WL_ERR(("bad length:%zu\n", len));
+               return BCME_BADLEN;
+       }
 #ifdef DHD_IFDEBUG
        PRINT_WDEV_INFO(cfgdev);
 #endif /* DHD_IFDEBUG */
@@ -7862,8 +8085,8 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
                        if (!bcmp((const uint8 *)BSSID_BROADCAST,
                                (const struct ether_addr *)mgmt->da, ETHER_ADDR_LEN)) {
                                assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
-                               err = wldev_ioctl(dev, WLC_GET_ASSOCLIST,
-                                       assoc_maclist, sizeof(mac_buf), false);
+                               err = wldev_ioctl_get(dev, WLC_GET_ASSOCLIST,
+                                       assoc_maclist, sizeof(mac_buf));
                                if (err < 0)
                                        WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err));
                                else
@@ -7871,13 +8094,13 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
                        }
                        memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN);
                        scb_val.val = mgmt->u.disassoc.reason_code;
-                       err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
-                               sizeof(scb_val_t), true);
+                       err = wldev_ioctl_set(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
+                               sizeof(scb_val_t));
                        if (err < 0)
                                WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON error %d\n", err));
-                       WL_ERR(("Disconnect STA : %s scb_val.val %d\n",
-                               bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
-                               scb_val.val));
+                       WL_ERR(("Disconnect STA : " MACDBG " scb_val.val %d\n",
+                               MAC2STRDBG(bcm_ether_ntoa((const struct ether_addr *)mgmt->da,
+                               eabuf)), scb_val.val));
 
                        if (num_associated > 0 && ETHER_ISBCAST(mgmt->da))
                                wl_delay(400);
@@ -8030,6 +8253,7 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
        enum nl80211_channel_type channel_type)
 {
        s32 _chan;
+       u32 _band;
        chanspec_t chspec = 0;
        chanspec_t fw_chspec = 0;
        u32 bw = WL_CHANSPEC_BW_20;
@@ -8051,6 +8275,7 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 
        dev = ndev_to_wlc_ndev(dev, cfg);
        _chan = ieee80211_frequency_to_channel(chan->center_freq);
+       _band = chan->band;
        WL_ERR(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
                dev->ifindex, channel_type, _chan));
 
@@ -8074,24 +8299,23 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 #define DEFAULT_2G_SOFTAP_CHANNEL      1
 #define DEFAULT_5G_SOFTAP_CHANNEL      149
        if (wl_get_mode_by_netdev(cfg, dev) == WL_MODE_AP &&
-               (dhd->op_mode & DHD_FLAG_CONCURR_STA_HOSTAP_MODE) ==
-               DHD_FLAG_CONCURR_STA_HOSTAP_MODE &&
+               DHD_OPMODE_STA_SOFTAP_CONCURR(dhd) &&
                wl_get_drv_status(cfg, CONNECTED, bcmcfg_to_prmry_ndev(cfg))) {
                u32 *sta_chan = (u32 *)wl_read_prof(cfg,
                        bcmcfg_to_prmry_ndev(cfg), WL_PROF_CHAN);
+#ifdef WL_RESTRICTED_APSTA_SCC
+               _chan = *sta_chan;
+#else
                u32 sta_band = (*sta_chan > CH_MAX_2G_CHANNEL) ?
                        IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
                if (chan->band == sta_band) {
-                       /* Do not try SCC in 5GHz if channel is not CH149 */
                        _chan = (sta_band == IEEE80211_BAND_5GHZ &&
                                *sta_chan != DEFAULT_5G_SOFTAP_CHANNEL) ?
                                DEFAULT_2G_SOFTAP_CHANNEL : *sta_chan;
-                       WL_ERR(("target channel will be changed to %d\n", _chan));
-                       if (_chan <= CH_MAX_2G_CHANNEL) {
-                               bw = WL_CHANSPEC_BW_20;
-                               goto set_channel;
-                       }
                }
+#endif /* WL_RESTRICTED_APSTA_SCC */
+               _band = (_chan <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+               WL_ERR(("Target SoftAP channel will be set to %d\n", _chan));
        }
 #undef DEFAULT_2G_SOFTAP_CHANNEL
 #undef DEFAULT_5G_SOFTAP_CHANNEL
@@ -8104,7 +8328,7 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
                goto set_channel;
        }
 #endif /* WL11ULB */
-       if (chan->band == IEEE80211_BAND_5GHZ) {
+       if (_band == IEEE80211_BAND_5GHZ) {
                param.band = WLC_BAND_5G;
                err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
                        cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
@@ -8130,7 +8354,7 @@ wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 
                }
 
-       } else if (chan->band == IEEE80211_BAND_2GHZ)
+       } else if (_band == IEEE80211_BAND_2GHZ)
                bw = WL_CHANSPEC_BW_20;
 set_channel:
        chspec = wf_channel2chspec(_chan, bw);
@@ -8141,8 +8365,8 @@ set_channel:
                                fw_chspec)) == BCME_BADCHAN) {
                                if (bw == WL_CHANSPEC_BW_80)
                                        goto change_bw;
-                               err = wldev_ioctl(dev, WLC_SET_CHANNEL,
-                                       &_chan, sizeof(_chan), true);
+                               err = wldev_ioctl_set(dev, WLC_SET_CHANNEL,
+                                       &_chan, sizeof(_chan));
                                if (err < 0) {
                                        WL_ERR(("WLC_SET_CHANNEL error %d"
                                        "chip may not be supporting this channel\n", err));
@@ -8938,16 +9162,16 @@ static s32 wl_cfg80211_bcn_set_params(
                info->beacon_interval, info->dtim_period));
 
        if (info->beacon_interval) {
-               if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD,
-                       &info->beacon_interval, sizeof(s32), true)) < 0) {
+               if ((err = wldev_ioctl_set(dev, WLC_SET_BCNPRD,
+                       &info->beacon_interval, sizeof(s32))) < 0) {
                        WL_ERR(("Beacon Interval Set Error, %d\n", err));
                        return err;
                }
        }
 
        if (info->dtim_period) {
-               if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
-                       &info->dtim_period, sizeof(s32), true)) < 0) {
+               if ((err = wldev_ioctl_set(dev, WLC_SET_DTIMPRD,
+                       &info->dtim_period, sizeof(s32))) < 0) {
                        WL_ERR(("DTIM Interval Set Error, %d\n", err));
                        return err;
                }
@@ -9048,7 +9272,7 @@ wl_cfg80211_set_ap_role(
                        }
                        if (apsta == 0) {
                                /* If apsta is not set, set it */
-                               err = wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true);
+                               err = wldev_ioctl_set(dev, WLC_DOWN, &ap, sizeof(s32));
                                if (err < 0) {
                                        WL_ERR(("WLC_DOWN error %d\n", err));
                                        return err;
@@ -9058,8 +9282,8 @@ wl_cfg80211_set_ap_role(
                                        WL_ERR(("wl apsta 0 error %d\n", err));
                                        return err;
                                }
-                               if ((err = wldev_ioctl(dev,
-                                       WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
+                               if ((err = wldev_ioctl_set(dev,
+                                       WLC_SET_AP, &ap, sizeof(s32))) < 0) {
                                        WL_ERR(("setting AP mode failed %d \n", err));
                                        return err;
                                }
@@ -9067,12 +9291,12 @@ wl_cfg80211_set_ap_role(
                }
 
                pm = 0;
-               if ((err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true)) != 0) {
+               if ((err = wldev_ioctl_set(dev, WLC_SET_PM, &pm, sizeof(pm))) != 0) {
                        WL_ERR(("wl PM 0 returned error:%d\n", err));
                        /* Ignore error, if any */
                        err = BCME_OK;
                }
-               err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+               err = wldev_ioctl_set(dev, WLC_SET_INFRA, &infra, sizeof(s32));
                if (err < 0) {
                        WL_ERR(("SET INFRA error %d\n", err));
                        return err;
@@ -9126,11 +9350,16 @@ wl_cfg80211_bcn_bringup_ap(
 
        WL_DBG(("Enter dev_role:%d bssidx:%d ifname:%s\n", dev_role, bssidx, dev->name));
 
+       if (wl_check_dongle_idle(bcmcfg_to_wiphy(cfg)) != TRUE) {
+               WL_ERR(("FW is busy to add interface"));
+               return -EINVAL;
+       }
+
        /* Common code for SoftAP and P2P GO */
        wl_clr_drv_status(cfg, AP_CREATED, dev);
 
        /* Make sure INFRA is set for AP/GO */
-       err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+       err = wldev_ioctl_set(dev, WLC_SET_INFRA, &infra, sizeof(s32));
        if (err < 0) {
                WL_ERR(("SET INFRA error %d\n", err));
                goto exit;
@@ -9175,14 +9404,14 @@ wl_cfg80211_bcn_bringup_ap(
 
 #ifdef DISABLE_11H_SOFTAP
                if (is_rsdb_supported == 0) {
-                       err = wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true);
+                       err = wldev_ioctl_set(dev, WLC_DOWN, &ap, sizeof(s32));
                        if (err < 0) {
                                WL_ERR(("WLC_DOWN error %d\n", err));
                                goto exit;
                        }
                }
-               err = wldev_ioctl(dev, WLC_SET_SPECT_MANAGMENT,
-                       &spect, sizeof(s32), true);
+               err = wldev_ioctl_set(dev, WLC_SET_SPECT_MANAGMENT,
+                       &spect, sizeof(s32));
                if (err < 0) {
                        WL_ERR(("SET SPECT_MANAGMENT error %d\n", err));
                        goto exit;
@@ -9197,7 +9426,7 @@ wl_cfg80211_bcn_bringup_ap(
                }
 #endif /* SOFTAP_UAPSD_OFF */
 
-               err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
+               err = wldev_ioctl_set(dev, WLC_UP, &ap, sizeof(s32));
                if (unlikely(err)) {
                        WL_ERR(("WLC_UP error (%d)\n", err));
                        goto exit;
@@ -9270,8 +9499,8 @@ wl_cfg80211_bcn_bringup_ap(
                join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
 
                /* create softap */
-               if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
-                       join_params_size, true)) != 0) {
+               if ((err = wldev_ioctl_set(dev, WLC_SET_SSID, &join_params,
+                       join_params_size)) != 0) {
                        WL_ERR(("SoftAP/GO set ssid failed! \n"));
                        goto exit;
                } else {
@@ -9630,8 +9859,8 @@ wl_cfg80211_del_station(
        }
 
        assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
-       err = wldev_ioctl(ndev, WLC_GET_ASSOCLIST,
-               assoc_maclist, sizeof(mac_buf), false);
+       err = wldev_ioctl_get(ndev, WLC_GET_ASSOCLIST,
+               assoc_maclist, sizeof(mac_buf));
        if (err < 0)
                WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err));
        else
@@ -9646,9 +9875,10 @@ wl_cfg80211_del_station(
        } else {
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
 #endif /* CUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE */
+       dhd_wait_pend8021x(dev);
        scb_val.val = DOT11_RC_DEAUTH_LEAVING;
-       err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
-               sizeof(scb_val_t), true);
+       err = wldev_ioctl_set(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
+               sizeof(scb_val_t));
        if (err < 0)
                WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON err %d\n", err));
 #ifdef CUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE
@@ -9656,9 +9886,9 @@ wl_cfg80211_del_station(
        }
 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
 #endif /* CUSTOM_BLOCK_DEAUTH_AT_EAP_FAILURE */
-       WL_ERR(("Disconnect STA : %s scb_val.val %d\n",
-               bcm_ether_ntoa((const struct ether_addr *)mac_addr, eabuf),
-               scb_val.val));
+       WL_ERR(("Disconnect STA : " MACDBG " scb_val.val %d\n",
+               MAC2STRDBG(bcm_ether_ntoa((const struct ether_addr *)mac_addr,
+               eabuf)), scb_val.val));
 
        if (num_associated > 0 && ETHER_ISBCAST(mac_addr))
                wl_delay(400);
@@ -9699,9 +9929,9 @@ wl_cfg80211_change_station(
 
        if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))) {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
-               err = wldev_ioctl(dev, WLC_SCB_DEAUTHORIZE, (u8 *)mac, ETH_ALEN, true);
+               err = wldev_ioctl_set(dev, WLC_SCB_DEAUTHORIZE, (u8 *)mac, ETH_ALEN);
 #else
-               err = wldev_ioctl(dev, WLC_SCB_DEAUTHORIZE, mac, ETH_ALEN, true);
+               err = wldev_ioctl_set(dev, WLC_SCB_DEAUTHORIZE, mac, ETH_ALEN);
 #endif
                if (err)
                        WL_ERR(("WLC_SCB_DEAUTHORIZE error (%d)\n", err));
@@ -9709,9 +9939,9 @@ wl_cfg80211_change_station(
        }
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
-       err = wldev_ioctl(dev, WLC_SCB_AUTHORIZE, (u8 *)mac, ETH_ALEN, true);
+       err = wldev_ioctl_set(dev, WLC_SCB_AUTHORIZE, (u8 *)mac, ETH_ALEN);
 #else
-       err = wldev_ioctl(dev, WLC_SCB_AUTHORIZE, mac, ETH_ALEN, true);
+       err = wldev_ioctl_set(dev, WLC_SCB_AUTHORIZE, mac, ETH_ALEN);
 #endif
        if (err)
                WL_ERR(("WLC_SCB_AUTHORIZE error (%d)\n", err));
@@ -9730,6 +9960,7 @@ wl_cfg80211_set_scb_timings(
        int err;
        u32 ps_pretend;
        wl_scb_probe_t scb_probe;
+       u32 ps_pretend_retries;
 
        bzero(&scb_probe, sizeof(wl_scb_probe_t));
        scb_probe.scb_timeout = WL_SCB_TIMEOUT;
@@ -9743,6 +9974,20 @@ wl_cfg80211_set_scb_timings(
                return err;
        }
 
+       ps_pretend_retries = WL_PSPRETEND_RETRY_LIMIT;
+       err = wldev_iovar_setint(dev, "pspretend_retry_limit", ps_pretend_retries);
+       if (unlikely(err)) {
+               if (err == BCME_UNSUPPORTED) {
+                       /* Ignore error if fw doesn't support the iovar */
+                       WL_DBG(("set 'pspretend_retry_limit %d' failed, error = %d\n",
+                               ps_pretend_retries, err));
+               } else {
+                       WL_ERR(("set 'pspretend_retry_limit %d' failed, error = %d\n",
+                               ps_pretend_retries, err));
+                       return err;
+               }
+       }
+
        ps_pretend = MAX(WL_SCB_MAX_PROBE / 2, WL_MIN_PSPRETEND_THRESHOLD);
        err = wldev_iovar_setint(dev, "pspretend_threshold", ps_pretend);
        if (unlikely(err)) {
@@ -9809,6 +10054,9 @@ wl_cfg80211_start_ap(
                        dhd_arp_offload_enable(dhd, FALSE);
                }
 #endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef SUPPORT_SET_CAC
+               wl_cfg80211_set_cac(cfg, 0);
+#endif /* SUPPORT_SET_CAC */
        } else {
                /* only AP or GO role need to be handled here. */
                err = -EINVAL;
@@ -9942,14 +10190,13 @@ wl_cfg80211_stop_ap(
        int ap = 0;
        s32 bssidx = 0;
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
-       s32 is_rsdb_supported = BCME_ERROR;
        dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
 
        WL_DBG(("Enter \n"));
 
-       is_rsdb_supported = DHD_OPMODE_SUPPORTED(cfg->pub, DHD_FLAG_RSDB_MODE);
-       if (is_rsdb_supported < 0)
+       if (!dhd) {
                return (-ENODEV);
+       }
 
        wl_clr_drv_status(cfg, AP_CREATING, dev);
        wl_clr_drv_status(cfg, AP_CREATED, dev);
@@ -9999,9 +10246,11 @@ wl_cfg80211_stop_ap(
                }
 #endif /* ARP_OFFLOAD_SUPPORT */
 
-               if (is_rsdb_supported == 0) {
-                       /* For non-rsdb chips, we use stand alone AP. Do wl down on stop AP */
-                       err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
+               if (!DHD_OPMODE_STA_SOFTAP_CONCURR(dhd)) {
+                       /* For non-STA/SoftAP Concurrent mode,
+                        * we use stand alone AP. Do wl down on stop AP
+                        */
+                       err = wldev_ioctl_set(dev, WLC_UP, &ap, sizeof(s32));
                        if (unlikely(err)) {
                                WL_ERR(("WLC_UP error (%d)\n", err));
                                err = -EINVAL;
@@ -10016,12 +10265,9 @@ wl_cfg80211_stop_ap(
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
        } else {
                WL_DBG(("Stopping P2P GO \n"));
-               DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE((dhd_pub_t *)(cfg->pub),
-                       DHD_EVENT_TIMEOUT_MS*3);
-               DHD_OS_WAKE_LOCK_TIMEOUT((dhd_pub_t *)(cfg->pub));
+               DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS*3);
+               DHD_OS_WAKE_LOCK_TIMEOUT(dhd);
        }
-
-
 exit:
 #ifdef WLTDLS
        if (bssidx == 0) {
@@ -10034,6 +10280,9 @@ exit:
                /* clear the AP mode */
                dhd->op_mode &= ~DHD_FLAG_HOSTAP_MODE;
        }
+#ifdef SUPPORT_SET_CAC
+       wl_cfg80211_set_cac(cfg, 1);
+#endif /* SUPPORT_SET_CAC */
        return err;
 }
 
@@ -10226,15 +10475,15 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 
        /* Set BI and DTIM period */
        if (info->interval) {
-               if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD,
-                       &info->interval, sizeof(s32), true)) < 0) {
+               if ((err = wldev_ioctl_set(dev, WLC_SET_BCNPRD,
+                       &info->interval, sizeof(s32))) < 0) {
                        WL_ERR(("Beacon Interval Set Error, %d\n", err));
                        return err;
                }
        }
        if (info->dtim_period) {
-               if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
-                       &info->dtim_period, sizeof(s32), true)) < 0) {
+               if ((err = wldev_ioctl_set(dev, WLC_SET_DTIMPRD,
+                       &info->dtim_period, sizeof(s32))) < 0) {
                        WL_ERR(("DTIM Interval Set Error, %d\n", err));
                        return err;
                }
@@ -10326,7 +10575,7 @@ wl_cfg80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
        }
 
        /* fall through is intentional */
-       err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
+       err = wldev_ioctl_set(dev, WLC_SET_INFRA, &infra, sizeof(s32));
        if (err < 0) {
                WL_ERR(("SET INFRA error %d\n", err));
        }
@@ -10654,7 +10903,7 @@ static int wl_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
        if (!idx) {
                /* Set interface up, explicitly. */
                val = 1;
-               err = wldev_ioctl(ndev, WLC_UP, (void *)&val, sizeof(val), true);
+               err = wldev_ioctl_set(ndev, WLC_UP, (void *)&val, sizeof(val));
                if (err < 0) {
                        WL_ERR(("set interface up failed, error = %d\n", err));
                }
@@ -10663,8 +10912,9 @@ static int wl_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
        /* Get noise value */
        retry = IOCTL_RETRY_COUNT;
        while (retry--) {
-               err = wldev_ioctl(ndev, WLC_GET_PHY_NOISE, &noise,
-                       sizeof(noise), false);
+               noise = 0;
+               err = wldev_ioctl_get(ndev, WLC_GET_PHY_NOISE, &noise,
+                       sizeof(noise));
                if (err >=  0) {
                        break;
                }
@@ -10787,9 +11037,11 @@ static struct cfg80211_ops wl_cfg80211_ops = {
 #ifdef WL_CFG80211_ACL
        .set_mac_acl = wl_cfg80211_set_mac_acl,
 #endif /* WL_CFG80211_ACL */
+#ifdef GTK_OFFLOAD_SUPPORT
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
        .set_rekey_data = wl_cfg80211_set_rekey_data,
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) */
+#endif /* GTK_OFFLOAD_SUPPORT */
 };
 
 s32 wl_mode_to_nl80211_iftype(s32 mode)
@@ -11072,15 +11324,18 @@ static s32 wl_inform_bss(struct bcm_cfg80211 *cfg)
 #ifdef ROAM_CHANNEL_CACHE
        reset_roam_cache(cfg);
 #endif /* ROAM_CHANNEL_CACHE */
+       preempt_disable();
        bi = next_bss(bss_list, bi);
        for_each_bss(bss_list, bi, i) {
 #ifdef ROAM_CHANNEL_CACHE
                add_roam_cache(cfg, bi);
 #endif /* ROAM_CHANNEL_CACHE */
                err = wl_inform_single_bss(cfg, bi, false);
-               if (unlikely(err))
-                       break;
+               if (unlikely(err)) {
+                       WL_ERR(("bss inform failed\n"));
+               }
        }
+       preempt_enable();
 #ifdef ROAM_CHANNEL_CACHE
        /* print_roam_cache(); */
        update_roam_cache(cfg, ioctl_version);
@@ -11195,7 +11450,8 @@ static s32 wl_inform_single_bss(struct bcm_cfg80211 *cfg, struct wl_bss_info *bi
        cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
                le16_to_cpu(notif_bss_info->frame_len), signal, aflags);
        if (unlikely(!cbss)) {
-               WL_ERR(("cfg80211_inform_bss_frame error\n"));
+               WL_ERR(("cfg80211_inform_bss_frame error bssid " MACDBG " channel %d \n",
+                       MAC2STRDBG((u8*)(&bi->BSSID)), notif_bss_info->channel));
                err = -EINVAL;
                goto out_err;
        }
@@ -11310,6 +11566,41 @@ static bool wl_is_linkup(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e, stru
        return false;
 }
 
+#ifdef WL_LASTEVT
+static bool wl_is_linkdown(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e, void *data)
+{
+       u32 event = ntoh32(e->event_type);
+       u16 flags = ntoh16(e->flags);
+       wl_last_event_t *last_event = (wl_last_event_t *)data;
+       u32 len = ntoh32(e->datalen);
+
+       if (event == WLC_E_DEAUTH_IND ||
+       event == WLC_E_DISASSOC_IND ||
+       event == WLC_E_DISASSOC ||
+       event == WLC_E_DEAUTH) {
+               WL_ERR(("Link down Reason : %s\n", bcmevent_get_name(event)));
+               return true;
+       } else if (event == WLC_E_LINK) {
+               if (!(flags & WLC_EVENT_MSG_LINK)) {
+                       if (last_event && len > 0) {
+                               u32 current_time = last_event->current_time;
+                               u32 timestamp = last_event->timestamp;
+                               u32 event_type = last_event->event.event_type;
+                               u32 status = last_event->event.status;
+                               u32 reason = last_event->event.reason;
+
+                               WL_ERR(("Last roam event before disconnection : current_time %d,"
+                                       " time %d, type %d, status %d, reason %d\n",
+                                       current_time, timestamp, event_type, status, reason));
+                       }
+                       WL_ERR(("Link down Reason : %s\n", bcmevent_get_name(event)));
+                       return true;
+               }
+       }
+
+       return false;
+}
+#else
 static bool wl_is_linkdown(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e)
 {
        u32 event = ntoh32(e->event_type);
@@ -11319,21 +11610,18 @@ static bool wl_is_linkdown(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e)
        event == WLC_E_DISASSOC_IND ||
        event == WLC_E_DISASSOC ||
        event == WLC_E_DEAUTH) {
-#if (WL_DBG_LEVEL > 0)
-       WL_ERR(("Link down Reason : WLC_E_%s\n", wl_dbg_estr[event]));
-#endif /* (WL_DBG_LEVEL > 0) */
+               WL_ERR(("Link down Reason : %s\n", bcmevent_get_name(event)));
                return true;
        } else if (event == WLC_E_LINK) {
                if (!(flags & WLC_EVENT_MSG_LINK)) {
-#if (WL_DBG_LEVEL > 0)
-       WL_ERR(("Link down Reason : WLC_E_%s\n", wl_dbg_estr[event]));
-#endif /* (WL_DBG_LEVEL > 0) */
+                       WL_ERR(("Link down Reason : %s\n", bcmevent_get_name(event)));
                        return true;
                }
        }
 
        return false;
 }
+#endif /* WL_LASTEVT */
 
 static bool wl_is_nonetwork(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e)
 {
@@ -11436,7 +11724,8 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
                NULL, 0, cfg->ioctl_buf, WLC_IOCTL_SMLEN, bsscfgidx, &cfg->ioctl_buf_sync);
        memcpy(da.octet, cfg->ioctl_buf, ETHER_ADDR_LEN);
-       err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+       memset(&bssid, 0, sizeof(bssid));
+       err = wldev_ioctl_get(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN);
        switch (event) {
                case WLC_E_ASSOC_IND:
                        fc = FC_ASSOC_REQ;
@@ -11457,7 +11746,8 @@ wl_notify_connect_status_ap(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                        fc = 0;
                        goto exit;
        }
-       if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false))) {
+       memset(&ci, 0, sizeof(ci));
+       if ((err = wldev_ioctl_get(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci)))) {
                kfree(body);
                return err;
        }
@@ -11525,7 +11815,8 @@ exit:
                cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
        } else if (event == WLC_E_DISASSOC_IND) {
                cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
-       } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+       } else if ((event == WLC_E_DEAUTH_IND) ||
+               ((event == WLC_E_DEAUTH) && (reason != DOT11_RC_RESERVED))) {
                cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
        }
 #endif /* LINUX_VERSION < VERSION(3,2,0) && !WL_CFG80211_STA_EVENT && !WL_COMPAT_WIRELESS */
@@ -11533,14 +11824,23 @@ exit:
 }
 
 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
-#define MAX_ASSOC_REJECT_ERR_STATUS 5
+enum {
+       BIGDATA_ASSOC_REJECT_NO_ACK = 1,
+       BIGDATA_ASSOC_REJECT_FAIL = 2,
+       BIGDATA_ASSOC_REJECT_UNSOLICITED = 3,
+       BIGDATA_ASSOC_REJECT_TIMEOUT = 4,
+       BIGDATA_ASSOC_REJECT_ABORT = 5,
+       BIGDATA_ASSOC_REJECT_NO_NETWWORKS = 6,
+       BIGDATA_ASSOC_REJECT_MAX = 50
+};
+
 int wl_get_connect_failed_status(struct bcm_cfg80211 *cfg, const wl_event_msg_t *e)
 {
        u32 status = ntoh32(e->status);
 
        cfg->assoc_reject_status = 0;
 
-       if (status == WLC_E_STATUS_FAIL) {
+       if (status != WLC_E_STATUS_SUCCESS) {
                WL_ERR(("auth assoc status event=%d e->status %d e->reason %d \n",
                        ntoh32(cfg->event_auth_assoc.event_type),
                        (int)ntoh32(cfg->event_auth_assoc.status),
@@ -11548,26 +11848,33 @@ int wl_get_connect_failed_status(struct bcm_cfg80211 *cfg, const wl_event_msg_t
 
                switch ((int)ntoh32(cfg->event_auth_assoc.status)) {
                        case WLC_E_STATUS_NO_ACK:
-                               cfg->assoc_reject_status = 1;
+                               cfg->assoc_reject_status = BIGDATA_ASSOC_REJECT_NO_ACK;
                                break;
                        case WLC_E_STATUS_FAIL:
-                               cfg->assoc_reject_status = 2;
+                               cfg->assoc_reject_status = BIGDATA_ASSOC_REJECT_FAIL;
                                break;
                        case WLC_E_STATUS_UNSOLICITED:
-                               cfg->assoc_reject_status = 3;
+                               cfg->assoc_reject_status = BIGDATA_ASSOC_REJECT_UNSOLICITED;
                                break;
                        case WLC_E_STATUS_TIMEOUT:
-                               cfg->assoc_reject_status = 4;
+                               cfg->assoc_reject_status = BIGDATA_ASSOC_REJECT_TIMEOUT;
                                break;
                        case WLC_E_STATUS_ABORT:
-                               cfg->assoc_reject_status = 5;
+                               cfg->assoc_reject_status = BIGDATA_ASSOC_REJECT_ABORT;
                                break;
+                       case WLC_E_STATUS_SUCCESS:
+                               if (status == WLC_E_STATUS_NO_NETWORKS) {
+                                       cfg->assoc_reject_status =
+                                               BIGDATA_ASSOC_REJECT_NO_NETWWORKS;
+                                       break;
+                               }
                        default:
+                               cfg->assoc_reject_status = BIGDATA_ASSOC_REJECT_MAX;
                                break;
                }
                if (cfg->assoc_reject_status) {
                        if (ntoh32(cfg->event_auth_assoc.event_type) == WLC_E_ASSOC) {
-                               cfg->assoc_reject_status += MAX_ASSOC_REJECT_ERR_STATUS;
+                               cfg->assoc_reject_status += BIGDATA_ASSOC_REJECT_MAX;
                        }
                }
        }
@@ -11715,6 +12022,95 @@ wl_notify_connect_status_ibss(struct bcm_cfg80211 *cfg, struct net_device *ndev,
 #define WiFiALL_OUI_LEN     3
 #define WiFiALL_OUI_TYPE    16
 
+/* 11kv feature flag for big data */
+#define WL_BIGDATA_11KV_QBSSLOAD               0x00000001
+#define WL_BIGDATA_11KV_PROXYARP               0x00000002
+#define WL_BIGDATA_11KV_TFS                    0x00000004
+#define WL_BIGDATA_11KV_SLEEP                  0x00000008
+#define WL_BIGDATA_11KV_TIMBC                  0x00000010
+#define WL_BIGDATA_11KV_BSSTRANS               0x00000020
+#define WL_BIGDATA_11KV_DMS                    0x00000040
+#define WL_BIGDATA_11KV_LINK_MEA               0x00000080
+#define WL_BIGDATA_11KV_NBRREP                 0x00000100
+#define WL_BIGDATA_11KV_BCNPASSIVE             0x00000200
+#define WL_BIGDATA_11KV_BCNACTIVE              0x00000400
+#define WL_BIGDATA_11KV_BCNTABLE               0x00000800
+#define WL_BIGDATA_11KV_BSSAAD                 0x00001000
+#define WL_BIGDATA_11KV_MAX                    0x00002000
+
+#define WL_BIGDATA_SUPPORT_11K         0x00000001
+#define WL_BIGDATA_SUPPORT_11V         0x00000002
+
+typedef struct {
+       uint8   bitmap;
+       uint8   octet_len;
+       uint32  flag;
+} bigdata_11kv_t;
+
+bigdata_11kv_t bigdata_11k_info[] = {
+       {DOT11_RRM_CAP_LINK, DOT11_RRM_CAP_LEN, WL_BIGDATA_11KV_LINK_MEA},
+       {DOT11_RRM_CAP_NEIGHBOR_REPORT, DOT11_RRM_CAP_LEN, WL_BIGDATA_11KV_NBRREP},
+       {DOT11_RRM_CAP_BCN_PASSIVE, DOT11_RRM_CAP_LEN, WL_BIGDATA_11KV_BCNPASSIVE},
+       {DOT11_RRM_CAP_BCN_ACTIVE, DOT11_RRM_CAP_LEN, WL_BIGDATA_11KV_BCNACTIVE},
+       {DOT11_RRM_CAP_BCN_TABLE, DOT11_RRM_CAP_LEN, WL_BIGDATA_11KV_BCNTABLE},
+       {DOT11_RRM_CAP_BSSAAD, DOT11_RRM_CAP_LEN, WL_BIGDATA_11KV_BSSAAD},
+};
+
+bigdata_11kv_t bigdata_11v_info[] = {
+       {DOT11_EXT_CAP_PROXY_ARP, DOT11_EXTCAP_LEN_PROXY_ARP, WL_BIGDATA_11KV_PROXYARP},
+       {DOT11_EXT_CAP_TFS, DOT11_EXTCAP_LEN_TFS, WL_BIGDATA_11KV_TFS},
+       {DOT11_EXT_CAP_WNM_SLEEP, DOT11_EXTCAP_LEN_WNM_SLEEP, WL_BIGDATA_11KV_SLEEP},
+       {DOT11_EXT_CAP_TIMBC, DOT11_EXTCAP_LEN_TIMBC, WL_BIGDATA_11KV_TIMBC},
+       {DOT11_EXT_CAP_BSSTRANS_MGMT, DOT11_EXTCAP_LEN_BSSTRANS, WL_BIGDATA_11KV_BSSTRANS},
+       {DOT11_EXT_CAP_DMS, DOT11_EXTCAP_LEN_DMS, WL_BIGDATA_11KV_DMS}
+};
+
+static void
+wl_get_11kv_info(u8 *ie, u32 ie_len, uint8 *support_11kv, uint32 *flag_11kv)
+{
+       bcm_tlv_t *ie_11kv = NULL;
+       uint32 flag_11k = 0, flag_11v = 0;
+       int i;
+
+       /* parsing QBSS load ie */
+       if ((bcm_parse_tlvs(ie, (u32)ie_len,
+                       DOT11_MNG_QBSS_LOAD_ID)) != NULL) {
+               flag_11k |= WL_BIGDATA_11KV_QBSSLOAD;
+       }
+
+       /* parsing RM IE for 11k */
+       if ((ie_11kv = bcm_parse_tlvs(ie, (u32)ie_len,
+                       DOT11_MNG_RRM_CAP_ID)) != NULL) {
+               for (i = 0; i < ARRAYSIZE(bigdata_11k_info); i++) {
+                       if ((ie_11kv->len >= bigdata_11k_info[i].octet_len) &&
+                                       isset(ie_11kv->data, bigdata_11k_info[i].bitmap)) {
+                               flag_11k |= bigdata_11k_info[i].flag;
+                       }
+               }
+       }
+
+       /* parsing extended cap. IE for 11v */
+       if ((ie_11kv = bcm_parse_tlvs(ie, (u32)ie_len,
+                       DOT11_MNG_EXT_CAP_ID)) != NULL) {
+               for (i = 0; i < ARRAYSIZE(bigdata_11v_info); i++) {
+                       if ((ie_11kv->len >= bigdata_11v_info[i].octet_len) &&
+                                       isset(ie_11kv->data, bigdata_11v_info[i].bitmap)) {
+                               flag_11v |= bigdata_11v_info[i].flag;
+                       }
+               }
+       }
+
+       if (flag_11k > 0) {
+               *support_11kv |= WL_BIGDATA_SUPPORT_11K;
+       }
+
+       if (flag_11v > 0) {
+               *support_11kv |= WL_BIGDATA_SUPPORT_11V;
+       }
+
+       *flag_11kv = flag_11k | flag_11v;
+}
+
 int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, uint8 *mac)
 {
        s32 err = 0;
@@ -11734,14 +12130,17 @@ int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, uint8 *mac
        u32 i, remained_len, count = 0;
        char roam_count_str[4], akm_str[4];
        s32 val = 0;
+       uint8 support_11kv = 0;
+       uint32 flag_11kv = 0;   /* bit flags of 11kv big data */
 
        /* get BSS information */
 
-       strncpy(cfg->bss_info, "x x x x x x x x x x x x x", GET_BSS_INFO_LEN);
+       strncpy(cfg->bss_info, "x x x x x x x x x x x x x x x", GET_BSS_INFO_LEN);
 
+       memset(cfg->extra_buf, 0, WL_EXTRA_BUF_MAX);
        *(u32 *) cfg->extra_buf = htod32(WL_EXTRA_BUF_MAX);
 
-       err = wldev_ioctl(dev, WLC_GET_BSS_INFO, cfg->extra_buf, WL_EXTRA_BUF_MAX, false);
+       err = wldev_ioctl_get(dev, WLC_GET_BSS_INFO, cfg->extra_buf, WL_EXTRA_BUF_MAX);
        if (unlikely(err)) {
                WL_ERR(("Could not get bss info %d\n", err));
                cfg->roam_count = 0;
@@ -11768,8 +12167,8 @@ int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, uint8 *mac
                freq = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
        }
 #endif
-
-       err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
+       rate = 0;
+       err = wldev_ioctl_get(dev, WLC_GET_RATE, &rate, sizeof(rate));
        if (err) {
                WL_ERR(("Could not get rate (%d)\n", err));
                snprintf(rate_str, sizeof(rate_str), "x"); // Unknown
@@ -11884,6 +12283,9 @@ int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, uint8 *mac
                                }
                        }
                }
+
+               /* get 11kv information from ie of current bss */
+               wl_get_11kv_info(ie, ie_len, &support_11kv, &flag_11kv);
        }
 
        for (i = 0; i < bi->SSID_len; i++) {
@@ -11920,31 +12322,29 @@ int wl_get_bss_info(struct bcm_cfg80211 *cfg, struct net_device *dev, uint8 *mac
        }
        cfg->roam_count = 0;
 
-       WL_ERR(("BSSID:" MACDBG " SSID %s \n", MAC2STRDBG(eabuf), bi->SSID));
+       WL_ERR(("BSSID:" MACDBG " SSID %s \n", MAC2STRDBG(eabuf), "*****"));
        WL_ERR(("freq:%d, BW:%s, RSSI:%d dBm, Rate:%d Mbps, 11mode:%d, stream:%d,"
                                "MU-MIMO:%d, Passpoint:%d, SNR:%d, Noise:%d, \n"
-                               "akm:%s roam:%s \n",
+                               "akm:%s, roam:%s, 11kv:%d/%d \n",
                                freq, wf_chspec_to_bw_str(bi->chanspec),
                                dtoh32(bi->RSSI), (rate / 2), mode_80211, nss,
                                ie_mu_mimo_cap, ie_11u_rel_num, bi->SNR, bi->phy_noise,
-                               akm_str, roam_count_str));
+                               akm_str, roam_count_str, support_11kv, flag_11kv));
 
        if (ie) {
                snprintf(cfg->bss_info, GET_BSS_INFO_LEN,
-                               "%02x:%02x:%02x %d %s %d %s %d %d %d %d %d %d %s %s",
-                               eabuf[0], eabuf[1], eabuf[2],
-                               freq, wf_chspec_to_bw_str(bi->chanspec),
-                               dtoh32(bi->RSSI), rate_str, mode_80211, nss,
-                               ie_mu_mimo_cap, ie_11u_rel_num,
-                               bi->SNR, bi->phy_noise, akm_str, roam_count_str);
+                               MACOUI" %d %s %d %s %d %d %d %d %d %d %s %s %d %d",
+                               MACOUI2STR(eabuf), freq, wf_chspec_to_bw_str(bi->chanspec),
+                               dtoh32(bi->RSSI), rate_str, mode_80211, nss, ie_mu_mimo_cap,
+                               ie_11u_rel_num, bi->SNR, bi->phy_noise, akm_str, roam_count_str,
+                               support_11kv, flag_11kv);
        } else {
                //ie_mu_mimo_cap and ie_11u_rel_num is unknow.
                snprintf(cfg->bss_info, GET_BSS_INFO_LEN,
-                               "%02x:%02x:%02x %d %s %d %s %d %d x x %d %d %s %s",
-                               eabuf[0], eabuf[1], eabuf[2],
-                               freq, wf_chspec_to_bw_str(bi->chanspec),
-                               dtoh32(bi->RSSI), rate_str, mode_80211, nss,
-                               bi->SNR, bi->phy_noise, akm_str, roam_count_str);
+                               MACOUI" %d %s %d %s %d %d x x %d %d %s %s x x",
+                               MACOUI2STR(eabuf), freq, wf_chspec_to_bw_str(bi->chanspec),
+                               dtoh32(bi->RSSI), rate_str, mode_80211, nss, bi->SNR,
+                               bi->phy_noise, akm_str, roam_count_str);
        }
 
        CFG80211_PUT_BSS(wiphy, bss);
@@ -11963,7 +12363,7 @@ s32 wl_cfg80211_get_bss_info(struct net_device *dev, char* cmd, int total_len)
        memset(cmd, 0, total_len);
        memcpy(cmd, cfg->bss_info, GET_BSS_INFO_LEN);
 
-       WL_ERR(("cmd: %s \n", cmd));
+       WL_ERR_KERN(("cmd: %s \n", cmd));
 
        return GET_BSS_INFO_LEN;
 }
@@ -11989,6 +12389,9 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 #ifdef DHD_PM_CONTROL_FROM_FILE
        int scan_suppress;
 #endif /* DHD_PM_CONTROL_FROM_FILE */
+       int vndr_oui_num = 0;
+       char vndr_oui[MAX_VNDR_OUI_STR_LEN] = {0, };
+       bool loc_gen = false;
 
        ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
        dhdp = (dhd_pub_t *)(cfg->pub);
@@ -12010,49 +12413,61 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                        wl_link_up(cfg);
                        act = true;
                        if (!wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
-                                       if (event == WLC_E_LINK &&
+                               if (event == WLC_E_LINK &&
 #ifdef DHD_LOSSLESS_ROAMING
-                                               !cfg->roam_offload &&
+                                       !cfg->roam_offload &&
 #endif /* DHD_LOSSLESS_ROAMING */
-                                                       wl_get_drv_status(cfg, CONNECTED, ndev)) {
+                                       wl_get_drv_status(cfg, CONNECTED, ndev)) {
                                        wl_bss_roaming_done(cfg, ndev, e, data);
-                                       }
-                                       WL_ERR(("wl_bss_connect_done succeeded with " MACDBG "\n",
-                                               MAC2STRDBG((const u8*)(&e->addr))));
-                                       wl_bss_connect_done(cfg, ndev, e, data, true);
-                                       WL_DBG(("joined in BSS network \"%s\"\n",
+                               }
+
+                               wl_bss_connect_done(cfg, ndev, e, data, true);
+                               if (ndev == bcmcfg_to_prmry_ndev(cfg)) {
+                                       vndr_oui_num = wl_vndr_ies_get_vendor_oui(cfg,
+                                               ndev, vndr_oui, ARRAYSIZE(vndr_oui));
+#if defined(STAT_REPORT)
+                                       /* notify STA connection only */
+                                       wl_stat_report_notify_connected(cfg);
+#endif /* STAT_REPORT */
+                               }
+
+                               WL_ERR(("wl_bss_connect_done succeeded with "
+                                       MACDBG " %s%s\n", MAC2STRDBG((const u8*)(&e->addr)),
+                                       vndr_oui_num > 0 ? "vndr_oui: " : "",
+                                       vndr_oui_num > 0 ? vndr_oui : ""));
+                               WL_DBG(("joined in BSS network \"%s\"\n",
                                        ((struct wlc_ssid *)
                                         wl_read_prof(cfg, ndev, WL_PROF_SSID))->SSID));
 #ifdef DHD_PM_CONTROL_FROM_FILE
-                                       if (g_pm_control) {
-                                               /* connected done...scansuppress on */
-                                               scan_suppress = TRUE;
-                                               err = wldev_ioctl(ndev, WLC_SET_SCANSUPPRESS,
-                                                       &scan_suppress, sizeof(int), true);
-                                               if (unlikely(err)) {
-                                                       WL_ERR(("Scan Suppress TRUE Set"
-                                                               " Failed (%d)\n", err));
-                                                       err = 0;
-                                               }
-                                               WL_ERR(("[WIFI_SEC] Enable Scan Suppress on"
-                                                       " RF mode\n"));
+                               if (g_pm_control) {
+                                       /* connected done...scansuppress on */
+                                       scan_suppress = TRUE;
+                                       err = wldev_ioctl_set(ndev, WLC_SET_SCANSUPPRESS,
+                                               &scan_suppress, sizeof(int));
+                                       if (unlikely(err)) {
+                                               WL_ERR(("Scan Suppress TRUE Set"
+                                                       " Failed (%d)\n", err));
+                                               err = 0;
                                        }
+                                       WL_ERR(("[WIFI_SEC] Enable Scan Suppress on"
+                                               " RF mode\n"));
+                               }
 #endif /* DHD_PM_CONTROL_FROM_FILE */
 
 #ifdef WBTEXT
-                                       if (ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION &&
-                                                       dhdp->wbtext_support &&
-                                                       event == WLC_E_SET_SSID) {
-                                               /* set wnm_keepalives_max_idle after association */
-                                               wl_cfg80211_wbtext_set_wnm_maxidle(cfg, ndev);
-                                               /* send nbr request or BTM query to update RCC */
-                                               wl_cfg80211_wbtext_update_rcc(cfg, ndev);
-                                       }
-#endif /* WBTEXT */
+                               if (ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION &&
+                                       dhdp->wbtext_support &&
+                                       event == WLC_E_SET_SSID) {
+                                       /* set wnm_keepalives_max_idle after association */
+                                       wl_cfg80211_wbtext_set_wnm_maxidle(cfg, ndev);
+                                       /* send nbr request or BTM query to update RCC */
+                                       wl_cfg80211_wbtext_update_rcc(cfg, ndev);
                                }
+#endif /* WBTEXT */
+                       }
                        wl_update_prof(cfg, ndev, e, &act, WL_PROF_ACT);
                        wl_update_prof(cfg, ndev, NULL, (const void *)&e->addr, WL_PROF_BSSID);
-               } else if (wl_is_linkdown(cfg, e) ||
+               } else if (WL_IS_LINKDOWN(cfg, e, data) ||
                                ((event == WLC_E_SET_SSID) &&
                                (ntoh32(e->status) != WLC_E_STATUS_SUCCESS) &&
                                (wl_get_drv_status(cfg, CONNECTED, ndev)))) {
@@ -12079,6 +12494,16 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                                return 0;
                        }
 
+#ifdef DYNAMIC_MUMIMO_CONTROL
+                       wl_set_murx_reassoc_status(cfg, FALSE);
+                       wl_set_murx_block_eapol_status(cfg, FALSE);
+                       /* Reset default murx_bfe_cap value */
+                       wl_set_murx_bfe_cap(ndev, 1, FALSE);
+#ifdef ARGOS_CPU_SCHEDULER
+                       argos_config_mumimo_reset();
+#endif /* ARGOS_CPU_SCHEDULER */
+                       DHD_ENABLE_RUNTIME_PM((dhd_pub_t *)(cfg->pub));
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 #ifdef DHD_LOSSLESS_ROAMING
                        wl_del_roam_timeout(cfg);
 #endif
@@ -12112,14 +12537,23 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                        if (wl_get_drv_status(cfg, CONNECTED, ndev)) {
                                scb_val_t scbval;
                                u8 *curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID);
-                               s32 reason = 0;
+                               uint32 reason = 0;
                                struct ether_addr bssid_dongle = {{0, 0, 0, 0, 0, 0}};
                                struct ether_addr bssid_null = {{0, 0, 0, 0, 0, 0}};
 
-                               if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND)
+                               if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
                                        reason = ntoh32(e->reason);
-                               /* WLAN_REASON_UNSPECIFIED is used for hang up event in Android */
-                               reason = (reason == WLAN_REASON_UNSPECIFIED)? 0 : reason;
+                                       if (reason > WLC_E_DEAUTH_MAX_REASON) {
+                                               WL_ERR(("Event %d original reason is %d, "
+                                                       "changed 0xFF\n", event, reason));
+                                               reason = WLC_E_DEAUTH_MAX_REASON;
+                                       }
+                               }
+#ifdef SET_SSID_FAIL_CUSTOM_RC
+                               if (event == WLC_E_SET_SSID) {
+                                       reason = SET_SSID_FAIL_CUSTOM_RC;
+                               }
+#endif /* SET_SSID_FAIL_CUSTOM_RC */
 
                                WL_ERR(("link down if %s may call cfg80211_disconnected. "
                                        "event : %d, reason=%d from " MACDBG "\n",
@@ -12130,8 +12564,8 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                                if (g_pm_control) {
                                        scan_suppress = FALSE;
                                        /* Reset the SCAN SUPPRESS Flag */
-                                       err = wldev_ioctl(ndev, WLC_SET_SCANSUPPRESS,
-                                               &scan_suppress, sizeof(int), true);
+                                       err = wldev_ioctl_set(ndev, WLC_SET_SCANSUPPRESS,
+                                               &scan_suppress, sizeof(int));
                                        if (unlikely(err)) {
                                                WL_ERR(("Scan Suppress FALSE Set Failed (%d)\n",
                                                        err));
@@ -12142,8 +12576,9 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 #endif /* DHD_PM_CONTROL_FROM_FILE */
                                /* roam offload does not sync BSSID always, get it from dongle */
                                if (cfg->roam_offload) {
-                                       if (wldev_ioctl(ndev, WLC_GET_BSSID, &bssid_dongle,
-                                                       sizeof(bssid_dongle), false) == BCME_OK) {
+                                       memset(&bssid_dongle, 0, sizeof(bssid_dongle));
+                                       if (wldev_ioctl_get(ndev, WLC_GET_BSSID, &bssid_dongle,
+                                                       sizeof(bssid_dongle)) == BCME_OK) {
                                                /* if not roam case, it would return null bssid */
                                                if (memcmp(&bssid_dongle, &bssid_null,
                                                                ETHER_ADDR_LEN) != 0) {
@@ -12182,11 +12617,8 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                                    FALSE, 0, 0);
 #endif /* RSSI_MONITOR_SUPPORT */
                                wl_clr_drv_status(cfg, CONNECTED, ndev);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
-                               CFG80211_DISCONNECTED(ndev, reason, NULL, 0, false, GFP_KERNEL);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) */
 
-                               if (! wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
+                               if (!wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
                                        /* To make sure disconnect, explictly send dissassoc
                                        *  for BSSID 00:00:00:00:00:00 issue
                                        */
@@ -12194,21 +12626,24 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 
                                        memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
                                        scbval.val = htod32(scbval.val);
-                                       err = wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
-                                               sizeof(scb_val_t), true);
+                                       err = wldev_ioctl_set(ndev, WLC_DISASSOC, &scbval,
+                                               sizeof(scb_val_t));
                                        if (err < 0) {
                                                WL_ERR(("WLC_DISASSOC error %d\n", err));
                                                err = 0;
                                        }
-                                       CFG80211_DISCONNECTED(ndev, reason, NULL, 0,
-                                                       false, GFP_KERNEL);
-                                       wl_link_down(cfg);
-                                       wl_init_prof(cfg, ndev);
                                }
+                               if (wl_get_drv_status(cfg, DISCONNECTING, ndev)) {
+                                       loc_gen = true;
+                               }
+                               /* Send up deauth and clear states */
+                               CFG80211_DISCONNECTED(ndev, reason, NULL, 0,
+                                               loc_gen, GFP_KERNEL);
+                               wl_link_down(cfg);
+                               wl_init_prof(cfg, ndev);
 #ifdef WBTEXT
                                /* when STA was disconnected, clear join pref and set wbtext */
-                               if (ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION &&
-                                               dhdp->wbtext_support) {
+                               if (ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION) {
                                        char smbuf[WLC_IOCTL_SMLEN];
                                        char clear[] = { 0x01, 0x02, 0x00, 0x00, 0x03,
                                                0x02, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00 };
@@ -12232,11 +12667,12 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                                        wl_cfg80211_wbtext_clear_bssid_list(cfg);
                                }
 #endif /* WBTEXT */
+                               wl_vndr_ies_clear_vendor_oui_list(cfg);
                        }
                        else if (wl_get_drv_status(cfg, CONNECTING, ndev)) {
                                WL_ERR(("link down, during connecting\n"));
                                /* Issue WLC_DISASSOC to prevent FW roam attempts */
-                               err = wldev_ioctl(ndev, WLC_DISASSOC, NULL, 0, true);
+                               err = wldev_ioctl_set(ndev, WLC_DISASSOC, NULL, 0);
                                if (err < 0) {
                                        WL_ERR(("CONNECTING state, WLC_DISASSOC error %d\n", err));
                                        err = 0;
@@ -12287,6 +12723,10 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                } else {
                        WL_DBG(("%s nothing\n", __FUNCTION__));
                }
+
+#ifdef DYNAMIC_MUMIMO_CONTROL
+               if (!wl_get_murx_reassoc_status(cfg))
+#endif /* DYNAMIC_MUMIMO_CONTROL */
                DHD_ENABLE_RUNTIME_PM((dhd_pub_t *)cfg->pub);
        }
                else {
@@ -12490,6 +12930,10 @@ wl_notify_roaming_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                act = true;
                wl_update_prof(cfg, ndev, e, &act, WL_PROF_ACT);
                wl_update_prof(cfg, ndev, NULL, (const void *)&e->addr, WL_PROF_BSSID);
+
+               if (ndev == bcmcfg_to_prmry_ndev(cfg)) {
+                       wl_vndr_ies_get_vendor_oui(cfg, ndev, NULL, 0);
+               }
        }
 #ifdef DHD_LOSSLESS_ROAMING
        else if ((event == WLC_E_ROAM || event == WLC_E_BSSID) && status != WLC_E_STATUS_SUCCESS) {
@@ -12500,6 +12944,10 @@ wl_notify_roaming_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 }
 
 #ifdef CUSTOM_EVENT_PM_WAKE
+uint32 last_dpm_upd_time = 0;  /* ms */
+#define DPM_UPD_LMT_TIME       (CUSTOM_EVENT_PM_WAKE + 5000) * 4       /* ms */
+#define DPM_UPD_LMT_RSSI       -85     /* dbm */
+
 static s32
 wl_check_pmstatus(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        const wl_event_msg_t *e, void *data)
@@ -12507,6 +12955,12 @@ wl_check_pmstatus(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        s32 err = BCME_OK;
        struct net_device *ndev = NULL;
        u8 *pbuf = NULL;
+       uint32 cur_dpm_upd_time = 0;
+       dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+       s32 rssi;
+#ifdef SUPPORT_RSSI_SUM_REPORT
+       wl_rssi_ant_mimo_t rssi_ant_mimo;
+#endif /* SUPPORT_RSSI_SUM_REPORT */
        ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
 
        pbuf = kzalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
@@ -12527,16 +12981,69 @@ wl_check_pmstatus(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        if (pbuf) {
                kfree(pbuf);
        }
-       return err;
-}
-#endif /* CUSTOM_EVENT_PM_WAKE */
 
-#ifdef QOS_MAP_SET
-/* get user priority table */
-uint8 *
-wl_get_up_table(dhd_pub_t * dhdp, int idx)
-{
-       struct net_device *ndev;
+       if (dhd->early_suspended) {
+               /* LCD off */
+#ifdef SUPPORT_RSSI_SUM_REPORT
+               /* Query RSSI sum across antennas */
+               memset(&rssi_ant_mimo, 0, sizeof(rssi_ant_mimo));
+               err = wl_get_rssi_per_ant(ndev, ndev->name, NULL, &rssi_ant_mimo);
+               if (err) {
+                       WL_ERR(("Could not get rssi sum (%d)\n", err));
+               }
+               rssi = rssi_ant_mimo.rssi_sum;
+               if (rssi == 0)
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+               {
+                       scb_val_t scb_val;
+                       memset(&scb_val, 0, sizeof(scb_val_t));
+                       scb_val.val = 0;
+                       err = wldev_ioctl_get(ndev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
+                       if (err) {
+                               WL_ERR(("Could not get rssi (%d)\n", err));
+                       }
+                       rssi = wl_rssi_offset(dtoh32(scb_val.val));
+               }
+               WL_ERR(("[%s] RSSI %d dBm\n", ndev->name, rssi));
+               if (rssi > DPM_UPD_LMT_RSSI) {
+                       return err;
+               }
+       } else {
+               /* LCD on */
+               return err;
+       }
+
+       if (last_dpm_upd_time == 0) {
+               last_dpm_upd_time = OSL_SYSUPTIME();
+       } else {
+               cur_dpm_upd_time = OSL_SYSUPTIME();
+               if (cur_dpm_upd_time - last_dpm_upd_time < DPM_UPD_LMT_TIME) {
+                       scb_val_t scbval;
+                       bzero(&scbval, sizeof(scb_val_t));
+
+                       err = wldev_ioctl_set(ndev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));
+                       if (err < 0) {
+                               WL_ERR(("%s: Disassoc error %d\n", __FUNCTION__, err));
+                               return err;
+                       }
+                       WL_ERR(("%s: Force Disassoc due to updated DPM event.\n", __FUNCTION__));
+
+                       last_dpm_upd_time = 0;
+               } else {
+                       last_dpm_upd_time = cur_dpm_upd_time;
+               }
+       }
+
+       return err;
+}
+#endif /* CUSTOM_EVENT_PM_WAKE */
+
+#ifdef QOS_MAP_SET
+/* get user priority table */
+uint8 *
+wl_get_up_table(dhd_pub_t * dhdp, int idx)
+{
+       struct net_device *ndev;
        struct bcm_cfg80211 *cfg;
 
        ndev = dhd_idx2net(dhdp, idx);
@@ -12560,9 +13067,15 @@ wl_notify_roam_prep_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 #if defined(DHD_LOSSLESS_ROAMING) || defined(DBG_PKT_MON)
        dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
 #endif /* DHD_LOSSLESS_ROAMING || DBG_PKT_MON */
+       u32 status = ntoh32(e->status);
+       u32 reason = ntoh32(e->reason);
 
        BCM_REFERENCE(sec);
 
+       if (status == WLC_E_STATUS_SUCCESS && reason != WLC_E_REASON_INITIAL_ASSOC) {
+               WL_ERR(("Attempting roam with reason code : %d\n", reason));
+       }
+
        ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
 
 #ifdef DBG_PKT_MON
@@ -12583,6 +13096,9 @@ sec = wl_read_prof(cfg, ndev, WL_PROF_SEC);
                return BCME_OK;
        }
        dhdp->dequeue_prec_map = 1 << PRIO_8021D_NC;
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       if (!wl_get_murx_reassoc_status(cfg))
+#endif /* DYNAMIC_MUMIMO_CONTROL */
        /* Restore flow control  */
        dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF);
 
@@ -12627,6 +13143,27 @@ static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev)
        assoc_info.req_len = htod32(assoc_info.req_len);
        assoc_info.resp_len = htod32(assoc_info.resp_len);
        assoc_info.flags = htod32(assoc_info.flags);
+
+       if (assoc_info.req_len > (MAX_REQ_LINE + sizeof(struct dot11_assoc_req) +
+               ((assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) ? ETHER_ADDR_LEN : 0))) {
+               err = BCME_BADLEN;
+               goto exit;
+       }
+       if ((assoc_info.req_len > 0) &&
+               (assoc_info.req_len < (sizeof(struct dot11_assoc_req) +
+                       ((assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) ? ETHER_ADDR_LEN : 0)))) {
+               err = BCME_BADLEN;
+               goto exit;
+       }
+       if (assoc_info.resp_len > (MAX_REQ_LINE + sizeof(struct dot11_assoc_resp))) {
+               err = BCME_BADLEN;
+               goto exit;
+       }
+       if ((assoc_info.resp_len > 0) && (assoc_info.resp_len < sizeof(struct dot11_assoc_resp))) {
+               err = BCME_BADLEN;
+               goto exit;
+       }
+
        if (conn_info->req_ie_len) {
                conn_info->req_ie_len = 0;
                bzero(conn_info->req_ie, sizeof(conn_info->req_ie));
@@ -12637,41 +13174,26 @@ static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev)
        }
        if (assoc_info.req_len) {
                err = wldev_iovar_getbuf(ndev, "assoc_req_ies", NULL, 0, cfg->extra_buf,
-                       WL_ASSOC_INFO_MAX, NULL);
+                       assoc_info.req_len, NULL);
                if (unlikely(err)) {
                        WL_ERR(("could not get assoc req (%d)\n", err));
-                       return err;
+                       goto exit;
                }
                conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
                if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
                        conn_info->req_ie_len -= ETHER_ADDR_LEN;
                }
-               if (conn_info->req_ie_len <= MAX_REQ_LINE)
-                       memcpy(conn_info->req_ie, cfg->extra_buf, conn_info->req_ie_len);
-               else {
-                       WL_ERR(("IE size %d above max %d size \n",
-                               conn_info->req_ie_len, MAX_REQ_LINE));
-                       return err;
-               }
-       } else {
-               conn_info->req_ie_len = 0;
+               memcpy(conn_info->req_ie, cfg->extra_buf, conn_info->req_ie_len);
        }
        if (assoc_info.resp_len) {
                err = wldev_iovar_getbuf(ndev, "assoc_resp_ies", NULL, 0, cfg->extra_buf,
-                       WL_ASSOC_INFO_MAX, NULL);
+                       assoc_info.resp_len, NULL);
                if (unlikely(err)) {
                        WL_ERR(("could not get assoc resp (%d)\n", err));
-                       return err;
-               }
-               conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
-               if (conn_info->resp_ie_len <= MAX_REQ_LINE) {
-                       memcpy(conn_info->resp_ie, cfg->extra_buf, conn_info->resp_ie_len);
-               } else {
-                       WL_ERR(("IE size %d above max %d size \n",
-                               conn_info->resp_ie_len, MAX_REQ_LINE));
-                       return err;
+                       goto exit;
                }
-
+               conn_info->resp_ie_len = assoc_info.resp_len - sizeof(struct dot11_assoc_resp);
+               memcpy(conn_info->resp_ie, cfg->extra_buf, conn_info->resp_ie_len);
 #ifdef QOS_MAP_SET
                /* find qos map set ie */
                if ((qos_map_ie = bcm_parse_tlvs(conn_info->resp_ie, conn_info->resp_ie_len,
@@ -12686,12 +13208,14 @@ static s32 wl_get_assoc_ies(struct bcm_cfg80211 *cfg, struct net_device *ndev)
                        cfg->up_table = NULL;
                }
 #endif /* QOS_MAP_SET */
-       } else {
-               conn_info->resp_ie_len = 0;
        }
-       WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
-               conn_info->resp_ie_len));
 
+exit:
+       if (err) {
+               WL_ERR(("err:%d, assoc_info-req:%u,resp:%u conn_info-req:%u,resp:%u\n",
+                       err, assoc_info.req_len, assoc_info.resp_len,
+                       conn_info->req_ie_len, conn_info->resp_ie_len));
+       }
        return err;
 }
 
@@ -12709,7 +13233,7 @@ static s32 wl_ch_to_chanspec(struct net_device *dev, int ch, struct wl_join_para
                        /* If ROAM CACHE is enabled, use the cached channel list */
                        int n_channels;
                        n_channels = get_roam_channel_list(ch, join_params->params.chanspec_list,
-                               &join_params->ssid, ioctl_version);
+                               MAX_ROAM_CHANNEL, &join_params->ssid, ioctl_version);
                        join_params->params.chanspec_num = htod32(n_channels);
                        *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
                                join_params->params.chanspec_num * sizeof(chanspec_t);
@@ -12767,10 +13291,8 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        s32 err = 0;
        struct wiphy *wiphy;
        u32 channel;
-#ifdef  ROAM_CHANNEL_CACHE
-       struct ieee80211_channel *cur_channel;
+       char *buf;
        u32 freq, band;
-#endif /* ROAM_CHANNEL_CACHE */
 
        wiphy = bcmcfg_to_wiphy(cfg);
 
@@ -12778,16 +13300,19 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID);
        bss = CFG80211_GET_BSS(wiphy, NULL, curbssid,
                ssid->SSID, ssid->SSID_len);
+       buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_ATOMIC);
+       if (!buf) {
+               WL_ERR(("buffer alloc failed.\n"));
+               return BCME_NOMEM;
+       }
        mutex_lock(&cfg->usr_sync);
-
-       *(u32 *) cfg->extra_buf = htod32(WL_EXTRA_BUF_MAX);
-       err = wldev_ioctl(ndev, WLC_GET_BSS_INFO,
-               cfg->extra_buf, WL_EXTRA_BUF_MAX, false);
+       *(u32 *)buf = htod32(WL_EXTRA_BUF_MAX);
+       err = wldev_ioctl_get(ndev, WLC_GET_BSS_INFO, buf, WL_EXTRA_BUF_MAX);
        if (unlikely(err)) {
                WL_ERR(("Could not get bss info %d\n", err));
                goto update_bss_info_out;
        }
-       bi = (struct wl_bss_info *)(cfg->extra_buf + 4);
+       bi = (struct wl_bss_info *)(buf + 4);
        channel = wf_chspec_ctlchan(wl_chspec_driver_to_host(bi->chanspec));
        wl_update_prof(cfg, ndev, NULL, &channel, WL_PROF_CHAN);
 
@@ -12807,16 +13332,13 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                beacon_interval = cpu_to_le16(bi->beacon_period);
        } else {
                WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
-#ifdef  ROAM_CHANNEL_CACHE
 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
                freq = ieee80211_channel_to_frequency(channel);
 #else
                band = (channel <= CH_MAX_2G_CHANNEL) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
                freq = ieee80211_channel_to_frequency(channel, band);
 #endif
-               cur_channel = ieee80211_get_channel(wiphy, freq);
-               bss->channel = cur_channel;
-#endif /* ROAM_CHANNEL_CACHE */
+               bss->channel = ieee80211_get_channel(wiphy, freq);
 #if defined(WL_CFG80211_P2P_DEV_IF)
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
 #pragma GCC diagnostic push
@@ -12845,8 +13367,9 @@ static s32 wl_update_bss_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                * information out of probe response.
                * so we speficially query dtim information.
                */
-               err = wldev_ioctl(ndev, WLC_GET_DTIMPRD,
-                       &dtim_period, sizeof(dtim_period), false);
+               dtim_period = 0;
+               err = wldev_ioctl_get(ndev, WLC_GET_DTIMPRD,
+                       &dtim_period, sizeof(dtim_period));
                if (unlikely(err)) {
                        WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
                        goto update_bss_info_out;
@@ -12860,6 +13383,8 @@ update_bss_info_out:
        if (unlikely(err)) {
                WL_ERR(("Failed with error %d\n", err));
        }
+
+       kfree(buf);
        mutex_unlock(&cfg->usr_sync);
        return err;
 }
@@ -12877,13 +13402,10 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        struct ieee80211_supported_band *band;
        struct ieee80211_channel *notify_channel = NULL;
        u32 freq;
-       struct channel_info ci;
-       u32 cur_channel;
 #endif /* LINUX_VERSION > 2.6.39 || WL_COMPAT_WIRELESS */
 #if defined(WLADPS_SEAK_AP_WAR) || defined(WBTEXT)
        dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
 #endif /* WLADPS_SEAK_AP_WAR || WBTEXT */
-
 #ifdef WLFBT
        uint32 data_len = 0;
        if (data)
@@ -12894,33 +13416,13 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        BCM_REFERENCE(dhdp);
 #endif /* WLADPS_SEAK_AP_WAR */
 
-       /* Skip calling cfg80211_roamed If the channels are same and
-        * the current bssid/last_roamed_bssid & the new bssid are same
-        * Also clear timer roam_timeout.
-        */
-       curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID);
-       channel = (u32 *)wl_read_prof(cfg, ndev, WL_PROF_CHAN);
-       if ((wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci,
-                       sizeof(ci), false)) < 0) {
-               WL_ERR(("Failed to get current channel !"));
-               return BCME_ERROR;
-       }
-       cur_channel = dtoh32(ci.hw_channel);
-       if ((*channel == cur_channel) && ((memcmp(curbssid, &e->addr,
-               ETHER_ADDR_LEN) == 0) || (memcmp(&cfg->last_roamed_addr,
-               &e->addr, ETHER_ADDR_LEN) == 0))) {
-               WL_ERR(("BSS already present, Skipping roamed event to"
-               " upper layer\n"));
-#ifdef DHD_LOSSLESS_ROAMING
-               wl_del_roam_timeout(cfg);
-#endif  /* DHD_LOSSLESS_ROAMING */
-               return  err;
-       }
-
        wl_get_assoc_ies(cfg, ndev);
        wl_update_prof(cfg, ndev, NULL, (const void *)(e->addr.octet), WL_PROF_BSSID);
        curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID);
-       wl_update_bss_info(cfg, ndev, true);
+       if ((err = wl_update_bss_info(cfg, ndev, true)) != BCME_OK) {
+               WL_ERR(("failed to update bss info, err=%d\n", err));
+               goto fail;
+       }
        wl_update_pmklist(ndev, cfg->pmk_list, err);
 
        channel = (u32 *)wl_read_prof(cfg, ndev, WL_PROF_CHAN);
@@ -12954,7 +13456,7 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                wl_set_adps_mode(cfg, ndev, enable_mode);
        }
 #endif /* WLADPS_SEAK_AP_WAR */
-       WL_ERR(("wl_bss_roaming_done succeeded to " MACDBG " (ch:%d)\n",
+       WL_ERR(("%s succeeded to " MACDBG " (ch:%d)\n", __FUNCTION__,
                MAC2STRDBG((const u8*)(&e->addr)), *channel));
 
        cfg80211_roamed(ndev,
@@ -12970,9 +13472,29 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        wl_set_drv_status(cfg, CONNECTED, ndev);
 
 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       if (!wl_get_murx_reassoc_status(cfg))
+#endif /* DYNAMIC_MUMIMO_CONTROL */
        cfg->roam_count++;
 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
 
+#ifdef DYNAMIC_MUMIMO_CONTROL
+       if (wl_get_murx_reassoc_status(cfg)) {
+               struct wl_security *sec = wl_read_prof(cfg, ndev, WL_PROF_SEC);
+               bool sec_wpa = sec ? (sec->wpa_versions &
+                       (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) : FALSE;
+               dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+               if (!sec_wpa) {
+                       wl_set_murx_reassoc_status(cfg, FALSE);
+                       WL_DBG(("Security is not WPA nor WPA2\n"));
+               } else {
+                       WL_DBG(("Security is WPA or WPA2\n"));
+               }
+               wl_set_murx_block_eapol_status(cfg, FALSE);
+               dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF);
+       }
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+
 #ifdef WBTEXT
        if (dhdp->wbtext_support) {
                /* set wnm_keepalives_max_idle after association */
@@ -12982,6 +13504,7 @@ wl_bss_roaming_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        }
 #endif /* WBTEXT */
 
+fail:
        return err;
 }
 
@@ -13033,6 +13556,9 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
        s32 err = 0;
        u8 *curbssid = wl_read_prof(cfg, ndev, WL_PROF_BSSID);
        dhd_pub_t *dhdp;
+#ifdef WL_IRQSET
+       int delta_time = 0;
+#endif /* WL_IRQSET */
 
        dhdp = (dhd_pub_t *)(cfg->pub);
        BCM_REFERENCE(dhdp);
@@ -13112,6 +13638,14 @@ wl_bss_connect_done(struct bcm_cfg80211 *cfg, struct net_device *ndev,
                                dhd_set_cpucore(dhdp, TRUE);
                        }
 #endif /* CUSTOM_SET_CPUCORE */
+#ifdef WL_IRQSET
+                       dhd_irq_set_affinity(dhdp);
+                       delta_time = IRQ_SET_DURATION - local_clock() / USEC_PER_SEC;
+                       if (delta_time > 0) {
+                               schedule_delayed_work(&cfg->irq_set_work,
+                                       msecs_to_jiffies((const unsigned int)delta_time));
+                       }
+#endif /* WL_IRQSET */
                        memset(&cfg->last_roamed_addr, 0, ETHER_ADDR_LEN);
                }
 
@@ -13249,14 +13783,6 @@ wl_notify_gscan_event(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        u32 len = ntoh32(e->datalen);
 
        switch (event) {
-               case WLC_E_PFN_SWC:
-                       ptr = dhd_dev_swc_scan_event(ndev, data, &send_evt_bytes);
-                       if (send_evt_bytes) {
-                               wl_cfgvendor_send_async_event(wiphy, ndev,
-                                   GOOGLE_GSCAN_SIGNIFICANT_EVENT, ptr, send_evt_bytes);
-                               kfree(ptr);
-                       }
-                       break;
                case WLC_E_PFN_BEST_BATCHING:
                        err = dhd_dev_retrieve_batch_scan(ndev);
                        if (err < 0) {
@@ -13307,7 +13833,7 @@ wl_notify_gscan_event(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                        }
                        break;
                case WLC_E_PFN_GSCAN_FULL_RESULT:
-                       ptr = dhd_dev_process_full_gscan_result(ndev, data, &send_evt_bytes);
+                       ptr = dhd_dev_process_full_gscan_result(ndev, data, len, &send_evt_bytes);
                        if (ptr) {
                                wl_cfgvendor_send_async_event(wiphy, ndev,
                                    GOOGLE_SCAN_FULL_RESULTS_EVENT, ptr, send_evt_bytes);
@@ -13354,8 +13880,9 @@ wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
 
        mutex_lock(&cfg->usr_sync);
        wl_clr_drv_status(cfg, SCANNING, ndev);
-       err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
-               sizeof(channel_inform), false);
+       memset(&channel_inform, 0, sizeof(channel_inform));
+       err = wldev_ioctl_get(ndev, WLC_GET_CHANNEL, &channel_inform,
+               sizeof(channel_inform));
        if (unlikely(err)) {
                WL_ERR(("scan busy (%d)\n", err));
                goto scan_done_out;
@@ -13370,7 +13897,7 @@ wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        bss_list = cfg->bss_list;
        memset(bss_list, 0, len);
        bss_list->buflen = htod32(len);
-       err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false);
+       err = wldev_ioctl_get(ndev, WLC_SCAN_RESULTS, bss_list, len);
        if (unlikely(err) && unlikely(!cfg->scan_suppressed)) {
                WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
                err = -EINVAL;
@@ -13628,14 +14155,25 @@ wl_notify_rx_mgmt_frame(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        wifi_p2p_pub_act_frame_t *act_frm = NULL;
        wifi_p2p_action_frame_t *p2p_act_frm = NULL;
        wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL;
-       wl_event_rx_frame_data_t *rxframe =
-               (wl_event_rx_frame_data_t*)data;
-       u32 event = ntoh32(e->event_type);
+       wl_event_rx_frame_data_t *rxframe;
+       u32 event;
        u8 *mgmt_frame;
-       u8 bsscfgidx = e->bsscfgidx;
-       u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
-       u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK));
-
+       u8 bsscfgidx;
+       u32 mgmt_frame_len;
+       u16 channel;
+       if (ntoh32(e->datalen) < sizeof(wl_event_rx_frame_data_t)) {
+               WL_ERR(("wrong datalen:%d\n", ntoh32(e->datalen)));
+               return -EINVAL;
+       }
+       mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
+       event = ntoh32(e->event_type);
+       bsscfgidx = e->bsscfgidx;
+       rxframe = (wl_event_rx_frame_data_t *)data;
+       if (!rxframe) {
+               WL_ERR(("rxframe: NULL\n"));
+               return -EINVAL;
+       }
+       channel = (ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK);
        memset(&bssid, 0, ETHER_ADDR_LEN);
        ndev = cfgdev_to_wlc_ndev(cfgdev, cfg);
        if ((ndev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) &&
@@ -13682,7 +14220,7 @@ _Pragma("GCC diagnostic pop")
                        goto exit;
                }
 
-               err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+               err = wldev_ioctl_get(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN);
                if (err < 0)
                         WL_ERR(("WLC_GET_BSSID error %d\n", err));
                memcpy(da.octet, cfg->ioctl_buf, ETHER_ADDR_LEN);
@@ -13860,7 +14398,10 @@ _Pragma("GCC diagnostic pop")
                WL_DBG((" Event WLC_E_PROBREQ_MSG received\n"));
                mgmt_frame = (u8 *)(data);
                mgmt_frame_len = ntoh32(e->datalen);
-
+               if (mgmt_frame_len < DOT11_MGMT_HDR_LEN) {
+                       WL_ERR(("wrong datalen:%d\n", mgmt_frame_len));
+                       return -EINVAL;
+               }
                prbreq_ie_len = mgmt_frame_len - DOT11_MGMT_HDR_LEN;
 
                /* Parse prob_req IEs */
@@ -14149,9 +14690,14 @@ static void wl_init_prof(struct bcm_cfg80211 *cfg, struct net_device *ndev)
        unsigned long flags;
        struct wl_profile *profile = wl_get_profile_by_netdev(cfg, ndev);
 
-       spin_lock_irqsave(&cfg->cfgdrv_lock, flags);
-       memset(profile, 0, sizeof(struct wl_profile));
-       spin_unlock_irqrestore(&cfg->cfgdrv_lock, flags);
+       if (profile) {
+               spin_lock_irqsave(&cfg->cfgdrv_lock, flags);
+               memset(profile, 0, sizeof(struct wl_profile));
+               spin_unlock_irqrestore(&cfg->cfgdrv_lock, flags);
+       } else {
+               WL_ERR(("%s: No profile\n", __FUNCTION__));
+       }
+       return;
 }
 
 static void wl_init_event_handler(struct bcm_cfg80211 *cfg)
@@ -14185,7 +14731,6 @@ static void wl_init_event_handler(struct bcm_cfg80211 *cfg)
        cfg->evt_handler[WLC_E_PFN_BEST_BATCHING] = wl_notify_gscan_event;
        cfg->evt_handler[WLC_E_PFN_SCAN_COMPLETE] = wl_notify_gscan_event;
        cfg->evt_handler[WLC_E_PFN_GSCAN_FULL_RESULT] = wl_notify_gscan_event;
-       cfg->evt_handler[WLC_E_PFN_SWC] = wl_notify_gscan_event;
        cfg->evt_handler[WLC_E_PFN_BSSID_NET_FOUND] = wl_notify_gscan_event;
        cfg->evt_handler[WLC_E_PFN_BSSID_NET_LOST] = wl_notify_gscan_event;
        cfg->evt_handler[WLC_E_PFN_SSID_EXT] = wl_notify_gscan_event;
@@ -14437,8 +14982,11 @@ static void wl_scan_timeout(unsigned long data)
        struct wl_bss_info *bi = NULL;
        s32 i;
        u32 channel;
-#if defined(DHD_DEBUG) && defined(DHD_FW_COREDUMP)
+#if defined(BCM4359_CHIP) || (defined(DHD_DEBUG) && defined(DHD_FW_COREDUMP))
        dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+#endif /*  BCM4359_CHIP || DHD_DEBUG && DHD_FW_COREDUMP */
+
+#if defined(DHD_DEBUG) && defined(DHD_FW_COREDUMP)
        uint32 prev_memdump_mode = dhdp->memdump_enabled;
 #endif /* DHD_DEBUG && DHD_FW_COREDUMP */
 
@@ -14490,6 +15038,11 @@ static void wl_scan_timeout(unsigned long data)
        if (!wl_scan_timeout_dbg_enabled)
                wl_scan_timeout_dbg_set();
 #endif /* CUSTOMER_HW4_DEBUG */
+
+#if defined(BCM4359_CHIP)
+       dhdp->hang_reason = HANG_REASON_IOCTL_RESP_TIMEOUT;
+       net_os_send_hang_message(ndev);
+#endif /* BCM4359_CHIP */
 }
 
 #ifdef DHD_LOSSLESS_ROAMING
@@ -14640,7 +15193,7 @@ void wl_cfg80211_scan_abort(struct bcm_cfg80211 *cfg)
                        err = -ENOMEM;
                } else {
                        /* Do a scan abort to stop the driver's scan engine */
-                       err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true);
+                       err = wldev_ioctl_set(dev, WLC_SCAN, params, params_size);
                        if (err < 0) {
                                WL_ERR(("scan abort  failed \n"));
                        }
@@ -15026,6 +15579,11 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                        WL_ERR(("Invalid escan result (NULL pointer)\n"));
                        goto exit;
                }
+               if ((dtoh32(escan_result->buflen) > (int)ESCAN_BUF_SIZE) ||
+                   (dtoh32(escan_result->buflen) < sizeof(wl_escan_result_t))) {
+                       WL_ERR(("Invalid escan buffer len:%d\n", dtoh32(escan_result->buflen)));
+                       goto exit;
+               }
                if (dtoh16(escan_result->bss_count) != 1) {
                        WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count));
                        goto exit;
@@ -15504,8 +16062,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                                WL_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n"));
                }
                pm = PM_OFF;
-               if ((err = wldev_ioctl(_net_info->ndev, WLC_SET_PM, &pm,
-                               sizeof(pm), true)) != 0) {
+               if ((err = wldev_ioctl_set(_net_info->ndev, WLC_SET_PM, &pm,
+                               sizeof(pm))) != 0) {
                        if (err == -ENODEV)
                                WL_DBG(("%s:netdev not ready\n",
                                        _net_info->ndev->name));
@@ -15524,8 +16082,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                {
                        if (wl_cfg80211_is_concurrent_mode(primary_dev)) {
                                int frameburst = 0;
-                               if (wldev_ioctl(primary_dev, WLC_SET_FAKEFRAG, &frameburst,
-                                       sizeof(frameburst), true) != 0) {
+                               if (wldev_ioctl_set(primary_dev, WLC_SET_FAKEFRAG, &frameburst,
+                                       sizeof(frameburst)) != 0) {
                                        WL_DBG(("frameburst set error\n"));
                                }
                                WL_DBG(("Frameburst Disabled\n"));
@@ -15543,8 +16101,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                        rtt_status = GET_RTTSTATE(dhd);
                        if (rtt_status->status != RTT_ENABLED)
 #endif /* RTT_SUPPORT */
-                               if ((err = wldev_ioctl(_net_info->ndev, WLC_SET_PM, &pm,
-                                               sizeof(pm), true)) != 0) {
+                               if ((err = wldev_ioctl_set(_net_info->ndev, WLC_SET_PM, &pm,
+                                               sizeof(pm))) != 0) {
                                        if (err == -ENODEV)
                                                WL_DBG(("%s:netdev not ready\n",
                                                        _net_info->ndev->name));
@@ -15563,8 +16121,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
 #endif /* USE_WFA_CERT_CONF */
                {
                        int frameburst = 1;
-                       if (wldev_ioctl(primary_dev, WLC_SET_FAKEFRAG, &frameburst,
-                               sizeof(frameburst), true) != 0) {
+                       if (wldev_ioctl_set(primary_dev, WLC_SET_FAKEFRAG, &frameburst,
+                               sizeof(frameburst)) != 0) {
                                WL_DBG(("frameburst set error\n"));
                        }
                        WL_DBG(("Frameburst Enabled\n"));
@@ -15641,6 +16199,7 @@ static s32 wl_init_priv(struct bcm_cfg80211 *cfg)
        mutex_init(&cfg->usr_sync);
        mutex_init(&cfg->event_sync);
        mutex_init(&cfg->scan_complete);
+       mutex_init(&cfg->if_sync);
 #ifdef WLTDLS
        mutex_init(&cfg->tdls_sync);
 #endif /* WLTDLS */
@@ -15828,6 +16387,8 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *context)
 #ifdef WBTEXT
        INIT_LIST_HEAD(&cfg->wbtext_bssid_list);
 #endif /* WBTEXT */
+       INIT_LIST_HEAD(&cfg->vndr_oui_list);
+       spin_lock_init(&cfg->vndr_oui_sync);
        spin_lock_init(&cfg->net_list_sync);
        ndev->ieee80211_ptr = wdev;
        SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
@@ -15882,8 +16443,17 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *context)
 #endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */
 
        INIT_DELAYED_WORK(&cfg->pm_enable_work, wl_cfg80211_work_handler);
+#ifdef WL_IRQSET
+       INIT_DELAYED_WORK(&cfg->irq_set_work, wl_irq_set_work_handler);
+#endif /* WL_IRQSET */
        mutex_init(&cfg->pm_sync);
 
+#if defined(STAT_REPORT)
+       err = wl_attach_stat_report(cfg);
+       if (err) {
+               goto cfg80211_attach_out;
+       }
+#endif /* STAT_REPORT */
        return err;
 
 cfg80211_attach_out:
@@ -15900,6 +16470,9 @@ void wl_cfg80211_detach(struct bcm_cfg80211 *cfg)
                return;
 
        wl_add_remove_pm_enable_work(cfg, WL_PM_WORKQ_DEL);
+#ifdef WL_IRQSET
+       cancel_delayed_work_sync(&cfg->irq_set_work);
+#endif /* WL_IRQSET */
 
 #if defined(COEX_DHCP)
        wl_cfg80211_btcoex_deinit();
@@ -15931,6 +16504,9 @@ void wl_cfg80211_detach(struct bcm_cfg80211 *cfg)
 #if defined(WL_ENABLE_P2P_IF) || defined(WL_NEWCFG_PRIVCMD_SUPPORT)
        wl_cfg80211_detach_p2p(cfg);
 #endif /* WL_ENABLE_P2P_IF || WL_NEWCFG_PRIVCMD_SUPPORT */
+#if defined(STAT_REPORT)
+       wl_detach_stat_report(cfg);
+#endif /* STAT_REPORT */
 
        wl_cfg80211_ibss_vsie_free(cfg);
        wl_cfg80211_clear_mgmt_vndr_ies(cfg);
@@ -15953,31 +16529,34 @@ static void wl_event_handler(struct work_struct *work_data)
        BCM_SET_CONTAINER_OF(cfg, work_data, struct bcm_cfg80211, event_work);
        DHD_EVENT_WAKE_LOCK(cfg->pub);
        while ((e = wl_deq_event(cfg))) {
-                       WL_DBG(("event type (%d), ifidx: %d bssidx: %d \n",
-                               e->etype, e->emsg.ifidx, e->emsg.bsscfgidx));
+               WL_DBG(("event type (%d), ifidx: %d bssidx: %d \n",
+                       e->etype, e->emsg.ifidx, e->emsg.bsscfgidx));
 
-                       if (e->emsg.ifidx > WL_MAX_IFS) {
-                               WL_ERR((" Event ifidx not in range. val:%d \n", e->emsg.ifidx));
-                               goto fail;
-                       }
+               if (e->emsg.ifidx > WL_MAX_IFS) {
+                       WL_ERR((" Event ifidx not in range. val:%d \n", e->emsg.ifidx));
+                       goto fail;
+               }
 
-                       if (!(wdev = wl_get_wdev_by_bssidx(cfg, e->emsg.bsscfgidx))) {
-                               /* For WLC_E_IF would be handled by wl_host_event */
-                               if (e->etype != WLC_E_IF)
-                                       WL_ERR(("No wdev corresponding to bssidx: 0x%x found!"
-                                               " Ignoring event.\n", e->emsg.bsscfgidx));
-                       } else if (e->etype < WLC_E_LAST && cfg->evt_handler[e->etype]) {
-                               dhd_pub_t *dhd = (struct dhd_pub *)(cfg->pub);
-                               if (dhd->busstate == DHD_BUS_DOWN) {
-                                       WL_ERR((": BUS is DOWN.\n"));
-                               } else
-                                       cfg->evt_handler[e->etype](cfg, wdev_to_cfgdev(wdev),
-                                               &e->emsg, e->edata);
-                       } else {
-                               WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
-                       }
+               /* Make sure iface operations, don't creat race conditions */
+               mutex_lock(&cfg->if_sync);
+               if (!(wdev = wl_get_wdev_by_bssidx(cfg, e->emsg.bsscfgidx))) {
+                       /* For WLC_E_IF would be handled by wl_host_event */
+                       if (e->etype != WLC_E_IF)
+                               WL_ERR(("No wdev corresponding to bssidx: 0x%x found!"
+                                       " Ignoring event.\n", e->emsg.bsscfgidx));
+               } else if (e->etype < WLC_E_LAST && cfg->evt_handler[e->etype]) {
+                       dhd_pub_t *dhd = (struct dhd_pub *)(cfg->pub);
+                       if (dhd->busstate == DHD_BUS_DOWN) {
+                               WL_ERR((": BUS is DOWN.\n"));
+                       } else
+                               cfg->evt_handler[e->etype](cfg, wdev_to_cfgdev(wdev),
+                                       &e->emsg, e->edata);
+               } else {
+                       WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
+               }
+               mutex_unlock(&cfg->if_sync);
 fail:
-                       wl_put_event(e);
+               wl_put_event(e);
        }
        DHD_EVENT_WAKE_UNLOCK(cfg->pub);
 }
@@ -15989,11 +16568,7 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
        struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
        struct net_info *netinfo;
 
-#if (WL_DBG_LEVEL > 0)
-       s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
-           wl_dbg_estr[event_type] : (s8 *) "Unknown";
-       WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
-#endif /* (WL_DBG_LEVEL > 0) */
+       WL_DBG(("event_type (%d): %s\n", event_type, bcmevent_get_name(event_type)));
 
        if ((cfg == NULL) || (cfg->p2p_supported && cfg->p2p == NULL)) {
                WL_ERR(("Stale event ignored\n"));
@@ -16143,7 +16718,7 @@ static s32 wl_config_ifmode(struct bcm_cfg80211 *cfg, struct net_device *ndev, s
                return err;
        }
        infra = htod32(infra);
-       err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), true);
+       err = wldev_ioctl_set(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
        if (unlikely(err)) {
                WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
                return err;
@@ -16185,9 +16760,7 @@ s32 wl_cfg80211_apply_eventbuffer(
        mutex_lock(&cfg->event_sync);
 
        /* Read event_msgs mask */
-       bcm_mkiovar("event_msgs", NULL, 0, iovbuf,
-               sizeof(iovbuf));
-       ret = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
+       ret = wldev_iovar_getbuf(ndev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
        if (unlikely(ret)) {
                WL_ERR(("Get event_msgs error (%d)\n", ret));
                goto exit;
@@ -16203,9 +16776,8 @@ s32 wl_cfg80211_apply_eventbuffer(
        }
 
        /* Write updated Event mask */
-       bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
-               sizeof(iovbuf));
-       ret = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
+       ret = wldev_iovar_setbuf(ndev, "event_msgs", eventmask, sizeof(eventmask), iovbuf,
+                       sizeof(iovbuf), NULL);
        if (unlikely(ret)) {
                WL_ERR(("Set event_msgs error (%d)\n", ret));
        }
@@ -16232,9 +16804,7 @@ s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
        mutex_lock(&cfg->event_sync);
 
        /* Setup event_msgs */
-       bcm_mkiovar("event_msgs", NULL, 0, iovbuf,
-               sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
+       err = wldev_iovar_getbuf(ndev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
        if (unlikely(err)) {
                WL_ERR(("Get event_msgs error (%d)\n", err));
                goto eventmsg_out;
@@ -16245,9 +16815,8 @@ s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
        } else {
                clrbit(eventmask, event);
        }
-       bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
-               sizeof(iovbuf));
-       err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
+       err = wldev_iovar_setbuf(ndev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+                       sizeof(iovbuf), NULL);
        if (unlikely(err)) {
                WL_ERR(("Set event_msgs error (%d)\n", err));
                goto eventmsg_out;
@@ -16279,9 +16848,6 @@ static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap)
                WL_ERR(("failed to allocate local buf\n"));
                return -ENOMEM;
        }
-       list = (wl_uint32_list_t *)(void *)pbuf;
-       list->count = htod32(WL_NUMCHANSPECS);
-
 
        err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL,
                0, pbuf, LOCAL_BUF_LEN, 0, &cfg->ioctl_buf_sync);
@@ -16438,14 +17004,14 @@ static s32 __wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify)
        struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS] = {NULL, };
 
        memset(bandlist, 0, sizeof(bandlist));
-       err = wldev_ioctl(dev, WLC_GET_BANDLIST, bandlist,
-               sizeof(bandlist), false);
+       err = wldev_ioctl_get(dev, WLC_GET_BANDLIST, bandlist,
+               sizeof(bandlist));
        if (unlikely(err)) {
                WL_ERR(("error read bandlist (%d)\n", err));
                return err;
        }
-       err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band,
-               sizeof(s32), false);
+       err = wldev_ioctl_get(dev, WLC_GET_BAND, &cur_band,
+               sizeof(s32));
        if (unlikely(err)) {
                WL_ERR(("error (%d)\n", err));
                return err;
@@ -16790,6 +17356,9 @@ static s32 __wl_cfg80211_down(struct bcm_cfg80211 *cfg)
 
        /* Delete pm_enable_work */
        wl_add_remove_pm_enable_work(cfg, WL_PM_WORKQ_DEL);
+#ifdef WL_IRQSET
+       cancel_delayed_work_sync(&cfg->irq_set_work);
+#endif /* WL_IRQSET */
 
        /* clear all the security setting on primary Interface */
        wl_cfg80211_clear_security(cfg);
@@ -16951,8 +17520,8 @@ s32 wl_cfg80211_up(struct net_device *net)
        WL_DBG(("In\n"));
        cfg = wl_get_cfg(net);
 
-       if ((err = wldev_ioctl(bcmcfg_to_prmry_ndev(cfg), WLC_GET_VERSION, &val,
-               sizeof(int), false) < 0)) {
+       if ((err = wldev_ioctl_get(bcmcfg_to_prmry_ndev(cfg), WLC_GET_VERSION, &val,
+               sizeof(int)) < 0)) {
                WL_ERR(("WLC_GET_VERSION failed, err=%d\n", err));
                return err;
        }
@@ -17004,8 +17573,8 @@ s32 wl_cfg80211_up(struct net_device *net)
 
        /* IOVAR configurations with 'up' condition */
 #ifdef DISABLE_PM_BCNRX
-       bcm_mkiovar("pm_bcnrx", (char *)&param, 4, iovbuf, sizeof(iovbuf));
-       interr = wldev_ioctl(bcmcfg_to_prmry_ndev(cfg), WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
+       interr = wldev_iovar_setbuf(bcmcfg_to_prmry_ndev(cfg), "pm_bcnrx", (char *)&param,
+                       sizeof(param), iovbuf, sizeof(iovbuf), NULL);
        if (unlikely(interr)) {
                WL_ERR(("Set pm_bcnrx returned (%d)\n", interr));
        }
@@ -17025,6 +17594,9 @@ s32 wl_cfg80211_up(struct net_device *net)
        wl_cfg80211_create_iface(cfg->wdev->wiphy, NL80211_IFTYPE_STATION, NULL, "wlan%d");
 #endif /* DUAL_STA_STATIC_IF */
 
+#ifdef SUPPORT_CUSTOM_SET_CAC
+       cfg->enable_cac = 0;
+#endif /* SUPPORT_CUSTOM_SET_CAC */
        return err;
 }
 
@@ -17049,6 +17621,11 @@ int wl_cfg80211_hang(struct net_device *dev, u16 reason)
                dhd->req_hang_type = 0;
        }
 #endif /* DHD_HANG_SEND_UP_TEST */
+       if ((dhd->hang_reason <= HANG_REASON_MASK) || (dhd->hang_reason >= HANG_REASON_MAX)) {
+               WL_ERR(("%s, Invalid hang reason 0x%x\n",
+                       __FUNCTION__, dhd->hang_reason));
+               dhd->hang_reason = HANG_REASON_UNKNOWN;
+       }
 #ifdef DHD_USE_EXTENDED_HANG_REASON
        if (dhd->hang_reason != 0) {
                reason = dhd->hang_reason;
@@ -17074,12 +17651,15 @@ int wl_cfg80211_hang(struct net_device *dev, u16 reason)
 s32 wl_cfg80211_down(struct net_device *dev)
 {
        struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
-       s32 err;
+       s32 err = BCME_ERROR;
 
        WL_DBG(("In\n"));
-       mutex_lock(&cfg->usr_sync);
-       err = __wl_cfg80211_down(cfg);
-       mutex_unlock(&cfg->usr_sync);
+
+       if (cfg) {
+               mutex_lock(&cfg->usr_sync);
+               err = __wl_cfg80211_down(cfg);
+               mutex_unlock(&cfg->usr_sync);
+       }
 
        return err;
 }
@@ -17219,7 +17799,7 @@ static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, const u8 *ie_stream,
 {
        u8 *ssidie;
        int32 ssid_len = MIN(bi->SSID_len, DOT11_MAX_SSID_LEN);
-       int32 remaining_ie_buf_len, available_buffer_len;
+       int32 remaining_ie_buf_len, available_buffer_len, unused_buf_len;
        /* cfg80211_find_ie defined in kernel returning const u8 */
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
        4 && __GNUC_MINOR__ >= 6))
@@ -17243,25 +17823,29 @@ _Pragma("GCC diagnostic pop")
        }
        available_buffer_len = ((int)(*ie_size)) - (ssidie + 2 - ie_stream);
        remaining_ie_buf_len = available_buffer_len - (int)ssidie[1];
-       if ((ssid_len > ssidie[1]) ||
-               (ssidie[1] > available_buffer_len)) {
+       unused_buf_len = WL_EXTRA_BUF_MAX - (4 + bi->length + *ie_size);
+       if (ssidie[1] > available_buffer_len) {
+               WL_ERR(("%s: skip wl_update_hidden_ap_ie : overflow\n", __FUNCTION__));
                return;
        }
 
 
        if (ssidie[1] != ssid_len) {
                if (ssidie[1]) {
-                       WL_ERR(("%s: Wrong SSID len: %d != %d\n",
+                       WL_INFORM(("%s: Wrong SSID len: %d != %d\n",
                                __FUNCTION__, ssidie[1], bi->SSID_len));
                }
-               if (roam) {
-                       WL_ERR(("Changing the SSID Info.\n"));
+               if ((roam && (ssid_len > ssidie[1])) && (unused_buf_len > ssid_len)) {
+                       WL_INFORM(("Changing the SSID Info.\n"));
                        memmove(ssidie + ssid_len + 2,
                                (ssidie + 2) + ssidie[1],
                                remaining_ie_buf_len);
                        memcpy(ssidie + 2, bi->SSID, ssid_len);
                        *ie_size = *ie_size + ssid_len - ssidie[1];
                        ssidie[1] = ssid_len;
+               } else if (ssid_len < ssidie[1]) {
+                       WL_ERR(("%s: Invalid SSID len: %d < %d\n",
+                               __FUNCTION__, ssidie[1], bi->SSID_len));
                }
                return;
        }
@@ -17408,7 +17992,7 @@ s32 wl_cfg80211_set_p2p_resp_ap_chn(struct net_device *net, s32 enable)
                /* disable PM for p2p responding on infra AP channel */
                s32 pm = PM_OFF;
 
-               ret = wldev_ioctl(net, WLC_SET_PM, &pm, sizeof(pm), true);
+               ret = wldev_ioctl_set(net, WLC_SET_PM, &pm, sizeof(pm));
        }
 
        return ret;
@@ -17468,8 +18052,12 @@ wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                        cfg80211_rx_mgmt(cfgdev, cfg->tdls_mgmt_freq,
                                        cfg->tdls_mgmt_frame, cfg->tdls_mgmt_frame_len, GFP_ATOMIC);
 #endif /* LINUX_VERSION >= VERSION(3, 18,0) || WL_COMPAT_WIRELESS */
-       }
+               }
                msg = " TDLS PEER CONNECTED ";
+#ifdef SUPPORT_SET_CAC
+               /* TDLS connect reset CAC */
+               wl_cfg80211_set_cac(cfg, 0);
+#endif /* SUPPORT_SET_CAC */
                break;
        case WLC_E_TDLS_PEER_DISCONNECTED :
                if (cfg->tdls_mgmt_frame) {
@@ -17478,6 +18066,10 @@ wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
                        cfg->tdls_mgmt_freq = 0;
                }
                msg = "TDLS PEER DISCONNECTED ";
+#ifdef SUPPORT_SET_CAC
+               /* TDLS disconnec, set CAC */
+               wl_cfg80211_set_cac(cfg, 1);
+#endif /* SUPPORT_SET_CAC */
                break;
        }
        if (msg) {
@@ -17634,6 +18226,9 @@ wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
                }
        }
 out:
+       if (ret) {
+               return -ENOTSUPP;
+       }
 #endif /* WLTDLS */
        return ret;
 }
@@ -17721,10 +18316,16 @@ wl_cfg80211_set_auto_channel_scan_state(struct net_device *ndev)
        u32 val = 0;
        s32 ret = BCME_ERROR;
        struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
+
+       if (wl_check_dongle_idle(bcmcfg_to_wiphy(cfg)) != TRUE) {
+               WL_ERR(("FW is busy to add interface"));
+               return ret;
+       }
+
        /* Set interface up, explicitly. */
        val = 1;
 
-       ret = wldev_ioctl(ndev, WLC_UP, (void *)&val, sizeof(val), true);
+       ret = wldev_ioctl_set(ndev, WLC_UP, (void *)&val, sizeof(val));
        if (ret < 0) {
                WL_ERR(("set interface up failed, error = %d\n", ret));
                goto done;
@@ -17778,14 +18379,9 @@ wl_cfg80211_get_chanspecs_2g(struct net_device *ndev, void *buf, s32 buflen)
 {
        s32 ret = BCME_ERROR;
        struct bcm_cfg80211 *cfg = NULL;
-       wl_uint32_list_t *list = NULL;
        chanspec_t chanspec = 0;
 
-       memset(buf, 0, buflen);
-
        cfg = wl_get_cfg(ndev);
-       list = (wl_uint32_list_t *)buf;
-       list->count = htod32(WL_NUMCHANSPECS);
 
        /* Restrict channels to 2.4GHz, 20MHz BW, no SB. */
        chanspec |= (WL_CHANSPEC_BAND_2G | WL_CHANSPEC_BW_20 |
@@ -17812,11 +18408,6 @@ wl_cfg80211_get_chanspecs_5g(struct net_device *ndev, void *buf, s32 buflen)
        wl_uint32_list_t *list = NULL;
        chanspec_t chanspec = 0;
 
-       memset(buf, 0, buflen);
-
-       list = (wl_uint32_list_t *)buf;
-       list->count = htod32(WL_NUMCHANSPECS);
-
        /* Restrict channels to 5GHz, 20MHz BW, no SB. */
        chanspec |= (WL_CHANSPEC_BAND_5G | WL_CHANSPEC_BW_20 |
                WL_CHANSPEC_CTL_SB_NONE);
@@ -17829,6 +18420,7 @@ wl_cfg80211_get_chanspecs_5g(struct net_device *ndev, void *buf, s32 buflen)
                goto done;
        }
 
+       list = (wl_uint32_list_t *)buf;
        /* Skip DFS and inavlid P2P channel. */
        for (i = 0, j = 0; i < dtoh32(list->count); i++) {
                chanspec = (chanspec_t) dtoh32(list->element[i]);
@@ -17865,7 +18457,7 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen,
        int retry = 0;
 
        /* Start auto channel selection scan. */
-       ret = wldev_ioctl(ndev, WLC_START_CHANNEL_SEL, buf, buflen, true);
+       ret = wldev_ioctl_set(ndev, WLC_START_CHANNEL_SEL, NULL, 0);
        if (ret < 0) {
                WL_ERR(("can't start auto channel scan, error = %d\n", ret));
                *channel = 0;
@@ -17877,9 +18469,8 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen,
 
        while (retry--) {
                OSL_SLEEP(CHAN_SEL_IOCTL_DELAY);
-
-               ret = wldev_ioctl(ndev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen),
-                       false);
+               chosen = 0;
+               ret = wldev_ioctl_get(ndev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
                if ((ret == 0) && (dtoh32(chosen) != 0)) {
                        *channel = (u16)(chosen & 0x00FF);
                        WL_INFORM(("selected channel = %d\n", *channel));
@@ -18294,6 +18885,9 @@ wl_cfg80211_clear_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 b
 
        WL_DBG(("clear interworking IE\n"));
 
+       memset(&ie_setbuf, 0, sizeof(ie_setbuf_t));
+
+       ie_setbuf.ie_buffer.iecount = htod32(1);
        ie_setbuf.ie_buffer.ie_list[0].ie_data.id = DOT11_MNG_INTERWORKING_ID;
        ie_setbuf.ie_buffer.ie_list[0].ie_data.len = 0;
 
@@ -18307,8 +18901,7 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
 {
        s32 err = BCME_OK;
        s32 buf_len;
-       s32 iecount;
-       ie_setbuf_t ie_setbuf;
+       ie_setbuf_t *ie_setbuf;
        ie_getbuf_t ie_getbufp;
        char getbuf[WLC_IOCTL_SMLEN];
 
@@ -18318,7 +18911,7 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
        }
 
        /* access network options (1 octet)  is the mandatory field */
-       if (!data || data_len == 0) {
+       if (!data || data_len == 0 || data_len > IW_IES_MAX_BUF_LEN) {
                WL_ERR(("wrong interworking IE (len=%d)\n", data_len));
                return BCME_BADARG;
        }
@@ -18332,9 +18925,6 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
                return BCME_BADARG;
        }
 
-       /* use VNDR_IE_CUSTOM_FLAG flags for none vendor IE . currently fixed value */
-       pktflag = htod32(pktflag);
-
        buf_len = sizeof(ie_setbuf_t) + data_len - 1;
 
        ie_getbufp.id = DOT11_MNG_INTERWORKING_ID;
@@ -18347,17 +18937,6 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
                }
        }
 
-       strncpy(ie_setbuf.cmd, "add", VNDR_IE_CMD_LEN - 1);
-       ie_setbuf.cmd[VNDR_IE_CMD_LEN - 1] = '\0';
-
-       /* Buffer contains only 1 IE */
-       iecount = htod32(1);
-       memcpy((void *)&ie_setbuf.ie_buffer.iecount, &iecount, sizeof(int));
-       memcpy((void *)&ie_setbuf.ie_buffer.ie_list[0].pktflag, &pktflag, sizeof(uint32));
-
-       /* Now, add the IE to the buffer */
-       ie_setbuf.ie_buffer.ie_list[0].ie_data.id = DOT11_MNG_INTERWORKING_ID;
-
        /* if already set with previous values, delete it first */
        if (cfg->wl11u) {
                if ((err = wl_cfg80211_clear_iw_ie(cfg, ndev, bssidx)) != BCME_OK) {
@@ -18365,10 +18944,25 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
                }
        }
 
-       ie_setbuf.ie_buffer.ie_list[0].ie_data.len = data_len;
-       memcpy((uchar *)&ie_setbuf.ie_buffer.ie_list[0].ie_data.data[0], data, data_len);
+       ie_setbuf = (ie_setbuf_t *) kzalloc(buf_len, GFP_KERNEL);
+       if (!ie_setbuf) {
+               WL_ERR(("Error allocating buffer for IE\n"));
+               return -ENOMEM;
+       }
+       strncpy(ie_setbuf->cmd, "add", sizeof(ie_setbuf->cmd));
+       ie_setbuf->cmd[sizeof(ie_setbuf->cmd) - 1] = '\0';
+
+       /* Buffer contains only 1 IE */
+       ie_setbuf->ie_buffer.iecount = htod32(1);
+       /* use VNDR_IE_CUSTOM_FLAG flags for none vendor IE . currently fixed value */
+       ie_setbuf->ie_buffer.ie_list[0].pktflag = htod32(pktflag);
+
+       /* Now, add the IE to the buffer */
+       ie_setbuf->ie_buffer.ie_list[0].ie_data.id = DOT11_MNG_INTERWORKING_ID;
+       ie_setbuf->ie_buffer.ie_list[0].ie_data.len = data_len;
+       memcpy((uchar *)&ie_setbuf->ie_buffer.ie_list[0].ie_data.data[0], data, data_len);
 
-       if ((err = wldev_iovar_setbuf_bsscfg(ndev, "ie", &ie_setbuf, buf_len,
+       if ((err = wldev_iovar_setbuf_bsscfg(ndev, "ie", ie_setbuf, buf_len,
                        cfg->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &cfg->ioctl_buf_sync))
                        == BCME_OK) {
                WL_DBG(("set interworking IE\n"));
@@ -18376,6 +18970,7 @@ wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bss
                err = wldev_iovar_setint_bsscfg(ndev, "grat_arp", 1, bssidx);
        }
 
+       kfree(ie_setbuf);
        return err;
 }
 #endif /* WL11U */
@@ -18405,6 +19000,55 @@ wl_cfg80211_set_band(struct net_device *ndev, int band)
        return 0;
 }
 #endif /* WL_HOST_BAND_MGMT */
+
+s32
+wl_cfg80211_set_if_band(struct net_device *ndev, int band)
+{
+       struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
+       int ret = 0, wait_cnt;
+       char ioctl_buf[32];
+
+       if ((band < WLC_BAND_AUTO) || (band > WLC_BAND_2G)) {
+               WL_ERR(("Invalid band\n"));
+               return -EINVAL;
+       }
+       if (wl_get_drv_status(cfg, CONNECTED, ndev) ||
+                       wl_get_drv_status(cfg, CONNECTING, ndev)) {
+               /* if driver is connected or connecting status, try to disconnect first.
+               * if dongle is associated, iovar 'if_band' would be rejected.
+               */
+               wl_set_drv_status(cfg, DISCONNECTING, ndev);
+               ret = wldev_ioctl_set(ndev, WLC_DISASSOC, NULL, 0);
+               if (ret < 0) {
+                       WL_ERR(("WLC_DISASSOC error %d\n", ret));
+                       /* continue to set 'if_band' */
+               }
+               else {
+                       /* This is to ensure that 'if_band' iovar is issued only after
+                       * disconnection is completed
+                       */
+                       wait_cnt = WAIT_FOR_DISCONNECT_MAX;
+                       while (wl_get_drv_status(cfg, DISCONNECTING, ndev) && wait_cnt) {
+                               WL_DBG(("Wait until disconnected. wait_cnt: %d\n", wait_cnt));
+                               wait_cnt--;
+                               OSL_SLEEP(10);
+                       }
+               }
+       }
+       if ((ret = wldev_iovar_setbuf(ndev, "if_band", &band,
+                       sizeof(int), ioctl_buf, sizeof(ioctl_buf), NULL)) < 0) {
+               WL_ERR(("seting if_band failed ret=%d\n", ret));
+               /* issue 'WLC_SET_BAND' if if_band is not supported */
+               if (ret == BCME_UNSUPPORTED) {
+                       ret = wldev_set_band(ndev, band);
+                       if (ret < 0) {
+                               WL_ERR(("seting band failed ret=%d\n", ret));
+                       }
+               }
+       }
+       return ret;
+}
+
 s32
 wl_cfg80211_dfs_ap_move(struct net_device *ndev, char *data, char *command, int total_len)
 {
@@ -18749,6 +19393,7 @@ exit:
 }
 
 #define BUFSZ 5
+#define BUFSZN BUFSZ + 1
 
 #define _S(x) #x
 #define S(x) _S(x)
@@ -18758,7 +19403,7 @@ int wl_cfg80211_wbtext_weight_config(struct net_device *ndev, char *data,
 {
        struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
        int bytes_written = 0, err = -EINVAL, argc = 0;
-       char rssi[BUFSZ], band[BUFSZ], weight[BUFSZ];
+       char rssi[BUFSZN], band[BUFSZN], weight[BUFSZN];
        char *endptr = NULL;
        wnm_bss_select_weight_cfg_t *bwcfg;
 
@@ -18842,7 +19487,7 @@ int wl_cfg80211_wbtext_table_config(struct net_device *ndev, char *data,
 {
        struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
        int bytes_written = 0, err = -EINVAL;
-       char rssi[BUFSZ], band[BUFSZ];
+       char rssi[BUFSZN], band[BUFSZN];
        int btcfg_len = 0, i = 0, parsed_len = 0;
        wnm_bss_select_factor_cfg_t *btcfg;
        size_t slen = strlen(data);
@@ -18957,7 +19602,7 @@ wl_cfg80211_wbtext_delta_config(struct net_device *ndev, char *data, char *comma
        uint i = 0;
        struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
        int err = -EINVAL, bytes_written = 0, argc = 0, val, len = 0;
-       char delta[BUFSZ], band[BUFSZ], *endptr = NULL;
+       char delta[BUFSZN], band[BUFSZN], *endptr = NULL;
        wl_roam_prof_band_t *rp;
 
        rp = (wl_roam_prof_band_t *) kzalloc(sizeof(*rp)
@@ -19147,8 +19792,8 @@ _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
                                wl_get_mode_by_netdev(cfg, iter->ndev) != WL_MODE_IBSS))
                                continue;
                        if (iter->ndev) {
-                               if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM,
-                                               &pm, sizeof(pm), true)) != 0) {
+                               if ((err = wldev_ioctl_set(iter->ndev, WLC_SET_PM,
+                                               &pm, sizeof(pm))) != 0) {
                                        if (err == -ENODEV)
                                                WL_DBG(("%s:netdev not ready\n",
                                                        iter->ndev->name));
@@ -19273,10 +19918,9 @@ wl_cfg80211_parse_vndr_ies(u8 *parse, u32 len,
                        memcpy(&parsed_info->vndrie, vndrie, sizeof(vndr_ie_t));
                        vndr_ies->count = count;
 
-                       WL_DBG(("\t ** OUI %02x %02x %02x, type 0x%02x len:%d\n",
-                       parsed_info->vndrie.oui[0], parsed_info->vndrie.oui[1],
-                       parsed_info->vndrie.oui[2], parsed_info->vndrie.data[0],
-                       parsed_info->ie_len));
+                       WL_DBG(("\t ** OUI "MACOUIDBG", type 0x%02x len:%d\n",
+                               MACOUI2STRDBG(parsed_info->vndrie.oui),
+                               parsed_info->vndrie.data[0], parsed_info->ie_len));
                }
 end:
                ie = bcm_next_tlv(ie, &remained_len);
@@ -19302,10 +19946,8 @@ wl_find_vndr_ies_specific_vender(struct bcm_cfg80211 *cfg,
                                vndr_info_list = &vndr_ies.ie_info[i];
                                if (!bcmp(vndr_info_list->vndrie.oui,
                                                (u8*)vndr_oui, DOT11_OUI_LEN)) {
-                                       WL_ERR(("Find OUI %02x %02x %02x\n",
-                                               vndr_info_list->vndrie.oui[0],
-                                               vndr_info_list->vndrie.oui[1],
-                                               vndr_info_list->vndrie.oui[2]));
+                                       WL_ERR(("Find OUI "MACOUIDBG"\n",
+                                               MACOUI2STRDBG(vndr_info_list->vndrie.oui)));
                                        ret = TRUE;
                                        break;
                                }
@@ -19357,56 +19999,236 @@ exit:
 }
 #endif /* WLADPS_SEAK_AP_WAR */
 
-s32
-wl_cfg80211_clear_per_bss_ies(struct bcm_cfg80211 *cfg, s32 bssidx)
+static bool
+wl_vndr_ies_exclude_vndr_oui(struct parsed_vndr_ie_info *vndr_info)
 {
-       s32 index;
-       struct net_info *netinfo;
-       s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG,
-               VNDR_IE_ASSOCRSP_FLAG, VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG};
-
-       netinfo = wl_get_netinfo_by_bssidx(cfg, bssidx);
-       if (!netinfo || !netinfo->wdev) {
-               WL_ERR(("netinfo or netinfo->wdev is NULL\n"));
-               return -1;
-       }
+       int i = 0;
 
-       WL_DBG(("clear management vendor IEs for bssidx:%d \n", bssidx));
-       /* Clear the IEs set in the firmware so that host is in sync with firmware */
-       for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) {
-               if (wl_cfg80211_set_mgmt_vndr_ies(cfg, wdev_to_cfgdev(netinfo->wdev),
-                       bssidx, vndrie_flag[index], NULL, 0) < 0)
-                       WL_ERR(("vndr_ies clear failed. Ignoring.. \n"));
+       while (exclude_vndr_oui_list[i]) {
+               if (!memcmp(vndr_info->vndrie.oui,
+                       exclude_vndr_oui_list[i],
+                       DOT11_OUI_LEN)) {
+                       return TRUE;
+               }
+               i++;
        }
 
-       return 0;
+       return FALSE;
 }
 
-s32
-wl_cfg80211_clear_mgmt_vndr_ies(struct bcm_cfg80211 *cfg)
+static bool
+wl_vndr_ies_check_duplicate_vndr_oui(struct bcm_cfg80211 *cfg,
+       struct parsed_vndr_ie_info *vndr_info)
 {
-       struct net_info *iter, *next;
+       wl_vndr_oui_entry_t *oui_entry = NULL;
+       unsigned long flags;
 
-       WL_DBG(("clear management vendor IEs \n"));
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
-       4 && __GNUC_MINOR__ >= 6))
-_Pragma("GCC diagnostic push")
-_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
+       spin_lock_irqsave(&cfg->vndr_oui_sync, flags);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
-       for_each_ndev(cfg, iter, next) {
-               wl_cfg80211_clear_per_bss_ies(cfg, iter->bssidx);
+       list_for_each_entry(oui_entry, &cfg->vndr_oui_list, list) {
+               if (!memcmp(oui_entry->oui, vndr_info->vndrie.oui, DOT11_OUI_LEN)) {
+                       spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+                       return TRUE;
+               }
        }
-#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
-       4 && __GNUC_MINOR__ >= 6))
-_Pragma("GCC diagnostic pop")
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
 #endif
-       return 0;
+       spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+       return FALSE;
 }
 
-#define WL_VNDR_IE_MAXLEN 2048
-static s8 g_mgmt_ie_buf[WL_VNDR_IE_MAXLEN];
-int
-wl_cfg80211_set_mgmt_vndr_ies(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
+static bool
+wl_vndr_ies_add_vendor_oui_list(struct bcm_cfg80211 *cfg,
+       struct parsed_vndr_ie_info *vndr_info)
+{
+       wl_vndr_oui_entry_t *oui_entry = NULL;
+       unsigned long flags;
+
+       oui_entry = kmalloc(sizeof(*oui_entry), GFP_KERNEL);
+       if (oui_entry == NULL) {
+               WL_ERR(("alloc failed\n"));
+               return FALSE;
+       }
+
+       memcpy(oui_entry->oui, vndr_info->vndrie.oui, DOT11_OUI_LEN);
+
+       INIT_LIST_HEAD(&oui_entry->list);
+       spin_lock_irqsave(&cfg->vndr_oui_sync, flags);
+       list_add_tail(&oui_entry->list, &cfg->vndr_oui_list);
+       spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+
+       return TRUE;
+}
+
+static void
+wl_vndr_ies_clear_vendor_oui_list(struct bcm_cfg80211 *cfg)
+{
+       wl_vndr_oui_entry_t *oui_entry = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cfg->vndr_oui_sync, flags);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+       while (!list_empty(&cfg->vndr_oui_list)) {
+               oui_entry = list_entry(cfg->vndr_oui_list.next, wl_vndr_oui_entry_t, list);
+               if (oui_entry) {
+                       list_del(&oui_entry->list);
+                       kfree(oui_entry);
+               }
+       }
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+       spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+}
+
+static int
+wl_vndr_ies_get_vendor_oui(struct bcm_cfg80211 *cfg, struct net_device *ndev,
+       char *vndr_oui, u32 vndr_oui_len)
+{
+       int i;
+       int vndr_oui_num = 0;
+
+       struct wl_connect_info *conn_info = wl_to_conn(cfg);
+       wl_vndr_oui_entry_t *oui_entry = NULL;
+       struct parsed_vndr_ie_info *vndr_info;
+       struct parsed_vndr_ies vndr_ies;
+
+       char *pos = vndr_oui;
+       u32 remained_buf_len = vndr_oui_len;
+       unsigned long flags;
+
+       if (!conn_info->resp_ie_len) {
+               return BCME_ERROR;
+       }
+
+       wl_vndr_ies_clear_vendor_oui_list(cfg);
+
+       if ((wl_cfg80211_parse_vndr_ies((u8 *)conn_info->resp_ie,
+               conn_info->resp_ie_len, &vndr_ies)) == BCME_OK) {
+               for (i = 0; i < vndr_ies.count; i++) {
+                       vndr_info = &vndr_ies.ie_info[i];
+                       if (wl_vndr_ies_exclude_vndr_oui(vndr_info)) {
+                               continue;
+                       }
+
+                       if (wl_vndr_ies_check_duplicate_vndr_oui(cfg, vndr_info)) {
+                               continue;
+                       }
+
+                       wl_vndr_ies_add_vendor_oui_list(cfg, vndr_info);
+                       vndr_oui_num++;
+               }
+       }
+
+       if (vndr_oui) {
+               spin_lock_irqsave(&cfg->vndr_oui_sync, flags);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+               list_for_each_entry(oui_entry, &cfg->vndr_oui_list, list) {
+                       if (remained_buf_len < VNDR_OUI_STR_LEN) {
+                               spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+                               return BCME_ERROR;
+                       }
+                       pos += snprintf(pos, VNDR_OUI_STR_LEN, "%02X-%02X-%02X ",
+                               oui_entry->oui[0], oui_entry->oui[1], oui_entry->oui[2]);
+                       remained_buf_len -= VNDR_OUI_STR_LEN;
+               }
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+               spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+       }
+
+       return vndr_oui_num;
+}
+
+int
+wl_cfg80211_get_vndr_ouilist(struct bcm_cfg80211 *cfg, uint8 *buf, int max_cnt)
+{
+       wl_vndr_oui_entry_t *oui_entry = NULL;
+       int cnt = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cfg->vndr_oui_sync, flags);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+       list_for_each_entry(oui_entry, &cfg->vndr_oui_list, list) {
+               memcpy(buf, oui_entry->oui, DOT11_OUI_LEN);
+               cnt++;
+               if (cnt >= max_cnt) {
+                       spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+                       return cnt;
+               }
+               buf += DOT11_OUI_LEN;
+       }
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+       spin_unlock_irqrestore(&cfg->vndr_oui_sync, flags);
+       return cnt;
+}
+
+s32
+wl_cfg80211_clear_per_bss_ies(struct bcm_cfg80211 *cfg, s32 bssidx)
+{
+       s32 index;
+       struct net_info *netinfo;
+       s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG,
+               VNDR_IE_ASSOCRSP_FLAG, VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG};
+
+       netinfo = wl_get_netinfo_by_bssidx(cfg, bssidx);
+       if (!netinfo || !netinfo->wdev) {
+               WL_ERR(("netinfo or netinfo->wdev is NULL\n"));
+               return -1;
+       }
+
+       WL_DBG(("clear management vendor IEs for bssidx:%d \n", bssidx));
+       /* Clear the IEs set in the firmware so that host is in sync with firmware */
+       for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) {
+               if (wl_cfg80211_set_mgmt_vndr_ies(cfg, wdev_to_cfgdev(netinfo->wdev),
+                       bssidx, vndrie_flag[index], NULL, 0) < 0)
+                       WL_ERR(("vndr_ies clear failed. Ignoring.. \n"));
+       }
+
+       return 0;
+}
+
+s32
+wl_cfg80211_clear_mgmt_vndr_ies(struct bcm_cfg80211 *cfg)
+{
+       struct net_info *iter, *next;
+
+       WL_DBG(("clear management vendor IEs \n"));
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+       4 && __GNUC_MINOR__ >= 6))
+_Pragma("GCC diagnostic push")
+_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
+#endif
+       for_each_ndev(cfg, iter, next) {
+               wl_cfg80211_clear_per_bss_ies(cfg, iter->bssidx);
+       }
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+       4 && __GNUC_MINOR__ >= 6))
+_Pragma("GCC diagnostic pop")
+#endif
+       return 0;
+}
+
+#define WL_VNDR_IE_MAXLEN 2048
+static s8 g_mgmt_ie_buf[WL_VNDR_IE_MAXLEN];
+int
+wl_cfg80211_set_mgmt_vndr_ies(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
        s32 bssidx, s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len)
 {
        struct net_device *ndev = NULL;
@@ -19539,10 +20361,9 @@ _Pragma("GCC diagnostic pop")
                                struct parsed_vndr_ie_info *vndrie_info =
                                &old_vndr_ies.ie_info[i];
 
-                               WL_INFORM(("DELETED ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
+                               WL_INFORM(("DELETED ID : %d, Len: %d , OUI:"MACOUIDBG"\n",
                                        vndrie_info->vndrie.id, vndrie_info->vndrie.len,
-                                       vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1],
-                                       vndrie_info->vndrie.oui[2]));
+                                       MACOUI2STRDBG(vndrie_info->vndrie.oui)));
 
                                del_add_ie_buf_len = wl_cfgp2p_vndr_ie(cfg, curr_ie_buf,
                                        pktflag, vndrie_info->vndrie.oui,
@@ -19568,11 +20389,10 @@ _Pragma("GCC diagnostic pop")
                                struct parsed_vndr_ie_info *vndrie_info =
                                        &new_vndr_ies.ie_info[i];
 
-                               WL_INFORM(("ADDED ID : %d, Len: %d(%d), OUI:%02x:%02x:%02x\n",
+                               WL_INFORM(("ADDED ID : %d, Len: %d(%d), OUI:"MACOUIDBG"\n",
                                        vndrie_info->vndrie.id, vndrie_info->vndrie.len,
                                        vndrie_info->ie_len - 2,
-                                       vndrie_info->vndrie.oui[0], vndrie_info->vndrie.oui[1],
-                                       vndrie_info->vndrie.oui[2]));
+                                       MACOUI2STRDBG(vndrie_info->vndrie.oui)));
 
                                del_add_ie_buf_len = wl_cfgp2p_vndr_ie(cfg, curr_ie_buf,
                                        pktflag, vndrie_info->vndrie.oui,
@@ -19837,7 +20657,7 @@ wl_cfg80211_set_ulb_mode(struct net_device *dev, int mode)
        }
 
        /* setting of ulb_mode requires wl to be down */
-       ret = wldev_ioctl(dev, WLC_DOWN, NULL, 0, true);
+       ret = wldev_ioctl_set(dev, WLC_DOWN, NULL, 0);
        if (unlikely(ret)) {
                WL_ERR(("[ULB] WLC_DOWN command failed:[%d]\n", ret));
                return ret;
@@ -19854,7 +20674,7 @@ wl_cfg80211_set_ulb_mode(struct net_device *dev, int mode)
                return ret;
        }
 
-       ret = wldev_ioctl(dev, WLC_UP, NULL, 0, true);
+       ret = wldev_ioctl_set(dev, WLC_UP, NULL, 0);
        if (unlikely(ret)) {
                WL_ERR(("[ULB] WLC_DOWN command failed:[%d]\n", ret));
                return ret;
@@ -20138,6 +20958,7 @@ void wl_cfg80211_del_p2p_wdev(struct net_device *dev)
 }
 #endif /* WL_CFG80211_P2P_DEV_IF */
 
+#ifdef GTK_OFFLOAD_SUPPORT
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
 static s32
 wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
@@ -20174,6 +20995,7 @@ wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
        return err;
 }
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) */
+#endif /* GTK_OFFLOAD_SUPPORT */
 
 #if defined(WL_SUPPORT_AUTO_CHANNEL)
 int
@@ -20185,19 +21007,19 @@ wl_cfg80211_set_spect(struct net_device *dev, int spect)
        int err = BCME_OK;
 
        if (!wl_get_drv_status_all(cfg, CONNECTED)) {
-               err = wldev_ioctl(dev, WLC_DOWN, &wlc_down, sizeof(wlc_down), true);
+               err = wldev_ioctl_set(dev, WLC_DOWN, &wlc_down, sizeof(wlc_down));
                if (err) {
                        WL_ERR(("%s: WLC_DOWN failed: code: %d\n", __func__, err));
                        return err;
                }
 
-               err = wldev_ioctl(dev, WLC_SET_SPECT_MANAGMENT, &spect, sizeof(spect), true);
+               err = wldev_ioctl_set(dev, WLC_SET_SPECT_MANAGMENT, &spect, sizeof(spect));
                if (err) {
                        WL_ERR(("%s: error setting spect: code: %d\n", __func__, err));
                        return err;
                }
 
-               err = wldev_ioctl(dev, WLC_UP, &wlc_up, sizeof(wlc_up), true);
+               err = wldev_ioctl_set(dev, WLC_UP, &wlc_up, sizeof(wlc_up));
                if (err) {
                        WL_ERR(("%s: WLC_UP failed: code: %d\n", __func__, err));
                        return err;
@@ -20207,12 +21029,11 @@ wl_cfg80211_set_spect(struct net_device *dev, int spect)
 }
 
 int
-wl_cfg80211_get_sta_channel(struct net_device *dev)
+wl_cfg80211_get_sta_channel(struct bcm_cfg80211 *cfg)
 {
-       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
        int channel = 0;
 
-       if (wl_get_drv_status(cfg, CONNECTED, dev)) {
+       if (wl_get_drv_status(cfg, CONNECTED, bcmcfg_to_prmry_ndev(cfg))) {
                channel = cfg->channel;
        }
        return channel;
@@ -20594,6 +21415,31 @@ struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname)
        return ndev;
 }
 
+struct net_device*
+wl_get_netdev_by_name(struct bcm_cfg80211 *cfg, char *ifname)
+{
+       struct net_info *iter, *next;
+       struct net_device *ndev = NULL;
+
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+       for_each_ndev(cfg, iter, next) {
+               if (iter->ndev) {
+                       if (strncmp(iter->ndev->name, ifname, IFNAMSIZ) == 0) {
+                               ndev = iter->ndev;
+                               break;
+                       }
+               }
+       }
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+       return ndev;
+}
+
 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
 #define WLC_RATE_FLAG  0x80
 #define RATE_MASK              0x7f
@@ -20971,6 +21817,75 @@ wl_cfg80211_iface_count(struct net_device *dev)
        return iface_count;
 }
 
+#ifdef DHD_ABORT_SCAN_CREATE_INTERFACE
+int
+wl_abort_scan_and_check(struct bcm_cfg80211 *cfg)
+{
+       int wait_cnt = MAX_SCAN_ABORT_WAIT_CNT;
+       int ret = TRUE;
+
+       wl_cfg80211_scan_abort(cfg);
+       while (wl_get_drv_status_all(cfg, SCANNING) && wait_cnt) {
+               WL_DBG(("Waiting for SCANNING terminated, wait_cnt: %d\n", wait_cnt));
+               wait_cnt--;
+               OSL_SLEEP(WAIT_SCAN_ABORT_OSL_SLEEP_TIME);
+       }
+
+       if (!wait_cnt && wl_get_drv_status_all(cfg, SCANNING)) {
+               WL_ERR(("Failed to abort scan\n"));
+               ret = FALSE;
+       }
+
+       return ret;
+}
+#endif /* DHD_ABORT_SCAN_CREATE_INTERFACE */
+
+#ifdef DHD_USE_CHECK_DONGLE_IDLE
+#define CHECK_DONGLE_IDLE_TIME 50
+#define CHECK_DONGLE_IDLE_CNT  100
+
+int
+wl_check_dongle_idle(struct wiphy *wiphy)
+{
+       int error = 0;
+       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+       struct net_device *primary_ndev;
+       int retry = 0;
+       struct channel_info ci;
+
+       if (!cfg) {
+               return FALSE;
+       }
+
+       /* Use primary I/F for sending cmds down to firmware */
+       primary_ndev = bcmcfg_to_prmry_ndev(cfg);
+
+       while (retry++ < CHECK_DONGLE_IDLE_CNT) {
+               memset(&ci, 0, sizeof(ci));
+               error = wldev_ioctl_get(primary_ndev, WLC_GET_CHANNEL, &ci, sizeof(ci));
+               if (error != BCME_OK || ci.scan_channel != 0) {
+                       if (error == -ENODEV) {
+                               WL_ERR(("Firmware is not ready, return TRUE\n"));
+                               return TRUE;
+                       }
+                       WL_DBG(("Firmware is busy(err:%d scan channel:%d). wait %dms\n",
+                               error, ci.scan_channel, CHECK_DONGLE_IDLE_TIME));
+               } else {
+                       break;
+               }
+               wl_delay(CHECK_DONGLE_IDLE_TIME);
+       }
+       if (retry >= CHECK_DONGLE_IDLE_CNT) {
+               WL_ERR(("DONGLE is BUSY too long\n"));
+               return FALSE;
+       }
+       WL_DBG(("DONGLE is idle\n"));
+       return TRUE;
+}
+#undef CHECK_DONGLE_IDLE_TIME
+#undef CHECK_DONGLE_IDLE_CNT
+#endif /* DHD_USE_CHECK_DONGLE_IDLE */
+
 #ifdef WES_SUPPORT
 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
 s32 wl_cfg80211_custom_scan_time(struct net_device *dev,
@@ -21098,7 +22013,8 @@ static void wl_cfg80211_wbtext_update_rcc(struct bcm_cfg80211 *cfg, struct net_d
        if (!req_sent) {
                if ((cap_ie = bcm_parse_tlvs(conn_info->resp_ie, conn_info->resp_ie_len,
                                DOT11_MNG_EXT_CAP_ID)) != NULL) {
-                       if (isset(cap_ie->data, DOT11_EXT_CAP_BSSTRANS_MGMT)) {
+                       if (cap_ie->len >= DOT11_EXTCAP_LEN_BSSTRANS &&
+                                       isset(cap_ie->data, DOT11_EXT_CAP_BSSTRANS_MGMT)) {
                                wl_cfg80211_wbtext_send_btm_query(cfg, dev, profile);
                        }
                }
@@ -21249,10 +22165,8 @@ wl_cfg80211_recv_nbr_resp(struct net_device *dev, uint8 *body, int body_len)
                }
 
                ch = CH20MHZ_CHSPEC(nbr_rep_ie->channel);
-               WL_DBG(("ch:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       ch, nbr_rep_ie->bssid.octet[0], nbr_rep_ie->bssid.octet[1],
-                       nbr_rep_ie->bssid.octet[2],     nbr_rep_ie->bssid.octet[3],
-                       nbr_rep_ie->bssid.octet[4],     nbr_rep_ie->bssid.octet[5]));
+               WL_DBG(("ch:%d, bssid:"MACDBG"\n",
+                       ch, MAC2STRDBG(nbr_rep_ie->bssid.octet)));
 
                /* get RCC list */
                error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0,
@@ -21288,3 +22202,550 @@ wl_cfg80211_recv_nbr_resp(struct net_device *dev, uint8 *body, int body_len)
        return BCME_OK;
 }
 #endif /* WBTEXT */
+
+#ifdef DYNAMIC_MUMIMO_CONTROL
+void
+wl_set_murx_block_eapol_status(struct bcm_cfg80211 *cfg, int enable)
+{
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+
+       if (dhdp) {
+               dhdp->murx_block_eapol = enable;
+       }
+}
+
+bool
+wl_get_murx_reassoc_status(struct bcm_cfg80211 *cfg)
+{
+       int status = 0;
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+
+       if (dhdp) {
+               status = dhdp->reassoc_mumimo_sw;
+       }
+
+       return status ? TRUE : FALSE;
+}
+
+void
+wl_set_murx_reassoc_status(struct bcm_cfg80211 *cfg, int enable)
+{
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+
+       if (dhdp) {
+               dhdp->reassoc_mumimo_sw = enable;
+       }
+}
+
+int
+wl_check_bss_support_mumimo(struct net_device *dev)
+{
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       struct wiphy *wiphy = NULL;
+       struct cfg80211_bss *bss = NULL;
+       struct wlc_ssid *ssid = NULL;
+       struct wl_bss_info *bi = NULL;
+       bcm_tlv_t *vht_ie = NULL;
+       u8 *bssid = NULL;
+       u8 *ie = NULL;
+       u32 ie_len = 0;
+       u16 ie_mu_mimo_cap = 0;
+
+       if (!wl_get_drv_status(cfg, CONNECTED, dev)) {
+               WL_DBG(("Not associated\n"));
+               return BCME_ERROR;
+       }
+
+       wiphy = bcmcfg_to_wiphy(cfg);
+       ssid = (struct wlc_ssid *)wl_read_prof(cfg, dev, WL_PROF_SSID);
+       bssid = (u8 *)wl_read_prof(cfg, dev, WL_PROF_BSSID);
+
+       if (wiphy && ssid && bssid) {
+               bss = CFG80211_GET_BSS(wiphy, NULL, bssid,
+                       ssid->SSID, ssid->SSID_len);
+       } else {
+               WL_DBG(("Could not find the associated AP\n"));
+               return FALSE;
+       }
+
+       if (bss) {
+#if defined(WL_CFG80211_P2P_DEV_IF)
+               ie = (u8 *)bss->ies->data;
+               ie_len = bss->ies->len;
+#else
+               ie = bss->information_elements;
+               ie_len = bss->len_information_elements;
+#endif /* WL_CFG80211_P2P_DEV_IF */
+               bi = (struct wl_bss_info *)(cfg->extra_buf + 4);
+               if (bi && bi->vht_cap) {
+                       vht_ie = bcm_parse_tlvs(ie, ie_len, DOT11_MNG_VHT_CAP_ID);
+                       if (vht_ie) {
+                               ie_mu_mimo_cap = (vht_ie->data[2] & 0x08) >> 3;
+                       }
+               }
+               CFG80211_PUT_BSS(wiphy, bss);
+       }
+
+       return ie_mu_mimo_cap ? TRUE : FALSE;
+}
+
+int
+wl_get_murx_bfe_cap(struct net_device *dev, int *cap)
+{
+       int err;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+
+       /* Now there is only single interface */
+       err = wldev_iovar_getbuf_bsscfg(dev, "murx_bfe_cap",
+               NULL, 0, cfg->ioctl_buf, WLC_IOCTL_SMLEN, 0, &cfg->ioctl_buf_sync);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to get murx_bfe_cap IOVAR, error = %d\n", err));
+               return err;
+       }
+
+       memcpy(cap, cfg->ioctl_buf, sizeof(*cap));
+
+       return err;
+}
+
+int
+wl_set_murx_bfe_cap(struct net_device *dev, int val, bool reassoc_req)
+{
+       int err;
+       int cur_val;
+       int iface_count = wl_cfg80211_iface_count(dev);
+       struct ether_addr bssid;
+       wl_reassoc_params_t params;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+
+       if (iface_count > 1) {
+               WL_ERR(("murx_bfe_cap change is not allowed when "
+                       "there are multiple interfaces\n"));
+               return -EINVAL;
+       }
+
+       if (reassoc_req && wl_get_murx_reassoc_status(cfg)) {
+               WL_ERR(("Reassociation is in progress...\n"));
+               return BCME_OK;
+       }
+
+       /* Check the current value */
+       err = wl_get_murx_bfe_cap(dev, &cur_val);
+       if (err) {
+               return err;
+       }
+
+       if (cur_val == val) {
+               /* We don't need to configure the new value. */
+               WL_DBG(("Already set murx_bfe_cap to %d\n", val));
+               return BCME_OK;
+       }
+
+       /* Now there is only single interface */
+       err = wldev_iovar_setbuf_bsscfg(dev, "murx_bfe_cap", (void *)&val,
+               sizeof(val), cfg->ioctl_buf, WLC_IOCTL_SMLEN, 0,
+               &cfg->ioctl_buf_sync);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to set murx_bfe_cap IOVAR to %d,"
+                       "error %d\n", val, err));
+               return err;
+       }
+
+       if (reassoc_req) {
+               DHD_DISABLE_RUNTIME_PM(dhdp);
+
+               /* Enable Tx flow control not to send any data frames to dongle
+                * while reassociation procedure is in progress
+                */
+               dhd_txflowcontrol(dhdp, ALL_INTERFACES, ON);
+
+               /* If successful intiate a reassoc */
+               if ((err = wldev_ioctl_get(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN)) < 0) {
+                       WL_ERR(("Failed to get bssid, error=%d\n", err));
+                       DHD_ENABLE_RUNTIME_PM(dhdp);
+                       dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF);
+                       return err;
+               }
+
+               bzero(&params, sizeof(wl_reassoc_params_t));
+               memcpy(&params.bssid, &bssid, ETHER_ADDR_LEN);
+
+               if ((err = wldev_ioctl_set(dev, WLC_REASSOC, &params,
+                       sizeof(wl_reassoc_params_t))) < 0) {
+                       WL_ERR(("reassoc failed err:%d\n", err));
+                       DHD_ENABLE_RUNTIME_PM(dhdp);
+                       dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF);
+                       /* configure previous value */
+                       err = wldev_iovar_setbuf_bsscfg(dev, "murx_bfe_cap", (void *)&cur_val,
+                               sizeof(val), cfg->ioctl_buf, WLC_IOCTL_SMLEN, 0,
+                               &cfg->ioctl_buf_sync);
+                       if (unlikely(err)) {
+                               WL_ERR(("Failed to set murx_bfe_cap IOVAR to %d,"
+                                       "error %d\n", val, err));
+                       }
+                       wl_set_murx_reassoc_status(cfg, FALSE);
+               } else {
+                       WL_ERR(("reassoc issued successfully\n"));
+                       wl_set_murx_reassoc_status(cfg, TRUE);
+                       wl_set_murx_block_eapol_status(cfg, TRUE);
+               }
+       }
+
+       return err;
+}
+#endif /* DYNAMIC_MUMIMO_CONTROL */
+
+#ifdef SUPPORT_SET_CAC
+static void
+wl_cfg80211_set_cac(struct bcm_cfg80211 *cfg, int enable)
+{
+       int ret = 0;
+       dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+
+#ifdef SUPPORT_CUSTOM_SET_CAC
+       if (cfg->enable_cac == 0) {
+               WL_DBG(("enable_cac %d\n", cfg->enable_cac));
+               enable = 0;
+       }
+#endif /* SUPPORT_CUSTOM_SET_CAC */
+
+       WL_DBG(("cac enable %d, op_mode 0x%04x\n", enable, dhd->op_mode));
+       if (!dhd) {
+               WL_ERR(("dhd is NULL\n"));
+               return;
+       }
+       if (enable && ((dhd->op_mode & DHD_FLAG_HOSTAP_MODE) ||
+                       (dhd->op_mode & DHD_FLAG_P2P_GC_MODE) ||
+                       (dhd->op_mode & DHD_FLAG_P2P_GO_MODE))) {
+               WL_ERR(("op_mode 0x%04x\n", dhd->op_mode));
+               enable = 0;
+       }
+       if ((ret = dhd_wl_ioctl_set_intiovar(dhd, "cac", enable,
+                       WLC_SET_VAR, TRUE, 0)) < 0) {
+               WL_ERR(("Failed set CAC, ret=%d\n", ret));
+       } else {
+               WL_DBG(("CAC set successfully\n"));
+       }
+       return;
+}
+
+int
+wl_cfg80211_enable_cac(struct net_device *dev, int enable)
+{
+       struct bcm_cfg80211 *cfg  = wl_get_cfg(dev);
+
+       WL_DBG(("enable %d\n", enable));
+
+#ifdef SUPPORT_CUSTOM_SET_CAC
+       cfg->enable_cac = enable;
+#endif /* SUPPORT_CUSTOM_SET_CAC */
+       wl_cfg80211_set_cac(cfg, enable);
+       return 0;
+}
+#endif /* SUPPORT_SET_CAC */
+
+#ifdef SUPPORT_RSSI_SUM_REPORT
+int
+wl_get_rssi_per_ant(struct net_device *dev, char *ifname, char *peer_mac, void *param)
+{
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       wl_rssi_ant_mimo_t *get_param = (wl_rssi_ant_mimo_t *)param;
+       rssi_ant_param_t *set_param = NULL;
+       struct net_device *ifdev = NULL;
+       char iobuf[WLC_IOCTL_SMLEN];
+       int err = BCME_OK;
+       int iftype = 0;
+
+       memset(iobuf, 0, WLC_IOCTL_SMLEN);
+
+       /* Check the interface type */
+       ifdev = wl_get_netdev_by_name(cfg, ifname);
+       if (ifdev == NULL) {
+               WL_ERR(("Could not find net_device for ifname:%s\n", ifname));
+               err = BCME_BADARG;
+               goto fail;
+       }
+
+       iftype = ifdev->ieee80211_ptr->iftype;
+       if (iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO) {
+               if (peer_mac) {
+                       set_param = (rssi_ant_param_t *)kzalloc(sizeof(rssi_ant_param_t),
+                               GFP_KERNEL);
+                       err = wl_cfg80211_ether_atoe(peer_mac, &set_param->ea);
+                       if (!err) {
+                               WL_ERR(("Invalid Peer MAC format\n"));
+                               err = BCME_BADARG;
+                               goto fail;
+                       }
+               } else {
+                       WL_ERR(("Peer MAC is not provided for iftype %d\n", iftype));
+                       err = BCME_BADARG;
+                       goto fail;
+               }
+       }
+
+       err = wldev_iovar_getbuf(ifdev, "phy_rssi_ant", peer_mac ?
+               (void *)&(set_param->ea) : NULL, peer_mac ? ETHER_ADDR_LEN : 0,
+               (void *)iobuf, sizeof(iobuf), NULL);
+       if (unlikely(err)) {
+               WL_ERR(("Failed to get rssi info, err=%d\n", err));
+       } else {
+               memcpy(get_param, iobuf, sizeof(wl_rssi_ant_mimo_t));
+               if (get_param->count == 0) {
+                       WL_ERR(("Not supported on this chip\n"));
+                       err = BCME_UNSUPPORTED;
+               }
+       }
+
+fail:
+       if (set_param) {
+               kfree(set_param);
+       }
+
+       return err;
+}
+
+int
+wl_get_rssi_logging(struct net_device *dev, void *param)
+{
+       rssilog_get_param_t *get_param = (rssilog_get_param_t *)param;
+       char iobuf[WLC_IOCTL_SMLEN];
+       int err = BCME_OK;
+
+       memset(iobuf, 0, WLC_IOCTL_SMLEN);
+       memset(get_param, 0, sizeof(*get_param));
+       err = wldev_iovar_getbuf(dev, "rssilog", NULL, 0, (void *)iobuf,
+               sizeof(iobuf), NULL);
+       if (err) {
+               WL_ERR(("Failed to get rssi logging info, err=%d\n", err));
+       } else {
+               memcpy(get_param, iobuf, sizeof(*get_param));
+       }
+
+       return err;
+}
+
+int
+wl_set_rssi_logging(struct net_device *dev, void *param)
+{
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       rssilog_set_param_t *set_param = (rssilog_set_param_t *)param;
+       int err;
+
+       err = wldev_iovar_setbuf(dev, "rssilog", set_param,
+               sizeof(*set_param), cfg->ioctl_buf, WLC_IOCTL_SMLEN,
+               &cfg->ioctl_buf_sync);
+       if (err) {
+               WL_ERR(("Failed to set rssi logging param, err=%d\n", err));
+       }
+
+       return err;
+}
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+#ifdef WL_IRQSET
+static void wl_irq_set_work_handler(struct work_struct * work)
+{
+       struct bcm_cfg80211 *cfg = NULL;
+       BCM_SET_CONTAINER_OF(cfg, work, struct bcm_cfg80211, irq_set_work.work);
+
+       if (cfg) {
+               dhd_irq_set_affinity(cfg->pub);
+       }
+}
+#endif /* WL_IRQSET */
+
+#ifdef APSTA_RESTRICTED_CHANNEL
+#define CMD_BLOCK_CH   "block_ch"
+#define BAND5G_CHANNELS_BLOCK_OP1      999
+#define BAND5G_CHANNELS_BLOCK_OP2      -1
+
+s32
+wl_cfg80211_set_indoor_channels(struct net_device *ndev, char *command, int total_len)
+{
+       uint i = 0, j = 0;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+       wl_block_ch_t *block_ch = NULL;
+       int block_ch_len = 0;
+       int err = BCME_OK;
+       ulong channel_num = 0;
+       ulong channel = 0;
+       char *pos, *token;
+       u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)];
+       wl_uint32_list_t *list;
+       u32 n_valid_chan = 0;
+       bool band5g_all_ch = FALSE;
+
+       BCM_REFERENCE(total_len);
+
+       pos = command;
+       /* drop command */
+       token = bcmstrtok(&pos, " ", NULL);
+       /* number of channel */
+       token = bcmstrtok(&pos, " ", NULL);
+
+       if (token == NULL) {
+               err = BCME_BADARG;
+               goto exit;
+       }
+
+       channel_num = bcm_strtoul(token, NULL, 0);
+       if (token == NULL) {
+               err = BCME_BADARG;
+               goto exit;
+       }
+
+       if ((channel_num == BAND5G_CHANNELS_BLOCK_OP1) ||
+               (channel_num == BAND5G_CHANNELS_BLOCK_OP2)) {
+
+               band5g_all_ch = TRUE;
+
+               if ((err = wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) < 0) {
+                       WL_ERR(("Failed to get valid channels - err %d\n", err));
+                       goto exit;
+               } else {
+                       list = (wl_uint32_list_t *) chan_buf;
+                       n_valid_chan = dtoh32(list->count);
+                       channel_num = 0;
+
+                       if (n_valid_chan > WL_NUMCHANNELS) {
+                               WL_ERR(("wrong n_valid_chan:%d\n", n_valid_chan));
+                               err = BCME_OUTOFRANGECHAN;
+                               goto exit;
+                       }
+
+                       for (i = 0; i < n_valid_chan; i++) {
+                               if (CHANNEL_IS_5G(dtoh32(list->element[i])))  {
+                                       channel_num++;
+                               }
+                       }
+                       if (channel_num == 0) {
+                               WL_ERR(("5G channels are not supported\n"));
+                               err = BCME_BADCHAN;
+                               goto exit;
+                       }
+               }
+       } else if (channel_num > MAXCHANNEL_NUM) {
+               WL_ERR(("Out of Range. Max channel number is %d\n", MAXCHANNEL_NUM));
+               err = BCME_RANGE;
+               goto exit;
+       }
+
+       block_ch_len = OFFSETOF(wl_block_ch_t, channel) + channel_num;
+       block_ch = (wl_block_ch_t *)MALLOCZ(dhdp->osh, block_ch_len);
+
+       if (unlikely(!block_ch)) {
+               WL_ERR(("Failed to allocate memory\n"));
+               err = BCME_NOMEM;
+               goto exit;
+       }
+       memset(block_ch, 0, block_ch_len);
+
+       block_ch->version = WL_BLOCK_CHANNEL_VER_1;
+       block_ch->len = block_ch_len;
+       block_ch->band = WF_CHAN_FACTOR_5_G;
+       block_ch->channel_num = channel_num;
+
+       if (band5g_all_ch) {
+               for (i = 0; i < n_valid_chan; i++) {
+                       channel = dtoh32(list->element[i]);
+                       if (CHANNEL_IS_5G(channel)) {
+                               block_ch->channel[j] = channel;
+                               j++;
+                               if (j >= channel_num) {
+                                       break;
+                               }
+                       }
+               }
+       } else {
+               for (i = 0; i < channel_num; i++) {
+                       token = bcmstrtok(&pos, " ", NULL);
+                       if (token == NULL) {
+                               err = BCME_BADARG;
+                               goto exit;
+                       }
+                       channel = bcm_strtoul(token, NULL, 0);
+
+                       if (!CHANNEL_IS_5G(channel)) {
+                               WL_ERR(("%d is Invalid Channel!\n", block_ch->channel[i]));
+                               err = BCME_BADCHAN;
+                               goto exit;
+                       }
+                       block_ch->channel[i] = channel;
+               }
+       }
+
+       /* Setting block channel list to fw */
+       if ((err = wldev_iovar_setbuf(ndev, CMD_BLOCK_CH, block_ch, block_ch->len,
+               cfg->ioctl_buf, WLC_IOCTL_SMLEN,  &cfg->ioctl_buf_sync))) {
+               WL_ERR(("Setting block_ch failed with err = %d\n", err));
+               goto exit;
+       }
+exit:
+       if (err == BCME_BADARG) {
+               WL_ERR(("Failed due to Bad Argument!\n"));
+       }
+       if (block_ch) {
+               MFREE(dhdp->osh, block_ch, block_ch_len);
+       }
+       return err;
+}
+
+s32
+wl_cfg80211_get_indoor_channels(struct net_device *ndev, char *command, int total_len)
+{
+       uint i = 0;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
+       dhd_pub_t *dhdp = (dhd_pub_t *)(cfg->pub);
+       wl_block_ch_t *iov_buf = NULL;
+       wl_block_ch_t *block_ch = NULL;
+       int data_len = 0;
+       int err = BCME_OK;
+       char *pos;
+
+       pos = command;
+       /* Get operation */
+
+       data_len = OFFSETOF(wl_block_ch_t, channel);
+       iov_buf = (wl_block_ch_t *)MALLOCZ(dhdp->osh, data_len);
+       if (iov_buf == NULL) {
+               WL_ERR(("Fail to allocate memory\n"));
+               err = BCME_NOMEM;
+               goto exit;
+       }
+       memset(iov_buf, 0, data_len);
+
+       iov_buf->version = WL_BLOCK_CHANNEL_VER_1;
+       iov_buf->len = data_len;
+       iov_buf->band = WF_CHAN_FACTOR_5_G;
+       iov_buf->channel_num = 0;
+
+       if ((err = wldev_iovar_getbuf(ndev, CMD_BLOCK_CH, iov_buf, data_len,
+               cfg->ioctl_buf, WLC_IOCTL_SMLEN,  &cfg->ioctl_buf_sync)) < 0) {
+               WL_ERR(("Setting block_ch failed with err=%d \n", err));
+               goto exit;
+       }
+       block_ch = (wl_block_ch_t *)cfg->ioctl_buf;
+
+       if (block_ch->version != WL_BLOCK_CHANNEL_VER_1) {
+               WL_ERR(("Version mismatched! actual %d expected: %d\n",
+                       block_ch->version, WL_BLOCK_CHANNEL_VER_1));
+               err = BCME_ERROR;
+               goto exit;
+       }
+       if (block_ch->channel_num) {
+               pos += snprintf(pos, total_len, "%d ", block_ch->channel_num);
+               for (i = 0; i < block_ch->channel_num; i++) {
+                       pos += snprintf(pos, total_len, "%d ", block_ch->channel[i]);
+               }
+               err = (pos - command);
+       }
+exit:
+       if (iov_buf) {
+               MFREE(dhdp->osh, iov_buf, data_len);
+       }
+       return err;
+}
+
+#endif /* APSTA_RESTRICTED_CHANNEL */
index 8cacf17c351a2f2eeba54942c95baa9811a214e4..034eae5135c4a29f38ff14d5aa827929ae71201c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_cfg80211.h 680309 2017-01-19 12:00:05Z $
+ * $Id: wl_cfg80211.h 750618 2018-03-07 11:14:10Z $
  */
 
 /**
@@ -97,6 +97,13 @@ do { \
                DHD_LOG_DUMP_WRITE args;        \
        }       \
 } while (0)
+#define WL_ERR_KERN(args)      \
+do {   \
+       if (wl_dbg_level & WL_DBG_ERR) {        \
+               printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__);        \
+               printk args;    \
+       }       \
+} while (0)
 #define        WL_ERR_MEM(args)        \
 do {   \
        if (wl_dbg_level & WL_DBG_ERR) {        \
@@ -121,6 +128,7 @@ do {                                                                                \
                        printk args;                                            \
                }                                                               \
 } while (0)
+#define WL_ERR_KERN(args) WL_ERR(args)
 #define WL_ERR_MEM(args) WL_ERR(args)
 #define WL_ERR_EX(args) WL_ERR(args)
 #endif /* DHD_LOG_DUMP */
@@ -132,6 +140,7 @@ do {                                                                                \
                        printk args;                                            \
                }                                                               \
 } while (0)
+#define WL_ERR_KERN(args) WL_ERR(args)
 #define WL_ERR_MEM(args) WL_ERR(args)
 #define WL_ERR_EX(args) WL_ERR(args)
 #endif /* defined(DHD_DEBUG) */
@@ -244,6 +253,10 @@ do {                                                                       \
 #define WL_SCB_MAX_PROBE       3
 #endif
 
+#ifndef WL_PSPRETEND_RETRY_LIMIT
+#define WL_PSPRETEND_RETRY_LIMIT 1
+#endif
+
 #ifndef WL_MIN_PSPRETEND_THRESHOLD
 #define WL_MIN_PSPRETEND_THRESHOLD     2
 #endif
@@ -511,12 +524,12 @@ struct net_info {
 };
 
 /* association inform */
-#define MAX_REQ_LINE 1024
+#define MAX_REQ_LINE 1024u
 struct wl_connect_info {
        u8 req_ie[MAX_REQ_LINE];
-       s32 req_ie_len;
+       u32 req_ie_len;
        u8 resp_ie[MAX_REQ_LINE];
-       s32 resp_ie_len;
+       u32 resp_ie_len;
 };
 
 /* firmware /nvram downloading controller */
@@ -653,10 +666,47 @@ typedef struct ap_rps_info {
 } ap_rps_info_t;
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
 
+#ifdef SUPPORT_RSSI_SUM_REPORT
+#define RSSILOG_FLAG_FEATURE_SW                0x1
+#define RSSILOG_FLAG_REPORT_READY      0x2
+typedef struct rssilog_set_param {
+       uint8 enable;
+       uint8 rssi_threshold;
+       uint8 time_threshold;
+       uint8 pad;
+} rssilog_set_param_t;
+
+typedef struct rssilog_get_param {
+       uint8 report_count;
+       uint8 enable;
+       uint8 rssi_threshold;
+       uint8 time_threshold;
+} rssilog_get_param_t;
+
+typedef struct rssi_ant_param {
+       struct ether_addr ea;
+       chanspec_t chanspec;
+} rssi_ant_param_t;
+
+typedef struct wl_rssi_ant_mimo {
+       uint32 version;
+       uint32 count;
+       int8 rssi_ant[WL_RSSI_ANT_MAX];
+       int8 rssi_sum;
+       int8 PAD[3];
+} wl_rssi_ant_mimo_t;
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+
 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
 #define GET_BSS_INFO_LEN 90
 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
 
+#ifdef DHD_LB_IRQSET
+#if defined(CONFIG_ARCH_MSM8998) || defined(CONFIG_ARCH_SDM845)
+#define WL_IRQSET
+#endif /* CONFIG_ARCH_MSM8998 | CONFIG_ARCH_SDM845) */
+#endif /* DHD_LB_IRQSET */
+
 #ifdef WES_SUPPORT
 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
 #define CUSTOMER_WL_SCAN_TIMER_INTERVAL_MS     25000 /* Scan timeout */
@@ -691,6 +741,7 @@ struct bcm_cfg80211 {
        struct completion iface_disable;
        struct completion wait_next_af;
        struct mutex usr_sync;  /* maily for up/down synchronization */
+       struct mutex if_sync;   /* maily for iface op synchronization */
        struct mutex scan_complete;     /* serialize scan_complete call */
        struct wl_scan_results *bss_list;
        struct wl_scan_results *scan_results;
@@ -784,6 +835,9 @@ struct bcm_cfg80211 {
        struct mutex event_sync;        /* maily for up/down synchronization */
        bool disable_roam_event;
        struct delayed_work pm_enable_work;
+#ifdef WL_IRQSET
+       struct delayed_work irq_set_work;
+#endif /* WL_IRQSET */
        struct workqueue_struct *event_workq;   /* workqueue for event */
        struct work_struct event_work;          /* work item for event */
        struct mutex pm_sync;   /* mainly for pm work synchronization */
@@ -864,6 +918,14 @@ struct bcm_cfg80211 {
 #ifdef WBTEXT
        struct list_head wbtext_bssid_list;
 #endif /* WBTEXT */
+       struct list_head vndr_oui_list;
+       spinlock_t vndr_oui_sync;       /* to protect vndr_oui_list */
+#ifdef STAT_REPORT
+       void *stat_report_info;
+#endif
+#ifdef SUPPORT_CUSTOM_SET_CAC
+       int enable_cac;
+#endif /* SUPPORT_CUSTOM_SET_CAC */
 };
 
 #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
@@ -1554,6 +1616,7 @@ extern s32 wl_cfg80211_get_bss_info(struct net_device *dev, char* cmd, int total
 extern s32 wl_cfg80211_get_connect_failed_status(struct net_device *dev, char* cmd, int total_len);
 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
 extern struct bcm_cfg80211 *wl_get_cfg(struct net_device *ndev);
+extern s32 wl_cfg80211_set_if_band(struct net_device *ndev, int band);
 
 #define SCAN_BUF_CNT   2
 #define SCAN_BUF_NEXT  1
@@ -1689,7 +1752,7 @@ extern void wl_cfg80211_del_p2p_wdev(struct net_device *dev);
 #endif /* WL_CFG80211_P2P_DEV_IF */
 #if defined(WL_SUPPORT_AUTO_CHANNEL)
 extern int wl_cfg80211_set_spect(struct net_device *dev, int spect);
-extern int wl_cfg80211_get_sta_channel(struct net_device *dev);
+extern int wl_cfg80211_get_sta_channel(struct bcm_cfg80211 *cfg);
 #endif /* WL_SUPPORT_AUTO_CHANNEL */
 
 #ifdef P2P_LISTEN_OFFLOADING
@@ -1728,6 +1791,40 @@ int wl_set_ap_rps(struct net_device *dev, bool enable, char *ifname);
 int wl_update_ap_rps_params(struct net_device *dev, ap_rps_info_t* rps, char *ifname);
 void wl_cfg80211_init_ap_rps(struct bcm_cfg80211 *cfg);
 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
+#ifdef SUPPORT_RSSI_SUM_REPORT
+int wl_get_rssi_logging(struct net_device *dev, void *param);
+int wl_set_rssi_logging(struct net_device *dev, void *param);
+int wl_get_rssi_per_ant(struct net_device *dev, char *ifname, char *peer_mac, void *param);
+#endif /* SUPPORT_RSSI_SUM_REPORT */
+#ifdef DYNAMIC_MUMIMO_CONTROL
+void wl_set_murx_block_eapol_status(struct bcm_cfg80211 *cfg, int enable);
+bool wl_get_murx_reassoc_status(struct bcm_cfg80211 *cfg);
+void wl_set_murx_reassoc_status(struct bcm_cfg80211 *cfg, int enable);
+int wl_check_bss_support_mumimo(struct net_device *dev);
+int wl_get_murx_bfe_cap(struct net_device *dev, int *cap);
+int wl_set_murx_bfe_cap(struct net_device *dev, int val, bool reassoc_req);
+#endif /* DYNAMIC_MUMIMO_CONTROL */
 int wl_cfg80211_iface_count(struct net_device *dev);
 struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname);
+struct net_device* wl_get_netdev_by_name(struct bcm_cfg80211 *cfg, char *ifname);
+int wl_cfg80211_get_vndr_ouilist(struct bcm_cfg80211 *cfg, uint8 *buf, int max_cnt);
+#ifdef SUPPORT_SET_CAC
+extern int wl_cfg80211_enable_cac(struct net_device *dev, int enable);
+#endif /* SUPPORT_SET_CAC */
+#ifdef DHD_USE_CHECK_DONGLE_IDLE
+int wl_check_dongle_idle(struct wiphy *wiphy);
+#else
+static inline int wl_check_dongle_idle(struct wiphy *wiphy)
+{
+       return TRUE;
+}
+#endif /* DHD_USE_CHECK_DONGLE_IDLE */
+#ifdef DHD_ABORT_SCAN_CREATE_INTERFACE
+extern int wl_abort_scan_and_check(struct bcm_cfg80211 *cfg);
+#else
+static inline int wl_abort_scan_and_check(struct bcm_cfg80211 *cfg)
+{
+       return TRUE;
+}
+#endif /* DHD_ABORT_SCAN_CREATE_INTERFACE */
 #endif /* _wl_cfg80211_h_ */
index 4fb9b21a81101586f60fad88206e8092dcbb6898..4a9b5daeb8e450fcc2dc4dacb163457ab99c6799 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 driver - Dongle Host Driver (DHD) related
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_cfg_btcoex.c 656598 2016-08-29 08:30:40Z $
+ * $Id: wl_cfg_btcoex.c 748337 2018-02-22 11:50:54Z $
  */
 
 #include <net/rtnetlink.h>
@@ -94,7 +94,7 @@ dev_wlc_intvar_get_reg(struct net_device *dev, char *name,
 
        bcm_mkiovar(name, (char *)(&reg), sizeof(reg),
                (char *)(&var), sizeof(var.buf));
-       error = wldev_ioctl(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf), false);
+       error = wldev_ioctl_get(dev, WLC_GET_VAR, (char *)(&var), sizeof(var.buf));
 
        *retval = dtoh32(var.val);
        return (error);
@@ -107,7 +107,7 @@ dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len)
 
        bcm_mkiovar(name, buf, len, ioctlbuf_local, sizeof(ioctlbuf_local));
 
-       return (wldev_ioctl(dev, WLC_SET_VAR, ioctlbuf_local, sizeof(ioctlbuf_local), true));
+       return (wldev_ioctl_set(dev, WLC_SET_VAR, ioctlbuf_local, sizeof(ioctlbuf_local)));
 }
 /*
 get named driver variable to uint register value and return error indication
@@ -448,8 +448,7 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, dhd_pub_t *dhd, char *co
                dhd->dhcp_in_progress = 1;
 
 #if defined(WL_VIRTUAL_APSTA) && defined(APSTA_BLOCK_ARP_DURING_DHCP)
-               if ((dhd->op_mode & DHD_FLAG_CONCURR_STA_HOSTAP_MODE) ==
-                       DHD_FLAG_CONCURR_STA_HOSTAP_MODE) {
+               if (DHD_OPMODE_STA_SOFTAP_CONCURR(dhd)) {
                        /* Block ARP frames while DHCP of STA interface is in
                         * progress in case of STA/SoftAP concurrent mode
                         */
@@ -509,8 +508,7 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, dhd_pub_t *dhd, char *co
                WL_TRACE_HW4(("DHCP is complete \n"));
 
 #if defined(WL_VIRTUAL_APSTA) && defined(APSTA_BLOCK_ARP_DURING_DHCP)
-               if ((dhd->op_mode & DHD_FLAG_CONCURR_STA_HOSTAP_MODE) ==
-                       DHD_FLAG_CONCURR_STA_HOSTAP_MODE) {
+               if (DHD_OPMODE_STA_SOFTAP_CONCURR(dhd)) {
                        /* Unblock ARP frames */
                        wl_cfg80211_block_arp(dev, FALSE);
                } else
index 39682b5dc9c5e0318128dc0cb0addecb33df24a1..3b87b69daf79c6266d15073c811d5e36affb0147 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Neighbor Awareness Networking
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index a609af3d2684265026acd4dc40a2a6a087813009..ace9671374200cc0439f168b486a100e78b35810 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Neighbor Awareness Networking
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 93587a273c56c4313e381ee38657a6632448ced4..e1f4676a3a9dbcf85d3d16f73a06dc06011a8c49 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfgp2p driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_cfgp2p.c 680286 2017-01-19 09:37:30Z $
+ * $Id: wl_cfgp2p.c 699163 2017-05-12 05:18:23Z $
  *
  */
 #include <typedefs.h>
@@ -392,7 +392,7 @@ wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg)
        }
        if (val == 0) {
                val = 1;
-               ret = wldev_ioctl(ndev, WLC_DOWN, &val, sizeof(s32), true);
+               ret = wldev_ioctl_set(ndev, WLC_DOWN, &val, sizeof(s32));
                if (ret < 0) {
                        CFGP2P_ERR(("WLC_DOWN error %d\n", ret));
                        return ret;
@@ -405,7 +405,7 @@ wl_cfgp2p_set_firm_p2p(struct bcm_cfg80211 *cfg)
                        return ret;
                }
 
-               ret = wldev_ioctl(ndev, WLC_UP, &val, sizeof(s32), true);
+               ret = wldev_ioctl_set(ndev, WLC_UP, &val, sizeof(s32));
                if (ret < 0) {
                        CFGP2P_ERR(("WLC_UP error %d\n", ret));
                        return ret;
@@ -1981,8 +1981,8 @@ wl_cfgp2p_set_p2p_ps(struct bcm_cfg80211 *cfg, struct net_device *ndev, char* bu
                }
 
                if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) {
-                       ret = wldev_ioctl(dev,
-                               WLC_SET_PM, &legacy_ps, sizeof(legacy_ps), true);
+                       ret = wldev_ioctl_set(dev,
+                               WLC_SET_PM, &legacy_ps, sizeof(legacy_ps));
                        if (unlikely(ret))
                                CFGP2P_ERR(("error (%d)\n", ret));
                        wl_cfg80211_update_power_mode(dev);
index 81451eccbf655c39a0ab0fcfd88dc7cf2de45618..7eb1881b485acdd9056f31fe6369307f4cd8e395 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfgp2p driver
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index adea17daf74e6bd48b6b5800519c20a4a1672f3e..d6d376481b600db0567e6816fb74035c6c6c4336 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 Vendor Extension Code
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_cfgvendor.c 681171 2017-01-25 05:27:08Z $
+ * $Id: wl_cfgvendor.c 744879 2018-02-06 02:45:32Z $
  */
 
 /*
 #endif
 #include <brcm_nl80211.h>
 
+#ifdef STAT_REPORT
+#include <wl_statreport.h>
+#endif
+
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
 
 /*
@@ -202,22 +206,24 @@ wl_cfgvendor_set_rand_mac_oui(struct wiphy *wiphy,
        int err = 0;
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
        int type;
-       uint8 random_mac_oui[DOT11_OUI_LEN];
 
        type = nla_type(data);
 
        if (type == ANDR_WIFI_ATTRIBUTE_RANDOM_MAC_OUI) {
-               memcpy(random_mac_oui, nla_data(data), DOT11_OUI_LEN);
-
-               err = dhd_dev_cfg_rand_mac_oui(bcmcfg_to_prmry_ndev(cfg), random_mac_oui);
+               if (nla_len(data) != DOT11_OUI_LEN) {
+                       WL_ERR(("nla_len not matched.\n"));
+                       err = -EINVAL;
+                       goto exit;
+               }
+               err = dhd_dev_cfg_rand_mac_oui(bcmcfg_to_prmry_ndev(cfg), nla_data(data));
 
                if (unlikely(err))
                        WL_ERR(("Bad OUI, could not set:%d \n", err));
 
        } else {
-               err = -1;
+               err = -EINVAL;
        }
-
+exit:
        return err;
 }
 #ifdef CUSTOM_FORCE_NODFS_FLAG
@@ -988,86 +994,6 @@ wl_cfgvendor_set_batch_scan_cfg(struct wiphy *wiphy,
        return err;
 }
 
-static int
-wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy,
-       struct wireless_dev *wdev, const void  *data, int len)
-{
-       int err = 0;
-       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
-       gscan_swc_params_t *significant_params;
-       int tmp, tmp1, tmp2, type, j = 0;
-       const struct nlattr *outer, *inner, *iter;
-       bool flush = FALSE;
-       wl_pfn_significant_bssid_t *pbssid;
-
-       significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL);
-       if (!significant_params) {
-               WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len));
-               return -ENOMEM;
-       }
-
-
-       nla_for_each_attr(iter, data, len, tmp2) {
-               type = nla_type(iter);
-
-               switch (type) {
-                       case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH:
-                       flush = (bool) nla_get_u8(iter);
-                       break;
-                       case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE:
-                               significant_params->rssi_window = nla_get_u16(iter);
-                               break;
-                       case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE:
-                               significant_params->lost_ap_window = nla_get_u16(iter);
-                               break;
-                       case GSCAN_ATTRIBUTE_MIN_BREACHING:
-                               significant_params->swc_threshold = nla_get_u16(iter);
-                               break;
-                       case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS:
-                               pbssid = significant_params->bssid_elem_list;
-                               nla_for_each_nested(outer, iter, tmp) {
-                                       nla_for_each_nested(inner, outer, tmp1) {
-                                                       switch (nla_type(inner)) {
-                                                               case GSCAN_ATTRIBUTE_BSSID:
-                                                               memcpy(&(pbssid[j].macaddr),
-                                                                    nla_data(inner),
-                                                                    ETHER_ADDR_LEN);
-                                                               break;
-                                                               case GSCAN_ATTRIBUTE_RSSI_HIGH:
-                                                               pbssid[j].rssi_high_threshold =
-                                                                      (int8) nla_get_u8(inner);
-                                                               break;
-                                                               case GSCAN_ATTRIBUTE_RSSI_LOW:
-                                                               pbssid[j].rssi_low_threshold =
-                                                                     (int8) nla_get_u8(inner);
-                                                               break;
-                                                               default:
-                                                                       WL_ERR(("ATTR unknown %d\n",
-                                                                                 type));
-                                                                       break;
-                                                       }
-                                               }
-                                       j++;
-                               }
-                               break;
-                       default:
-                               WL_ERR(("Unknown type %d\n", type));
-                               break;
-               }
-       }
-       significant_params->nbssid = j;
-
-       if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg),
-                     DHD_PNO_SIGNIFICANT_SCAN_CFG_ID,
-                     significant_params, flush) < 0) {
-               WL_ERR(("Could not set GSCAN significant cfg\n"));
-               err = -EINVAL;
-               goto exit;
-       }
-exit:
-       kfree(significant_params);
-       return err;
-}
 #endif /* GSCAN_SUPPORT */
 #if defined(GSCAN_SUPPORT) || defined(DHD_GET_VALID_CHANNELS)
 static int
@@ -1178,6 +1104,74 @@ static int wl_cfgvendor_set_tcpack_sup_mode(struct wiphy *wiphy,
 }
 #endif /* DHDTCPACK_SUPPRESS */
 
+#ifdef DHD_WAKE_STATUS
+static int
+wl_cfgvendor_get_wake_reason_stats(struct wiphy *wiphy,
+       struct wireless_dev *wdev, const void *data, int len)
+{
+       struct net_device *ndev = wdev_to_ndev(wdev);
+       wake_counts_t *pwake_count_info;
+       int ret, mem_needed;
+#if defined(DHD_WAKE_EVENT_STATUS) && defined(DHD_DEBUG)
+       int flowid;
+#endif /* DHD_WAKE_EVENT_STATUS && DHD_DEBUG */
+       struct sk_buff *skb;
+       dhd_pub_t *dhdp = wl_cfg80211_get_dhdp(ndev);
+
+       WL_DBG(("Recv get wake status info cmd.\n"));
+
+       pwake_count_info = dhd_get_wakecount(dhdp);
+       mem_needed =  VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * 20) +
+               (WLC_E_LAST * sizeof(uint));
+
+       skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed);
+       if (unlikely(!skb)) {
+               WL_ERR(("%s: can't allocate %d bytes\n", __FUNCTION__, mem_needed));
+               return -ENOMEM;
+               goto exit;
+       }
+#ifdef DHD_WAKE_EVENT_STATUS
+       WL_ERR(("pwake_count_info->rcwake %d\n", pwake_count_info->rcwake));
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT, pwake_count_info->rcwake);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED, WLC_E_LAST);
+       nla_put(skb, WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE, (WLC_E_LAST * sizeof(uint)),
+               pwake_count_info->rc_event);
+#ifdef DHD_DEBUG
+       for (flowid = 0; flowid < WLC_E_LAST; flowid++) {
+               if (pwake_count_info->rc_event[flowid] != 0) {
+                       WL_ERR((" %s = %u\n", bcmevent_get_name(flowid),
+                               pwake_count_info->rc_event[flowid]));
+               }
+       }
+#endif /* DHD_DEBUG */
+#endif /* DHD_WAKE_EVENT_STATUS */
+#ifdef DHD_WAKE_RX_STATUS
+       WL_ERR(("pwake_count_info->rxwake %d\n", pwake_count_info->rxwake));
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE, pwake_count_info->rxwake);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT, pwake_count_info->rx_ucast);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT, pwake_count_info->rx_mcast);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT, pwake_count_info->rx_bcast);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT, pwake_count_info->rx_arp);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT, pwake_count_info->rx_icmpv6);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA, pwake_count_info->rx_icmpv6_ra);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA, pwake_count_info->rx_icmpv6_na);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS, pwake_count_info->rx_icmpv6_ns);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT,
+               pwake_count_info->rx_multi_ipv4);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT,
+               pwake_count_info->rx_multi_ipv6);
+       nla_put_u32(skb, WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT,
+               pwake_count_info->rx_multi_other);
+#endif /* #ifdef DHD_WAKE_RX_STATUS */
+       ret = cfg80211_vendor_cmd_reply(skb);
+       if (unlikely(ret)) {
+               WL_ERR(("Vendor cmd reply for -get wake status failed:%d \n", ret));
+       }
+exit:
+       return ret;
+}
+#endif /* DHD_WAKE_STATUS */
+
 #ifdef RTT_SUPPORT
 void
 wl_cfgvendor_rtt_evt(void *ctx, void *rtt_data)
@@ -1739,55 +1733,100 @@ wl_cfgvendor_set_bssid_pref(struct wiphy *wiphy,
        wl_bssid_pref_list_t *bssids;
        int tmp, tmp1, tmp2, type;
        const struct nlattr *outer, *inner, *iter;
-       uint32 flush = 0, i = 0, num = 0;
+       uint32 flush = 0, num = 0;
+       uint8 bssid_found = 0, rssi_found = 0;
 
        /* Assumption: NUM attribute must come first */
        nla_for_each_attr(iter, data, len, tmp2) {
                type = nla_type(iter);
                switch (type) {
                        case GSCAN_ATTRIBUTE_NUM_BSSID:
+                               if (num) {
+                                       WL_ERR(("attempt overide bssid num.\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
+                               if (nla_len(iter) != sizeof(uint32)) {
+                                       WL_ERR(("nla_len not match\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                                num = nla_get_u32(iter);
-                               if (num > MAX_BSSID_PREF_LIST_NUM) {
-                                       WL_ERR(("Too many Preferred BSSIDs!\n"));
+                               if (num == 0 || num > MAX_BSSID_PREF_LIST_NUM) {
+                                       WL_ERR(("wrong BSSID num:%d\n", num));
                                        err = -EINVAL;
                                        goto exit;
                                }
+                               if ((bssid_pref = create_bssid_pref_cfg(num)) == NULL) {
+                                       WL_ERR(("Can't malloc memory\n"));
+                                       err = -ENOMEM;
+                                       goto exit;
+                               }
                                break;
                        case GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH:
+                               if (nla_len(iter) != sizeof(uint32)) {
+                                       WL_ERR(("nla_len not match\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                                flush = nla_get_u32(iter);
+                               if (flush != 1) {
+                                       WL_ERR(("wrong flush value\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                                break;
                        case GSCAN_ATTRIBUTE_BSSID_PREF_LIST:
-                               if (!num)
-                                       return -EINVAL;
-                               if ((bssid_pref = create_bssid_pref_cfg(num)) == NULL) {
-                                       WL_ERR(("%s: Can't malloc memory\n", __FUNCTION__));
-                                       err = -ENOMEM;
+                               if (!num || !bssid_pref) {
+                                       WL_ERR(("bssid list count not set\n"));
+                                       err = -EINVAL;
                                        goto exit;
                                }
-                               bssid_pref->count = num;
+                               bssid_pref->count = 0;
                                bssids = bssid_pref->bssids;
                                nla_for_each_nested(outer, iter, tmp) {
-                                       if (i >= num) {
-                                               WL_ERR(("CFGs don't seem right!\n"));
+                                       if (bssid_pref->count >= num) {
+                                               WL_ERR(("too many bssid list\n"));
                                                err = -EINVAL;
                                                goto exit;
                                        }
+                                       bssid_found = 0;
+                                       rssi_found = 0;
                                        nla_for_each_nested(inner, outer, tmp1) {
                                                type = nla_type(inner);
                                                switch (type) {
-                                                       case GSCAN_ATTRIBUTE_BSSID_PREF:
-                                                               memcpy(&(bssids[i].bssid),
-                                                                 nla_data(inner), ETHER_ADDR_LEN);
-                                                               /* not used for now */
-                                                               bssids[i].flags = 0;
-                                                               break;
-                                                       case GSCAN_ATTRIBUTE_RSSI_MODIFIER:
-                                                               bssids[i].rssi_factor =
-                                                                      (int8) nla_get_u32(inner);
-                                                               break;
+                                               case GSCAN_ATTRIBUTE_BSSID_PREF:
+                                                       if (nla_len(inner) != ETHER_ADDR_LEN) {
+                                                               WL_ERR(("nla_len not match.\n"));
+                                                               err = -EINVAL;
+                                                               goto exit;
+                                                       }
+                                                       memcpy(&(bssids[bssid_pref->count].bssid),
+                                                         nla_data(inner), ETHER_ADDR_LEN);
+                                                       /* not used for now */
+                                                       bssids[bssid_pref->count].flags = 0;
+                                                       bssid_found = 1;
+                                                       break;
+                                               case GSCAN_ATTRIBUTE_RSSI_MODIFIER:
+                                                       if (nla_len(inner) != sizeof(uint32)) {
+                                                               WL_ERR(("nla_len not match.\n"));
+                                                               err = -EINVAL;
+                                                               goto exit;
+                                                       }
+                                                       bssids[bssid_pref->count].rssi_factor =
+                                                              (int8) nla_get_u32(inner);
+                                                       rssi_found = 1;
+                                                       break;
+                                               default:
+                                                       WL_ERR(("wrong type:%d\n", type));
+                                                       err = -EINVAL;
+                                                       goto exit;
+                                               }
+                                               if (bssid_found && rssi_found) {
+                                                       break;
                                                }
                                        }
-                                       i++;
+                                       bssid_pref->count++;
                                }
                                break;
                        default:
@@ -1826,53 +1865,88 @@ wl_cfgvendor_set_bssid_blacklist(struct wiphy *wiphy,
        int err = 0;
        int type, tmp;
        const struct nlattr *iter;
-       uint32 mem_needed = 0, flush = 0, i = 0, num = 0;
+       uint32 mem_needed = 0, flush = 0, num = 0;
 
        /* Assumption: NUM attribute must come first */
        nla_for_each_attr(iter, data, len, tmp) {
                type = nla_type(iter);
                switch (type) {
                        case GSCAN_ATTRIBUTE_NUM_BSSID:
+                               if (num != 0) {
+                                       WL_ERR(("attempt to change BSSID num\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
+                               if (nla_len(iter) != sizeof(uint32)) {
+                                       WL_ERR(("not matching nla_len.\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                                num = nla_get_u32(iter);
-                               if (num > MAX_BSSID_BLACKLIST_NUM) {
-                                       WL_ERR(("Too many Blacklist BSSIDs!\n"));
+                               if (num == 0 || num > MAX_BSSID_BLACKLIST_NUM) {
+                                       WL_ERR(("wrong BSSID count:%d\n", num));
                                        err = -EINVAL;
                                        goto exit;
                                }
+                               if (!blacklist) {
+                                       mem_needed = OFFSETOF(maclist_t, ea) +
+                                               sizeof(struct ether_addr) * (num);
+                                       blacklist = (maclist_t *)
+                                               kzalloc(mem_needed, GFP_KERNEL);
+                                       if (!blacklist) {
+                                               WL_ERR(("kzalloc failed.\n"));
+                                               err = -ENOMEM;
+                                               goto exit;
+                                       }
+                               }
                                break;
                        case GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH:
+                               if (nla_len(iter) != sizeof(uint32)) {
+                                       WL_ERR(("not matching nla_len.\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                                flush = nla_get_u32(iter);
+                               if (flush != 1) {
+                                       WL_ERR(("flush arg is worng:%d\n", flush));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
                                break;
                        case GSCAN_ATTRIBUTE_BLACKLIST_BSSID:
-                               if (num) {
-                                       if (!blacklist) {
-                                               mem_needed = sizeof(maclist_t) +
-                                                    sizeof(struct ether_addr) * (num - 1);
-                                               blacklist = (maclist_t *)
-                                                     kmalloc(mem_needed, GFP_KERNEL);
-                                               if (!blacklist) {
-                                                       WL_ERR(("%s: Can't malloc %d bytes\n",
-                                                            __FUNCTION__, mem_needed));
-                                                       err = -ENOMEM;
-                                                       goto exit;
-                                               }
-                                               blacklist->count = num;
-                                       }
-                                       if (i >= num) {
-                                               WL_ERR(("CFGs don't seem right!\n"));
-                                               err = -EINVAL;
-                                               goto exit;
-                                       }
-                                       memcpy(&(blacklist->ea[i]),
-                                         nla_data(iter), ETHER_ADDR_LEN);
-                                       i++;
+                               if (num == 0 || !blacklist) {
+                                       WL_ERR(("number of BSSIDs not received.\n"));
+                                       err = -EINVAL;
+                                       goto exit;
                                }
+                               if (nla_len(iter) != ETHER_ADDR_LEN) {
+                                       WL_ERR(("not matching nla_len.\n"));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
+                               if (blacklist->count >= num) {
+                                       WL_ERR(("too many BSSIDs than expected:%d\n",
+                                               blacklist->count));
+                                       err = -EINVAL;
+                                       goto exit;
+                               }
+                               memcpy(&(blacklist->ea[blacklist->count]), nla_data(iter),
+                                               ETHER_ADDR_LEN);
+                               blacklist->count++;
                                break;
-                       default:
-                               WL_ERR(("%s: No such attribute %d\n", __FUNCTION__, type));
-                               break;
-                       }
+               default:
+                       WL_ERR(("No such attribute:%d\n", type));
+                       break;
+               }
        }
+
+       if (blacklist && (blacklist->count != num)) {
+               WL_ERR(("not matching bssid count:%d to expected:%d\n",
+                               blacklist->count, num));
+               err = -EINVAL;
+               goto exit;
+       }
+
        err = dhd_dev_set_blacklist_bssid(bcmcfg_to_prmry_ndev(cfg),
                  blacklist, mem_needed, flush);
 exit:
@@ -1888,70 +1962,122 @@ wl_cfgvendor_set_ssid_whitelist(struct wiphy *wiphy,
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
        wl_ssid_whitelist_t *ssid_whitelist = NULL;
        wlc_ssid_t *ssid_elem;
-       int tmp, tmp2, mem_needed = 0, type;
-       const struct nlattr *inner, *iter;
-       uint32 flush = 0, i = 0, num = 0;
+       int tmp, tmp1, mem_needed = 0, type;
+       const struct nlattr *iter, *iter1;
+       uint32 flush = 0, num = 0;
+       int ssid_found = 0;
 
        /* Assumption: NUM attribute must come first */
-       nla_for_each_attr(iter, data, len, tmp2) {
+       nla_for_each_attr(iter, data, len, tmp) {
                type = nla_type(iter);
                switch (type) {
-                       case GSCAN_ATTRIBUTE_NUM_WL_SSID:
-                               num = nla_get_u32(iter);
-                               if (num > MAX_SSID_WHITELIST_NUM) {
-                                       WL_ERR(("Too many WL SSIDs!\n"));
-                                       err = -EINVAL;
-                                       goto exit;
-                               }
-                               mem_needed = sizeof(wl_ssid_whitelist_t);
-                               if (num)
-                                       mem_needed += (num - 1) * sizeof(ssid_info_t);
-                               ssid_whitelist = (wl_ssid_whitelist_t *)
-                                       kzalloc(mem_needed, GFP_KERNEL);
-                               if (ssid_whitelist == NULL) {
-                                       WL_ERR(("%s: Can't malloc %d bytes\n",
-                                             __FUNCTION__, mem_needed));
-                                       err = -ENOMEM;
-                                       goto exit;
-                               }
-                               ssid_whitelist->ssid_count = num;
-                               break;
-                       case GSCAN_ATTRIBUTE_WL_SSID_FLUSH:
-                               flush = nla_get_u32(iter);
-                               break;
-                       case GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM:
-                               if (!num || !ssid_whitelist) {
-                                       WL_ERR(("num ssid is not set!\n"));
-                                       return -EINVAL;
-                               }
-                               if (i >= num) {
-                                       WL_ERR(("CFGs don't seem right!\n"));
-                                       err = -EINVAL;
-                                       goto exit;
-                               }
-                               ssid_elem = &ssid_whitelist->ssids[i];
-                               nla_for_each_nested(inner, iter, tmp) {
-                                       type = nla_type(inner);
-                                       switch (type) {
-                                               case GSCAN_ATTRIBUTE_WHITELIST_SSID:
-                                                       memcpy(ssid_elem->SSID,
-                                                         nla_data(inner),
-                                                         DOT11_MAX_SSID_LEN);
-                                                       break;
-                                               case GSCAN_ATTRIBUTE_WL_SSID_LEN:
-                                                       ssid_elem->SSID_len = (uint8)
-                                                               nla_get_u32(inner);
-                                                       break;
+               case GSCAN_ATTRIBUTE_NUM_WL_SSID:
+                       if (num != 0) {
+                               WL_ERR(("try to change SSID num\n"));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+                       if (nla_len(iter) != sizeof(uint32)) {
+                               WL_ERR(("not matching nla_len.\n"));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+                       num = nla_get_u32(iter);
+                       if (num == 0 || num > MAX_SSID_WHITELIST_NUM) {
+                               WL_ERR(("wrong SSID count:%d\n", num));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+                       mem_needed = sizeof(wl_ssid_whitelist_t) +
+                               sizeof(wlc_ssid_t) * num;
+                       ssid_whitelist = (wl_ssid_whitelist_t *)
+                               kzalloc(mem_needed, GFP_KERNEL);
+                       if (ssid_whitelist == NULL) {
+                               WL_ERR(("failed to alloc mem\n"));
+                               err = -ENOMEM;
+                               goto exit;
+                       }
+                       break;
+               case GSCAN_ATTRIBUTE_WL_SSID_FLUSH:
+                       if (nla_len(iter) != sizeof(uint32)) {
+                               WL_ERR(("not matching nla_len.\n"));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+                       flush = nla_get_u32(iter);
+                       if (flush != 1) {
+                               WL_ERR(("flush arg worng:%d\n", flush));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+                       break;
+               case GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM:
+                       if (!num || !ssid_whitelist) {
+                               WL_ERR(("num ssid is not set!\n"));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+                       if (ssid_whitelist->ssid_count >= num) {
+                               WL_ERR(("too many SSIDs:%d\n",
+                                       ssid_whitelist->ssid_count));
+                               err = -EINVAL;
+                               goto exit;
+                       }
+
+                       ssid_elem = &ssid_whitelist->ssids[
+                                       ssid_whitelist->ssid_count];
+                       ssid_found = 0;
+                       nla_for_each_nested(iter1, iter, tmp1) {
+                               type = nla_type(iter1);
+                               switch (type) {
+                               case GSCAN_ATTRIBUTE_WL_SSID_LEN:
+                                       if (nla_len(iter1) != sizeof(uint32)) {
+                                               WL_ERR(("not match nla_len\n"));
+                                               err = -EINVAL;
+                                               goto exit;
+                                       }
+                                       ssid_elem->SSID_len = nla_get_u32(iter1);
+                                       if (ssid_elem->SSID_len >
+                                                       DOT11_MAX_SSID_LEN) {
+                                               WL_ERR(("wrong SSID len:%d\n",
+                                                       ssid_elem->SSID_len));
+                                               err = -EINVAL;
+                                               goto exit;
+                                       }
+                                       break;
+                               case GSCAN_ATTRIBUTE_WHITELIST_SSID:
+                                       if (ssid_elem->SSID_len == 0) {
+                                               WL_ERR(("SSID_len not received\n"));
+                                               err = -EINVAL;
+                                               goto exit;
                                        }
+                                       if (nla_len(iter1) != ssid_elem->SSID_len) {
+                                               WL_ERR(("not match nla_len\n"));
+                                               err = -EINVAL;
+                                               goto exit;
+                                       }
+                                       memcpy(ssid_elem->SSID, nla_data(iter1),
+                                                       ssid_elem->SSID_len);
+                                       ssid_found = 1;
+                                       break;
                                }
-                               i++;
-                               break;
-                       default:
-                               WL_ERR(("%s: No such attribute %d\n", __FUNCTION__, type));
-                               break;
+                               if (ssid_found) {
+                                       ssid_whitelist->ssid_count++;
+                                       break;
+                               }
+                       }
+                       break;
+               default:
+                       WL_ERR(("No such attribute: %d\n", type));
+                       break;
                }
        }
 
+       if (ssid_whitelist && (ssid_whitelist->ssid_count != num)) {
+               WL_ERR(("not matching ssid count:%d to expected:%d\n",
+                               ssid_whitelist->ssid_count, num));
+               err = -EINVAL;
+       }
        err = dhd_dev_set_whitelist_ssid(bcmcfg_to_prmry_ndev(cfg),
                  ssid_whitelist, mem_needed, flush);
 exit:
@@ -2190,6 +2316,32 @@ exit:
 #define NUM_PEER 1
 #define NUM_CHAN 11
 #define HEADER_SIZE sizeof(ver_len)
+
+static int wl_cfgvendor_lstats_get_bcn_mbss(char *buf, uint32 *rxbeaconmbss)
+{
+       wl_cnt_info_t *cbuf = (wl_cnt_info_t *)buf;
+       const void *cnt;
+
+       if ((cnt = (const void *)bcm_get_data_from_xtlv_buf(cbuf->data, cbuf->datalen,
+               WL_CNT_XTLV_CNTV_LE10_UCODE, NULL, BCM_XTLV_OPTION_ALIGN32)) != NULL) {
+               *rxbeaconmbss = ((const wl_cnt_v_le10_mcst_t *)cnt)->rxbeaconmbss;
+       } else if ((cnt = (const void *)bcm_get_data_from_xtlv_buf(cbuf->data, cbuf->datalen,
+               WL_CNT_XTLV_LT40_UCODE_V1, NULL, BCM_XTLV_OPTION_ALIGN32)) != NULL) {
+               *rxbeaconmbss = ((const wl_cnt_lt40mcst_v1_t *)cnt)->rxbeaconmbss;
+       } else if ((cnt = (const void *)bcm_get_data_from_xtlv_buf(cbuf->data, cbuf->datalen,
+               WL_CNT_XTLV_GE40_UCODE_V1, NULL, BCM_XTLV_OPTION_ALIGN32)) != NULL) {
+               *rxbeaconmbss = ((const wl_cnt_ge40mcst_v1_t *)cnt)->rxbeaconmbss;
+       } else if ((cnt = (const void *)bcm_get_data_from_xtlv_buf(cbuf->data, cbuf->datalen,
+               WL_CNT_XTLV_GE80_UCODE_V1, NULL, BCM_XTLV_OPTION_ALIGN32)) != NULL) {
+               *rxbeaconmbss = ((const wl_cnt_ge80mcst_v1_t *)cnt)->rxbeaconmbss;
+       } else {
+               *rxbeaconmbss = 0;
+               return BCME_NOTFOUND;
+       }
+
+       return BCME_OK;
+}
+
 static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
        struct wireless_dev *wdev, const void  *data, int len)
 {
@@ -2199,7 +2351,6 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
        wifi_radio_stat *radio;
        wifi_radio_stat_h radio_h;
        wl_wme_cnt_t *wl_wme_cnt;
-       wl_cnt_ge40mcst_v1_t *macstat_cnt;
        wl_cnt_wlc_t *wlc_cnt;
        scb_val_t scbval;
        char *output = NULL;
@@ -2207,7 +2358,9 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
        wifi_rate_stat_v1 *p_wifi_rate_stat_v1 = NULL;
        wifi_rate_stat *p_wifi_rate_stat = NULL;
        uint total_len = 0;
+       uint32 rxbeaconmbss;
        wifi_iface_stat iface;
+       wlc_rev_info_t revinfo;
 #ifdef CONFIG_COMPAT
        compat_wifi_iface_stat compat_iface;
        int compat_task_state = is_compat_task();
@@ -2216,6 +2369,14 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
        WL_INFORM(("%s: Enter \n", __func__));
        RETURN_EIO_IF_NOT_UP(cfg);
 
+       /* Get the device rev info */
+       memset(&revinfo, 0, sizeof(revinfo));
+       err = wldev_ioctl_get(bcmcfg_to_prmry_ndev(cfg), WLC_GET_REVINFO, &revinfo,
+                       sizeof(revinfo));
+       if (err != BCME_OK) {
+               goto exit;
+       }
+
        outdata = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
        if (outdata == NULL) {
                WL_ERR(("%s: alloc failed\n", __func__));
@@ -2224,7 +2385,6 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
 
        memset(&scbval, 0, sizeof(scb_val_t));
        memset(outdata, 0, WLC_IOCTL_MAXLEN);
-       memset(iovar_buf, 0, WLC_IOCTL_MAXLEN);
        output = outdata;
 
        err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "radiostat", NULL, 0,
@@ -2285,7 +2445,6 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
                wl_wme_cnt->tx_failed[WIFI_AC_BK].packets);
 
 
-       memset(iovar_buf, 0, WLC_IOCTL_MAXLEN);
        err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "counters", NULL, 0,
                iovar_buf, WLC_IOCTL_MAXLEN, NULL);
        if (unlikely(err)) {
@@ -2294,8 +2453,13 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
        }
 
        CHK_CNTBUF_DATALEN(iovar_buf, WLC_IOCTL_MAXLEN);
+
+#ifdef STAT_REPORT
+       wl_stat_report_gather(cfg, iovar_buf);
+#endif
+
        /* Translate traditional (ver <= 10) counters struct to new xtlv type struct */
-       err = wl_cntbuf_to_xtlv_format(NULL, iovar_buf, WLC_IOCTL_MAXLEN, 0);
+       err = wl_cntbuf_to_xtlv_format(NULL, iovar_buf, WLC_IOCTL_MAXLEN, revinfo.corerev);
        if (err != BCME_OK) {
                WL_ERR(("%s wl_cntbuf_to_xtlv_format ERR %d\n",
                        __FUNCTION__, err));
@@ -2310,19 +2474,9 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
 
        COMPAT_ASSIGN_VALUE(iface, ac[WIFI_AC_BE].retries, wlc_cnt->txretry);
 
-       if ((macstat_cnt = bcm_get_data_from_xtlv_buf(((wl_cnt_info_t *)iovar_buf)->data,
-                       ((wl_cnt_info_t *)iovar_buf)->datalen,
-                       WL_CNT_XTLV_CNTV_LE10_UCODE, NULL,
-                       BCM_XTLV_OPTION_ALIGN32)) == NULL) {
-               macstat_cnt = bcm_get_data_from_xtlv_buf(((wl_cnt_info_t *)iovar_buf)->data,
-                               ((wl_cnt_info_t *)iovar_buf)->datalen,
-                               WL_CNT_XTLV_GE40_UCODE_V1, NULL,
-                               BCM_XTLV_OPTION_ALIGN32);
-       }
-
-       if (macstat_cnt == NULL) {
-               printf("wlmTxGetAckedPackets: macstat_cnt NULL!\n");
-               err = BCME_ERROR;
+       err = wl_cfgvendor_lstats_get_bcn_mbss(iovar_buf, &rxbeaconmbss);
+       if (unlikely(err)) {
+               WL_ERR(("get_bcn_mbss error (%d)\n", err));
                goto exit;
        }
 
@@ -2332,7 +2486,7 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
                goto exit;
        }
 
-       COMPAT_ASSIGN_VALUE(iface, beacon_rx, macstat_cnt->rxbeaconmbss);
+       COMPAT_ASSIGN_VALUE(iface, beacon_rx, rxbeaconmbss);
        COMPAT_ASSIGN_VALUE(iface, rssi_mgmt, scbval.val);
        COMPAT_ASSIGN_VALUE(iface, num_peers, NUM_PEER);
        COMPAT_ASSIGN_VALUE(iface, peer_info->num_rate, NUM_RATE);
@@ -2348,7 +2502,6 @@ static int wl_cfgvendor_lstats_get_info(struct wiphy *wiphy,
                output += (sizeof(iface) - sizeof(wifi_rate_stat));
        }
 
-       memset(iovar_buf, 0, WLC_IOCTL_MAXLEN);
        err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "ratestat", NULL, 0,
                iovar_buf, WLC_IOCTL_MAXLEN, NULL);
        if (err != BCME_OK && err != BCME_UNSUPPORTED) {
@@ -2512,9 +2665,9 @@ wl_cfgvendor_dbg_get_mem_dump(struct wiphy *wiphy,
 {
        int ret = BCME_OK, rem, type;
        int buf_len = 0;
-       void __user *user_buf = NULL;
+       uintptr_t user_buf = (uintptr_t)NULL;
        const struct nlattr *iter;
-       char *mem_buf;
+       char *mem_buf = NULL;
        struct sk_buff *skb;
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
 
@@ -2522,10 +2675,24 @@ wl_cfgvendor_dbg_get_mem_dump(struct wiphy *wiphy,
                type = nla_type(iter);
                switch (type) {
                        case DEBUG_ATTRIBUTE_FW_DUMP_LEN:
-                               buf_len = nla_get_u32(iter);
+                               /* Check if the iter is valid and
+                                * buffer length is not already initialized.
+                                */
+                               if ((nla_len(iter) == sizeof(uint32)) &&
+                                       !buf_len) {
+                                       buf_len = nla_get_u32(iter);
+                               } else {
+                                       ret = BCME_ERROR;
+                                       goto exit;
+                               }
                                break;
                        case DEBUG_ATTRIBUTE_FW_DUMP_DATA:
-                               user_buf = (void __user *)(unsigned long) nla_get_u64(iter);
+                               if (nla_len(iter) != sizeof(uint64)) {
+                                       WL_ERR(("Invalid len\n"));
+                                       ret = BCME_ERROR;
+                                       goto exit;
+                               }
+                               user_buf = (uintptr_t)nla_get_u64(iter);
                                break;
                        default:
                                WL_ERR(("Unknown type: %d\n", type));
@@ -2557,7 +2724,7 @@ wl_cfgvendor_dbg_get_mem_dump(struct wiphy *wiphy,
                else
 #endif /* CONFIG_COMPAT */
                {
-                       ret = copy_to_user(user_buf, mem_buf, buf_len);
+                       ret = copy_to_user((void*)user_buf, mem_buf, buf_len);
                        if (ret) {
                                WL_ERR(("failed to copy memdump into user buffer : %d\n", ret));
                                goto free_mem;
@@ -2586,50 +2753,6 @@ exit:
        return ret;
 }
 
-static int wl_cfgvendor_dbg_get_version(struct wiphy *wiphy,
-       struct wireless_dev *wdev, const void *data, int len)
-{
-       int ret = BCME_OK, rem, type;
-       int buf_len = 1024;
-       bool dhd_ver = FALSE;
-       char *buf_ptr;
-       const struct nlattr *iter;
-       gfp_t kflags;
-       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
-       kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
-       buf_ptr = kzalloc(buf_len, kflags);
-       if (!buf_ptr) {
-               WL_ERR(("failed to allocate the buffer for version n"));
-               ret = BCME_NOMEM;
-               goto exit;
-       }
-       nla_for_each_attr(iter, data, len, rem) {
-               type = nla_type(iter);
-               switch (type) {
-                       case DEBUG_ATTRIBUTE_GET_DRIVER:
-                               dhd_ver = TRUE;
-                               break;
-                       case DEBUG_ATTRIBUTE_GET_FW:
-                               dhd_ver = FALSE;
-                               break;
-                       default:
-                               WL_ERR(("Unknown type: %d\n", type));
-                               ret = BCME_ERROR;
-                               goto exit;
-               }
-       }
-       ret = dhd_os_get_version(bcmcfg_to_prmry_ndev(cfg), dhd_ver, &buf_ptr, buf_len);
-       if (ret < 0) {
-               WL_ERR(("failed to get the version %d\n", ret));
-               goto exit;
-       }
-       ret = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg),
-               buf_ptr, strlen(buf_ptr));
-exit:
-       kfree(buf_ptr);
-       return ret;
-}
-
 static int wl_cfgvendor_dbg_get_ring_status(struct wiphy *wiphy,
        struct wireless_dev *wdev, const void  *data, int len)
 {
@@ -2704,25 +2827,6 @@ static int wl_cfgvendor_dbg_get_ring_data(struct wiphy *wiphy,
        return ret;
 }
 
-static int wl_cfgvendor_dbg_get_feature(struct wiphy *wiphy,
-       struct wireless_dev *wdev, const void  *data, int len)
-{
-       int ret = BCME_OK;
-       u32 supported_features = 0;
-       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
-       dhd_pub_t *dhd_pub = cfg->pub;
-
-       ret = dhd_os_dbg_get_feature(dhd_pub, &supported_features);
-       if (ret < 0) {
-               WL_ERR(("dbg_get_feature failed ret:%d\n", ret));
-               goto exit;
-       }
-       ret = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg),
-               &supported_features, sizeof(supported_features));
-exit:
-       return ret;
-}
-
 static void wl_cfgvendor_dbg_ring_send_evt(void *ctx,
        const int ring_id, const void *data, const uint32 len,
        const dhd_dbg_ring_status_t ring_status)
@@ -2789,6 +2893,69 @@ static void wl_cfgvendor_dbg_send_urgent_evt(void *ctx, const void *data,
 }
 #endif /* DEBUGABILITY */
 
+static int wl_cfgvendor_dbg_get_version(struct wiphy *wiphy,
+       struct wireless_dev *wdev, const void *data, int len)
+{
+       int ret = BCME_OK, rem, type;
+       int buf_len = 1024;
+       bool dhd_ver = FALSE;
+       char *buf_ptr;
+       const struct nlattr *iter;
+       gfp_t kflags;
+       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+       kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
+       buf_ptr = kzalloc(buf_len, kflags);
+       if (!buf_ptr) {
+               WL_ERR(("failed to allocate the buffer for version n"));
+               ret = BCME_NOMEM;
+               goto exit;
+       }
+       nla_for_each_attr(iter, data, len, rem) {
+               type = nla_type(iter);
+               switch (type) {
+                       case DEBUG_ATTRIBUTE_GET_DRIVER:
+                               dhd_ver = TRUE;
+                               break;
+                       case DEBUG_ATTRIBUTE_GET_FW:
+                               dhd_ver = FALSE;
+                               break;
+                       default:
+                               WL_ERR(("Unknown type: %d\n", type));
+                               ret = BCME_ERROR;
+                               goto exit;
+               }
+       }
+       ret = dhd_os_get_version(bcmcfg_to_prmry_ndev(cfg), dhd_ver, &buf_ptr, buf_len);
+       if (ret < 0) {
+               WL_ERR(("failed to get the version %d\n", ret));
+               goto exit;
+       }
+       ret = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg),
+               buf_ptr, strlen(buf_ptr));
+exit:
+       kfree(buf_ptr);
+       return ret;
+}
+
+static int wl_cfgvendor_dbg_get_feature(struct wiphy *wiphy,
+       struct wireless_dev *wdev, const void  *data, int len)
+{
+       int ret = BCME_OK;
+       u32 supported_features = 0;
+       struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
+       dhd_pub_t *dhd_pub = cfg->pub;
+
+       ret = dhd_os_dbg_get_feature(dhd_pub, &supported_features);
+       if (ret < 0) {
+               WL_ERR(("dbg_get_feature failed ret:%d\n", ret));
+               goto exit;
+       }
+       ret = wl_cfgvendor_send_cmd_reply(wiphy, bcmcfg_to_prmry_ndev(cfg),
+               &supported_features, sizeof(supported_features));
+exit:
+       return ret;
+}
+
 #ifdef DBG_PKT_MON
 static int wl_cfgvendor_dbg_start_pkt_fate_monitoring(struct wiphy *wiphy,
        struct wireless_dev *wdev, const void *data, int len)
@@ -3226,14 +3393,6 @@ static const struct wiphy_vendor_command wl_vendor_cmds [] = {
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = wl_cfgvendor_hotlist_cfg
        },
-       {
-               {
-                       .vendor_id = OUI_GOOGLE,
-                       .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG
-               },
-               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
-               .doit = wl_cfgvendor_significant_change_cfg
-       },
        {
                {
                        .vendor_id = OUI_GOOGLE,
@@ -3411,6 +3570,22 @@ static const struct wiphy_vendor_command wl_vendor_cmds [] = {
                .doit = wl_cfgvendor_set_bssid_blacklist
        },
 #endif /* GSCAN_SUPPORT */
+       {
+               {
+                       .vendor_id = OUI_GOOGLE,
+                       .subcmd = DEBUG_GET_VER
+               },
+               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+               .doit = wl_cfgvendor_dbg_get_version
+       },
+       {
+               {
+                       .vendor_id = OUI_GOOGLE,
+                       .subcmd = DEBUG_GET_FEATURE
+               },
+               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+               .doit = wl_cfgvendor_dbg_get_feature
+       },
 #ifdef DEBUGABILITY
        {
                {
@@ -3444,14 +3619,6 @@ static const struct wiphy_vendor_command wl_vendor_cmds [] = {
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = wl_cfgvendor_dbg_get_mem_dump
        },
-       {
-               {
-                       .vendor_id = OUI_GOOGLE,
-                       .subcmd = DEBUG_GET_VER
-               },
-               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
-               .doit = wl_cfgvendor_dbg_get_version
-       },
        {
                {
                        .vendor_id = OUI_GOOGLE,
@@ -3468,14 +3635,6 @@ static const struct wiphy_vendor_command wl_vendor_cmds [] = {
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = wl_cfgvendor_dbg_get_ring_data
        },
-       {
-               {
-                       .vendor_id = OUI_GOOGLE,
-                       .subcmd = DEBUG_GET_FEATURE
-               },
-               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
-               .doit = wl_cfgvendor_dbg_get_feature
-       },
 #endif /* DEBUGABILITY */
 #ifdef DBG_PKT_MON
        {
@@ -3568,8 +3727,18 @@ static const struct wiphy_vendor_command wl_vendor_cmds [] = {
                },
                .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
                .doit = wl_cfgvendor_set_tcpack_sup_mode
-       }
+       },
 #endif /* DHDTCPACK_SUPPRESS */
+#ifdef DHD_WAKE_STATUS
+       {
+               {
+                       .vendor_id = OUI_GOOGLE,
+                       .subcmd = DEBUG_GET_WAKE_REASON_STATS
+               },
+               .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
+               .doit = wl_cfgvendor_get_wake_reason_stats
+       }
+#endif /* DHD_WAKE_STATUS */
 };
 
 static const struct  nl80211_vendor_cmd_info wl_vendor_events [] = {
index bf48e721357c0e13428ad925fbdf0dcbde004b47..c0a8a9f16648e0b208e98575e3a95104f62844b2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux cfg80211 Vendor Extension Code
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_cfgvendor.h 681171 2017-01-25 05:27:08Z $
+ * $Id: wl_cfgvendor.h 698895 2017-05-11 02:55:17Z $
  */
 
 
@@ -468,6 +468,67 @@ typedef enum gscan_complete_event {
        WIFI_SCAN_BUFFER_THR_BREACHED
 } gscan_complete_event_t;
 
+#ifdef DHD_WAKE_STATUS
+enum wake_stat_attributes {
+       WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT,
+       WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE,
+       WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT,
+       WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT_USED,
+       WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW,
+       WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE,
+       WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT,
+       WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED,
+       WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE,
+       WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT,
+       WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT,
+       WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT,
+       WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT,
+       WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT,
+       WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA,
+       WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA,
+       WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS,
+       WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT,
+       WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT,
+       WAKE_STAT_ATTRIBUTE_OTHER_RX_MULTICAST_ADD_CNT
+};
+
+typedef struct rx_data_cnt_details_t {
+       int rx_unicast_cnt;             /* Total rx unicast packet which woke up host */
+       int rx_multicast_cnt;   /* Total rx multicast packet which woke up host */
+       int rx_broadcast_cnt;   /* Total rx broadcast packet which woke up host */
+} RX_DATA_WAKE_CNT_DETAILS;
+
+typedef struct rx_wake_pkt_type_classification_t {
+       int icmp_pkt;   /* wake icmp packet count */
+       int icmp6_pkt;  /* wake icmp6 packet count */
+       int icmp6_ra;   /* wake icmp6 RA packet count */
+       int icmp6_na;   /* wake icmp6 NA packet count */
+       int icmp6_ns;   /* wake icmp6 NS packet count */
+} RX_WAKE_PKT_TYPE_CLASSFICATION;
+
+typedef struct rx_multicast_cnt_t {
+       int ipv4_rx_multicast_addr_cnt; /* Rx wake packet was ipv4 multicast */
+       int ipv6_rx_multicast_addr_cnt; /* Rx wake packet was ipv6 multicast */
+       int other_rx_multicast_addr_cnt; /* Rx wake packet was non-ipv4 and non-ipv6 */
+} RX_MULTICAST_WAKE_DATA_CNT;
+
+typedef struct wlan_driver_wake_reason_cnt_t {
+       int total_cmd_event_wake;    /* Total count of cmd event wakes */
+       int *cmd_event_wake_cnt;     /* Individual wake count array, each index a reason */
+       int cmd_event_wake_cnt_sz;   /* Max number of cmd event wake reasons */
+       int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */
+       int total_driver_fw_local_wake;    /* Total count of drive/fw wakes, for local reasons */
+       int *driver_fw_local_wake_cnt;     /* Individual wake count array, each index a reason */
+       int driver_fw_local_wake_cnt_sz;   /* Max number of local driver/fw wake reasons */
+       /* Number of local driver/fw wake reasons specific to the driver */
+       int driver_fw_local_wake_cnt_used;
+       int total_rx_data_wake;     /* total data rx packets, that woke up host */
+       RX_DATA_WAKE_CNT_DETAILS rx_wake_details;
+       RX_WAKE_PKT_TYPE_CLASSFICATION rx_wake_pkt_classification_info;
+       RX_MULTICAST_WAKE_DATA_CNT rx_multicast_wake_pkt_info;
+} WLAN_DRIVER_WAKE_REASON_CNT;
+#endif /* DHD_WAKE_STATUS */
+
 /* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */
 #define BRCM_VENDOR_SCMD_CAPA  "cap"
 
index e90fa5d1679aeda5a2f06e925d5129c508e8a9cf..d159725ad7d35d86acb2070cc5a6842ce651e9d7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Broadcom Dongle Host Driver (DHD), Linux monitor network interface
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
index 745a479244e9f7ae1cb90dda21933185e6e760f7..3edbb803daa05c8e3e68569e04d9276b6fe888ce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux roam cache
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_roam.c 662434 2016-09-29 12:21:46Z $
+ * $Id: wl_roam.c 731718 2017-11-14 08:10:43Z $
  */
 
 
@@ -39,7 +39,7 @@
 #endif
 #include <wldev_common.h>
 
-#define MAX_ROAM_CACHE         100
+#define MAX_ROAM_CACHE         200
 #define MAX_SSID_BUFSIZE       36
 
 #define ROAMSCAN_MODE_NORMAL   0
@@ -121,12 +121,14 @@ int set_roamscan_mode(struct net_device *dev, int mode)
        return error;
 }
 
-int get_roamscan_channel_list(struct net_device *dev, unsigned char channels[])
+int get_roamscan_channel_list(struct net_device *dev, unsigned char channels[],
+       int n_channels)
 {
        int n = 0;
+       int max_channel_number = MIN(n_channels, n_roam_cache);
 
        if (roamscan_mode == ROAMSCAN_MODE_WES) {
-               for (n = 0; n < n_roam_cache; n++) {
+               for (n = 0; n < max_channel_number; n++) {
                        channels[n] = roam_cache[n].chanspec & WL_CHANSPEC_CHAN_MASK;
 
                        WL_DBG(("channel[%d] - [%02d] \n", n, channels[n]));
@@ -249,7 +251,7 @@ static bool is_duplicated_channel(const chanspec_t *channels, int n_channels, ch
 }
 
 int get_roam_channel_list(int target_chan,
-       chanspec_t *channels, const wlc_ssid_t *ssid, int ioctl_ver)
+       chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver)
 {
        int i, n = 1;
        char chanbuf[CHANSPEC_STR_LEN];
@@ -280,6 +282,10 @@ int get_roam_channel_list(int target_chan,
                                WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
                                        wf_chspec_ntoa_ex(ch, chanbuf)));
                                channels[n++] = ch;
+                               if (n >= n_channels) {
+                                       WL_ERR(("Too many roam scan channels\n"));
+                                       return n;
+                               }
                        }
                }
 
@@ -303,6 +309,10 @@ int get_roam_channel_list(int target_chan,
                        WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
                                wf_chspec_ntoa_ex(ch, chanbuf)));
                        channels[n++] = ch;
+                       if (n >= n_channels) {
+                               WL_ERR(("Too many roam scan channels\n"));
+                               return n;
+                       }
                }
        }
 
diff --git a/drivers/net/wireless/bcmdhd_1_77/wl_statreport.c b/drivers/net/wireless/bcmdhd_1_77/wl_statreport.c
new file mode 100644 (file)
index 0000000..9c3d1e7
--- /dev/null
@@ -0,0 +1,1625 @@
+/*
+* Wifi dongle status logging and report
+*
+* Copyright (C) 1999-2018, Broadcom Corporation
+* 
+*      Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2 (the "GPL"),
+* available at http://www.broadcom.com/licenses/GPLv2.php, with the
+* following added to such license:
+* 
+*      As a special exception, the copyright holders of this software give you
+* permission to link this software with independent modules, and to copy and
+* distribute the resulting executable under terms of your choice, provided that
+* you also meet, for each linked independent module, the terms and conditions of
+* the license of that module.  An independent module is a module which is not
+* derived from this software.  The special exception does not apply to any
+* modifications of the software.
+* 
+*      Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a license
+* other than the GPL, without Broadcom's express prior written consent.
+*
+* <<Broadcom-WL-IPTag/Open:>>
+*
+* $Id: wl_statreport.c 735359 2017-12-08 10:56:04Z $
+*/
+#include <wlc_types.h>
+#include <bcmutils.h>
+#include <wlioctl.h>
+#include <wl_statreport.h>
+#include <wl_cfg80211.h>
+#include <wldev_common.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_linux.h>
+#include <linux/fs.h>
+
+#ifndef LINKSTAT_SUPPORT
+#error "LINK STAT is NOT supported"
+#endif /* LINKSTAT_SUPPORT */
+#ifndef DHD_LOG_DUMP
+#error "DHD_LOG_DUMP is not supported"
+#endif /* DHD_LOG_DUMP */
+
+#define WSR_REPORT_VERSION     20170620
+#define WSR_REPORT_MAX_DATA    64
+#define WSR_REPORT_MAX_WPA_CNT 5
+#define WSR_INVALID    (-1)
+
+#define WSR_CNT_SIZE   (1300 + 256)
+
+/* restrict maximum value less than 100M to reduce string length */
+#define WSR_CNT_VALUE_MAX      100000000
+
+#define WSR_NONSEC_TO_SEC              1000000000
+#define WSR_REPORT_YEAR_MUL    10000
+#define WSR_REPORT_MON_MUL             100
+#define WSR_REPORT_HOUR_MUL    10000
+#define WSR_REPORT_MIN_MUL             100
+#define WSR_REPORT_MINUTES             60
+#define WSR_REPORT_YEAR_BASE   1900
+
+#define WSR_MAX_OUI    3
+#define OUI_PAD_LEN (4 - (WSR_MAX_OUI * DOT11_OUI_LEN) % 4)
+
+#define WSR_MINIMIZE_REPORT
+
+/* logging connection info to follow up connection changes */
+typedef struct stat_report_conn {
+       uint8 bssid[ETHER_ADDR_LEN]; /* connected bssid */
+       uint8 oui_cnt;                          /* number of vndr OUI of connected AP */
+       uint8 pad1;
+       uint32 dhd_opmode;                      /* dhd operation mode : dhd_op_flags */
+       uint8 oui_list[WSR_MAX_OUI][DOT11_OUI_LEN]; /* vndr OUI list */
+       uint8 pad2[OUI_PAD_LEN];
+} wsr_conn_t;
+
+/* Kernel local clock is not elapsed at suspend mode
+ * but kernel logs show this value at the logs
+ * to avoid calculation print local clock
+ * and boot up time(of date/time format)
+ */
+typedef struct stat_report_clock {
+       uint32 kernel_clock;            /* kernel local clock */
+       uint32 date;                            /* date of WSR format */
+       uint32 time;                            /* time of WSR format */
+} wsr_clock_t;
+
+typedef struct stat_report_adps {
+       uint8 mode;                             /* ADPS mdoe 0=off, 1 = on */
+       uint8 flags;                    /* ADPS restrict flags 0 = adps work, not 0 = paused */
+       uint8 current_step;             /* ADPS step 0 = LOW PM STEP, 1 = HIGH PM STEP */
+       uint8 pad;
+       uint32 duration_high;   /* total duration in HIGH PM STEP in mili-second unit */
+       uint32 counts_high;             /* total number of HIGH PM STEP */
+       uint32 duration_low;    /* total duration in LOW PM STEP in mili-second unit */
+       uint32 counts_low;              /* total inumber of LOW PM STEP */
+} wsr_adps_t;
+
+typedef struct stat_report_link {
+       int8 lqcm;                              /* lqcm value -1 : INVALID, 0~8 : LQCM step */
+       int8 rssi;                              /* RSSI : -128 ~ 0 */
+       uint8 snr;                              /* SNR : 0 ~ 100 */
+       uint8 pad;
+} wsr_link_t;
+
+typedef struct stat_report_phy_tx_power {
+       uint8 sar_enable;                       /* SAR Enable/Disable */
+       uint8 phy_rsdb_mode;            /* PHY RSDB mode 0-MIMO, 1-RSDB */
+
+       /* 2.4G/5G SAR power capping value per core[0/1], Unit [qdBm] */
+       uint8 sar_limit_2g_core0;
+       uint8 sar_limit_2g_core1;
+       uint8 sar_limit_5g_core0;
+       uint8 sar_limit_5g_core1;
+       uint8 fcc_enable;                       /* FCC Enable/Disable */
+       uint8 fccpwrch12;                       /* FCC power capping value of 2.4G 12ch [qdBm] */
+       uint8 fccpwrch13;                       /* FCC power capping value of 2.4G 13ch [qdBm] */
+       uint8 bss_local_max;            /* BSS Local Max [qdBm] */
+       uint8 bss_local_constraint;     /* BSS Local Constraint [qdBm] */
+       uint8 dsss_1mbps_2g;            /* Target power - 2.4G DSSS 1Mbps rate [qdBm] */
+       uint8 ofdm_6mbps_2g;            /* Target power - 2.4G OFDM 6Mbps rate [qdBm] */
+       uint8 mcs_0_2g;                         /* Target power - 2.4G MCS 0 rate [qdBm] */
+       uint8 ofdm_6mbps_5g;            /* Target power - 5G OFDM 6Mbps rate [qdBm] */
+       uint8 mcs_0_5g;                         /* Target power - 5G MCS 0 rate [qdBm] */
+} wsr_tx_power_t;
+
+typedef struct stat_report_elem {
+       wsr_clock_t clock;
+       wsr_conn_t conn;
+       char cntinfo[WSR_CNT_SIZE];
+       wsr_link_t link_quality;
+       wsr_adps_t adps;
+       wsr_tx_power_t tx_power;
+} wsr_elem_t;
+
+typedef struct wl_stat_report_info {
+       uint32 version; /* WSR version */
+
+       int enabled;    /* enabled/disabled */
+
+       /* ring buf variables */
+       struct mutex ring_sync; /* mutex for critical section of ring buff */
+       int write_idx;  /* next write index, -1 : not started */
+       int read_idx;   /* next read index, -1 : not start */
+       /* conn idx : first connection of this connection */
+       /* -1 : not started if read = -1, same to read if read is not -1 */
+       /* counts between conn & write shall be less than MAX_REPORT */
+       int conn_idx;
+
+       /* protected elements during seiralization */
+       int lock_idx;   /* start index of locked, element will not be overried */
+       int lock_count; /* number of locked, from lock idx */
+
+       /* serialzation variables */
+       int seral_mode; /* serialize mode */
+       int trans_buf_len;      /* configed buffer length per serialize transaction */
+       int seral_state;        /* state of serialize */
+       int serial_sub_state;   /* sub state of each state, currently idx only */
+
+       /* saved data elements */
+       wsr_elem_t elem[WSR_REPORT_MAX_DATA];
+} wsr_info_t;
+
+/* ring buf control functions */
+static inline int wsr_get_write_idx(wsr_info_t *wsr_info);
+static inline int wsr_get_first_idx(wsr_info_t *wsr_info);
+static inline int wsr_get_last_idx(wsr_info_t *wsr_info);
+static inline int wsr_get_next_idx(wsr_info_t *wsr_info, int cur_idx);
+static inline void wsr_set_conn_idx(wsr_info_t *wsr_info);
+static inline int wsr_get_conn_idx(wsr_info_t *wsr_info, int max_cnt);
+static inline int wsr_get_count(int start_idx, int end_idx);
+
+/* ring buf serializing record protection lock */
+static inline void wsr_set_lock_idx(wsr_info_t *wsr_info, int max_cnt);
+static inline void wsr_free_lock_idx(wsr_info_t *wsr_info);
+static inline int wsr_get_lock_idx(wsr_info_t *wsr_info);
+static inline void wsr_decr_lock_count(wsr_info_t *wsr_info);
+static inline int wsr_get_lock_cnt(wsr_info_t *wsr_info);
+/* ring buff internal functions , no mutex lock */
+static int __wsr_get_write_idx(wsr_info_t *wsr_info);
+static inline int __wsr_get_first_idx(wsr_info_t *wsr_info);
+static int __wsr_get_next_idx(wsr_info_t *wsr_info, int cur_idx);
+static int __wsr_get_conn_idx(wsr_info_t *wsr_info, int max_cnt);
+
+/* status gathering functions */
+static inline void wsr_copy_cntinfo(wsr_elem_t *elem, wl_cnt_info_t *cntinfo);
+static void wsr_get_conn_info(struct bcm_cfg80211 *cfg, wsr_elem_t *elem);
+static void wsr_get_clock_info(wsr_elem_t *elem);
+static void wsr_gather_link_quality(struct bcm_cfg80211 *cfg, wsr_elem_t *elem);
+static void wsr_gather_adps(struct bcm_cfg80211 *cfg, wsr_elem_t *elem);
+
+#if defined(WSR_DEBUG)
+
+#define WSR_DEBUG_PRD  5       /* print debug every 5 recrod */
+typedef struct wpa_stat_report_elem {
+       wsr_clock_t clock;
+       wsr_conn_t conn;
+
+       /* Counters */
+       uint32 txframe;
+       uint32 rxmgocast;
+
+       /* Other Values */
+       wsr_link_t link_quality;
+       wsr_adps_t adps;
+} wsr_dbg_elem_t;
+
+static void wsr_dbg_main(wsr_info_t *wsr_info);
+static void wsr_dbg_copy_elem(wsr_dbg_elem_t *dest, wsr_elem_t *src);
+static void wsr_dbg_copy_cnts(wsr_dbg_elem_t *dest, wsr_elem_t *src);
+static inline void wsr_dbg_copy_conn(wsr_dbg_elem_t *dest, wsr_elem_t *src);
+static inline void wsr_dbg_copy_clock(wsr_dbg_elem_t *dest, wsr_elem_t *src);
+static inline void wsr_dbg_copy_link(wsr_dbg_elem_t *dest, wsr_elem_t *src);
+static inline void wsr_dbg_copy_adps(wsr_dbg_elem_t *dest, wsr_elem_t *src);
+static void wsr_dbg_print_elem(wsr_dbg_elem_t *elem);
+#endif /* WSR_DEBUG */
+
+#ifdef STAT_REPORT_TEMP_STATIC
+#undef DHD_OS_PREALLOC
+#undef DHD_OS_PREFREE
+
+#define DHD_OS_PREALLOC(dhdpub, section, size) ({\
+               int kflags; \
+               void *__ret; \
+               kflags = in_atomic() ?GFP_ATOMIC : GFP_KERNEL; \
+               __ret = kzalloc(size, kflags); \
+               __ret; \
+})
+
+#define DHD_OS_PREFREE(dhdpub, addr, size) kfree(addr)
+#endif /* STAT_REPORT_TEMP_STATIC */
+
+/* ========= Module functions : exposed to others ============= */
+int
+wl_attach_stat_report(void *cfg)
+{
+       struct bcm_cfg80211 *pcfg = (struct bcm_cfg80211 *)cfg;
+       wsr_info_t *wsr_info;
+       dhd_pub_t *dhdp = pcfg->pub;
+
+       if (!pcfg) {
+               WL_ERR(("FAIL to ATTACH STAT REPORT\n"));
+               return BCME_ERROR;
+       }
+
+       BCM_REFERENCE(dhdp);
+       wsr_info = (wsr_info_t *)DHD_OS_PREALLOC(dhdp,
+               DHD_PREALLOC_STAT_REPORT_BUF, sizeof(wsr_info_t));
+       if (unlikely(!wsr_info)) {
+               WL_ERR(("FAIL to alloc for STAT REPORT INFO\n"));
+               return BCME_ERROR;
+       }
+
+       /* Initialize control block */
+       mutex_init(&wsr_info->ring_sync);
+       wsr_info->version = WSR_REPORT_VERSION;
+       wsr_info->enabled = TRUE;
+       wsr_info->read_idx = WSR_INVALID;
+       wsr_info->write_idx = WSR_INVALID;
+       wsr_info->conn_idx = WSR_INVALID;
+       wsr_info->lock_idx = WSR_INVALID;
+       pcfg->stat_report_info = wsr_info;
+       ((dhd_pub_t *)(pcfg->pub))->stat_report_info = wsr_info;
+       return BCME_OK;
+}
+
+void
+wl_detach_stat_report(void *cfg)
+{
+       struct bcm_cfg80211 *pcfg = (struct bcm_cfg80211 *)cfg;
+       wsr_info_t *wsr_info;
+       dhd_pub_t *dhdp = pcfg->pub;
+
+       if (!pcfg) {
+               return;
+       }
+       BCM_REFERENCE(dhdp);
+       if (pcfg->stat_report_info) {
+               wsr_info = (wsr_info_t *)pcfg->stat_report_info;
+               mutex_destroy(&wsr_info->ring_sync);
+               DHD_OS_PREFREE(dhdp, pcfg->stat_report_info,
+                       sizeof(wsr_info_t));
+               pcfg->stat_report_info = NULL;
+       }
+}
+
+/* query dongle status data */
+void
+wl_stat_report_gather(void *cfg, void *cnt)
+{
+       int write_idx;
+       wl_cnt_info_t *cntinfo = (wl_cnt_info_t *)cnt;
+       struct bcm_cfg80211 *pcfg = (struct bcm_cfg80211 *)cfg;
+       wsr_info_t *wsr_info = pcfg->stat_report_info;
+       wsr_elem_t *elem;
+
+       /* Check Validation of counters */
+       if (cntinfo->version < WL_CNT_VERSION_XTLV) {
+               WL_ERR(("NOT supported CNT version\n"));
+               return;
+       }
+       if (wsr_info == NULL) {
+               WL_INFORM(("NOT enabled\n"));
+               return;
+       }
+
+       /* no available slot, due to oldest slot is locked */
+       write_idx = wsr_get_write_idx(wsr_info);
+       if (write_idx == WSR_INVALID) {
+               WL_ERR(("SKIP to logging due to locking\n"));
+               return;
+       }
+
+       elem = &wsr_info->elem[write_idx];
+       wsr_get_conn_info(pcfg, elem);
+       wsr_get_clock_info(elem);
+       wsr_copy_cntinfo(elem, cntinfo);
+       wsr_gather_link_quality(pcfg, elem);
+       wsr_gather_adps(pcfg, elem);
+
+#if defined(WSR_DEBUG)
+       {
+               static int pr_cnt = 0;
+               if ((pr_cnt++) % WSR_DEBUG_PRD == 0) {
+                       wsr_dbg_main(wsr_info);
+               }
+       }
+#endif /* WSR_DEBUG */
+}
+
+void
+wl_stat_report_notify_connected(void *cfg)
+{
+       struct bcm_cfg80211 *pcfg = (struct bcm_cfg80211 *)cfg;
+       wsr_info_t *wsr_info = pcfg->stat_report_info;
+
+       /* Set conn idx to next write idx */
+       wsr_set_conn_idx(wsr_info);
+}
+
+/* ========= Ring buffer management ============= */
+/* Get next index can be written
+ * will overwrite which doesn't read
+ * will return -1 if next pointer is locked
+ */
+static int
+__wsr_get_write_idx(wsr_info_t *wsr_info)
+{
+       int tmp_idx;
+
+       if (wsr_info->read_idx == WSR_INVALID) {
+               wsr_info->read_idx = wsr_info->write_idx = 0;
+               return wsr_info->write_idx;
+       }
+
+       /* check next index is not locked */
+       tmp_idx = (wsr_info->write_idx + 1) % WSR_REPORT_MAX_DATA;
+       if (wsr_info->lock_idx == tmp_idx) {
+               return WSR_INVALID;
+       }
+
+       wsr_info->write_idx = tmp_idx;
+       if (wsr_info->write_idx == wsr_info->read_idx) {
+               /* record is full, drop oldest one */
+               wsr_info->read_idx = (wsr_info->read_idx + 1) % WSR_REPORT_MAX_DATA;
+
+               /* set all data is for this connection */
+               if (wsr_info->read_idx == wsr_info->conn_idx) {
+                       wsr_info->conn_idx = WSR_INVALID;
+               }
+       }
+       return wsr_info->write_idx;
+
+}
+
+static inline int
+wsr_get_write_idx(wsr_info_t *wsr_info)
+{
+       int ret_idx;
+       mutex_lock(&wsr_info->ring_sync);
+       ret_idx = __wsr_get_write_idx(wsr_info);
+       mutex_unlock(&wsr_info->ring_sync);
+       return ret_idx;
+}
+
+/* Get read index : oldest element */
+static inline int
+__wsr_get_first_idx(wsr_info_t *wsr_info)
+{
+       if (wsr_info->read_idx == WSR_INVALID) {
+               return WSR_INVALID;
+       }
+
+       return wsr_info->read_idx;
+}
+
+static inline int
+wsr_get_first_idx(wsr_info_t *wsr_info)
+{
+       int ret_idx;
+       mutex_lock(&wsr_info->ring_sync);
+       ret_idx = __wsr_get_first_idx(wsr_info);
+       mutex_unlock(&wsr_info->ring_sync);
+       return ret_idx;
+}
+
+/* Get latest element */
+static inline int
+wsr_get_last_idx(wsr_info_t *wsr_info)
+{
+       int ret_idx;
+       mutex_lock(&wsr_info->ring_sync);
+       ret_idx = wsr_info->write_idx;
+       mutex_unlock(&wsr_info->ring_sync);
+       return ret_idx;
+}
+
+/* get counts between two indexes of ring buffer */
+static inline int
+wsr_get_count(int start_idx, int end_idx)
+{
+       if (start_idx == WSR_INVALID || end_idx == WSR_INVALID) {
+               return 0;
+       }
+
+       return (WSR_REPORT_MAX_DATA + end_idx - start_idx) % WSR_REPORT_MAX_DATA + 1;
+}
+
+/* Set conn idx to next write idx */
+static inline void
+wsr_set_conn_idx(wsr_info_t *wsr_info)
+{
+       mutex_lock(&wsr_info->ring_sync);
+       wsr_info->conn_idx = __wsr_get_next_idx(wsr_info, wsr_info->write_idx);
+       mutex_unlock(&wsr_info->ring_sync);
+}
+
+/* Get first record of this connection
+ * if conn_idx = -1, all record is for this connection, return first
+ * if counts btwn. conn and write, then return (write - max)
+ * else return conn idx
+ */
+static int
+__wsr_get_conn_idx(wsr_info_t *wsr_info, int max_cnt)
+{
+       int counts;
+
+       if (wsr_info->read_idx == WSR_INVALID) {
+               return WSR_INVALID;
+       }
+
+       if (wsr_info->conn_idx == WSR_INVALID) {
+               counts = wsr_get_count(wsr_info->read_idx, wsr_info->write_idx);
+       } else {
+               counts = wsr_get_count(wsr_info->conn_idx, wsr_info->write_idx);
+       }
+
+       counts = MIN(counts, max_cnt);
+       return (WSR_REPORT_MAX_DATA + wsr_info->write_idx - counts + 1) % WSR_REPORT_MAX_DATA;
+}
+
+static inline int
+wsr_get_conn_idx(wsr_info_t *wsr_info, int max_cnt)
+{
+       int con_idx;
+       mutex_lock(&wsr_info->ring_sync);
+       con_idx = __wsr_get_conn_idx(wsr_info, max_cnt);
+       mutex_unlock(&wsr_info->ring_sync);
+       return con_idx;
+}
+
+static int
+__wsr_get_next_idx(wsr_info_t *wsr_info, int cur_idx)
+{
+       if (wsr_info->read_idx == WSR_INVALID) {
+               return WSR_INVALID;
+       }
+
+       if (cur_idx == wsr_info->write_idx) {
+               /* no more new record */
+               return WSR_INVALID;
+       }
+
+       return ((cur_idx +1) % WSR_REPORT_MAX_DATA);
+}
+
+static inline int
+wsr_get_next_idx(wsr_info_t *wsr_info, int cur_idx)
+{
+       int next_idx;
+       mutex_lock(&wsr_info->ring_sync);
+       next_idx = __wsr_get_next_idx(wsr_info, cur_idx);
+       mutex_unlock(&wsr_info->ring_sync);
+       return next_idx;
+}
+
+static inline void
+wsr_set_lock_idx(wsr_info_t *wsr_info, int max_cnt)
+{
+       mutex_lock(&wsr_info->ring_sync);
+       wsr_info->lock_idx = __wsr_get_conn_idx(wsr_info, max_cnt);
+       wsr_info->lock_count = wsr_get_count(wsr_info->lock_idx, wsr_info->write_idx);
+       mutex_unlock(&wsr_info->ring_sync);
+}
+
+static inline void
+wsr_free_lock_idx(wsr_info_t *wsr_info)
+{
+       mutex_lock(&wsr_info->ring_sync);
+       wsr_info->lock_idx = WSR_INVALID;
+       wsr_info->lock_count = 0;
+       mutex_unlock(&wsr_info->ring_sync);
+}
+
+static inline int
+wsr_get_lock_idx(wsr_info_t *wsr_info)
+{
+       int ret_idx;
+       mutex_lock(&wsr_info->ring_sync);
+       ret_idx = wsr_info->lock_idx;
+       mutex_unlock(&wsr_info->ring_sync);
+       return ret_idx;
+}
+
+static inline void
+wsr_decr_lock_count(wsr_info_t *wsr_info)
+{
+
+       mutex_lock(&wsr_info->ring_sync);
+       wsr_info->lock_count--;
+       if (wsr_info->lock_count <= 0) {
+               wsr_info->lock_idx = WSR_INVALID;
+       } else {
+               wsr_info->lock_idx = __wsr_get_next_idx(wsr_info, wsr_info->lock_idx);
+       }
+       mutex_unlock(&wsr_info->ring_sync);
+}
+
+static inline int
+wsr_get_lock_cnt(wsr_info_t *wsr_info)
+{
+       int cnt;
+       mutex_lock(&wsr_info->ring_sync);
+       cnt = wsr_info->lock_count;
+       mutex_unlock(&wsr_info->ring_sync);
+       return cnt;
+}
+
+/* ========= Status Query Functions ============= */
+static inline void
+wsr_get_op_mode(struct bcm_cfg80211 *cfg, wsr_elem_t *elem)
+{
+       dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+
+       elem->conn.dhd_opmode = dhd->op_mode;
+}
+
+static void
+wsr_get_conn_info(struct bcm_cfg80211 *cfg, wsr_elem_t *elem)
+{
+       struct wl_profile *profile = wl_get_profile_by_netdev(cfg, bcmcfg_to_prmry_ndev(cfg));
+
+       memset(&elem->conn, 0, sizeof(elem->conn));
+       if (!profile) {
+               return;
+       }
+
+       memcpy(elem->conn.bssid, profile->bssid, ETHER_ADDR_LEN);
+       elem->conn.oui_cnt = wl_cfg80211_get_vndr_ouilist(cfg,
+               (uint8 *)&elem->conn.oui_list, WSR_MAX_OUI);
+
+       wsr_get_op_mode(cfg, elem);
+       return;
+}
+
+static void
+wsr_get_clock_info(wsr_elem_t *elem)
+{
+       struct timespec ts;
+       struct tm tm;
+       u64 tv_kernel =  local_clock();
+       wsr_clock_t *clock = &elem->clock;
+
+       getnstimeofday(&ts);
+       time_to_tm((ts.tv_sec - (sys_tz.tz_minuteswest*WSR_REPORT_MINUTES)), 0, &tm);
+
+       /* save seconds only */
+       clock->kernel_clock = (uint32)(tv_kernel/WSR_NONSEC_TO_SEC);
+       clock->date = (tm.tm_year + WSR_REPORT_YEAR_BASE) * WSR_REPORT_YEAR_MUL;
+       clock->date += (tm.tm_mon +1) * WSR_REPORT_MON_MUL;
+       clock->date += tm.tm_mday;
+       clock->time = tm.tm_hour * WSR_REPORT_HOUR_MUL;
+       clock->time += tm.tm_min * WSR_REPORT_MIN_MUL;
+       clock->time += tm.tm_sec;
+}
+
+static inline void
+wsr_copy_cntinfo(wsr_elem_t *elem, wl_cnt_info_t *cntinfo)
+{
+       uint32 copy_len;
+       copy_len = MIN((uint32)OFFSETOF(wl_cnt_info_t, data)+ cntinfo->datalen, WSR_CNT_SIZE);
+
+       memcpy(elem->cntinfo, cntinfo, copy_len);
+}
+
+#ifndef LQCM_ENAB_MASK
+#define LQCM_ENAB_MASK                 0x000000FF      /* LQCM enable flag mask */
+#define LQCM_TX_INDEX_MASK             0x0000FF00      /* LQCM tx index mask */
+#define LQCM_RX_INDEX_MASK             0x00FF0000      /* LQCM rx index mask */
+
+#define LQCM_TX_INDEX_SHIFT            8       /* LQCM tx index shift */
+#define LQCM_RX_INDEX_SHIFT            16      /* LQCM rx index shift */
+#endif /* LQCM_ENAB_MASK */
+
+static void
+wsr_gather_link_quality(struct bcm_cfg80211 *cfg, wsr_elem_t *elem)
+{
+       int err;
+       uint32 val;
+       uint8 uint8_v;
+       scb_val_t scbval;
+
+       memset(&elem->link_quality, 0, sizeof(elem->link_quality));
+
+       err = wldev_iovar_getint(bcmcfg_to_prmry_ndev(cfg), "lqcm", &val);
+       if (err != BCME_OK) {
+               WL_ERR(("failed to get lqcm report, error = %d\n", err));
+               return;
+       }
+       if (!(val & LQCM_ENAB_MASK)) {
+               elem->link_quality.lqcm = -1;
+       } else {
+               uint8_v = (val & LQCM_TX_INDEX_MASK) >> LQCM_TX_INDEX_SHIFT;
+               elem->link_quality.lqcm = (int8)uint8_v;
+       }
+
+       err = wldev_iovar_getint(bcmcfg_to_prmry_ndev(cfg), "snr", &val);
+       if (err != BCME_OK) {
+               WL_ERR((" Failed to get SNR %d, error = %d\n", val, err));
+               return;
+       }
+       elem->link_quality.snr = *(uint8 *)&val;
+
+       err = wldev_get_rssi(bcmcfg_to_prmry_ndev(cfg), &scbval);
+       if (err != BCME_OK) {
+               WL_ERR(("failed to get rssi, error = %d\n", err));
+               return;
+       }
+       elem->link_quality.rssi = *((int8 *)((int32 *)&scbval.val));
+
+}
+
+#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD)
+#ifndef ADPS_MODE_OFF
+#define ADPS_MODE_OFF  0
+#define ADPS_STEP_HIGH 1
+#define ADPS_STEP_LOW  0
+#endif /* ADPS_MODE_OFF */
+
+static void
+wsr_gather_adps(struct bcm_cfg80211 *cfg, wsr_elem_t *elem)
+{
+       int err;
+       uint8 dump_sub_cmd = 0;
+       uint8 *data;
+       bcm_iov_buf_t iov_buf;
+       bcm_iov_buf_t *resp;
+       bcm_tlv_t *tlv;
+       char adps_buf[WLC_IOCTL_MEDLEN];
+       wl_adps_dump_summary_v1_t *summary;
+       wsr_adps_t *adps = &elem->adps;
+
+       memset(&elem->adps, 0, sizeof(elem->adps));
+
+       iov_buf.version = WL_ADPS_IOV_VER;
+       iov_buf.len = sizeof(dump_sub_cmd);
+       iov_buf.id = WL_ADPS_IOV_DUMP;
+       data = (uint8 *)iov_buf.data;
+       data[0] = dump_sub_cmd;
+
+       err = wldev_iovar_getbuf(bcmcfg_to_prmry_ndev(cfg), "adps",
+               &iov_buf, sizeof(bcm_iov_buf_t), adps_buf, WLC_IOCTL_MEDLEN, NULL);
+       if (err) {
+               WL_ERR(("failed to get ADPS dump error = %d\n", err));
+               return;
+       }
+
+       resp = (bcm_iov_buf_t *)adps_buf;
+       tlv = (bcm_tlv_t *)resp->data;
+
+       if (!bcm_valid_tlv(tlv, resp->len)) {
+               WL_ERR(("Invalid TLV\n"));
+               return;
+       }
+
+       summary = (wl_adps_dump_summary_v1_t *)tlv->data;
+       if (tlv->len < OFFSETOF(wl_adps_dump_summary_v1_t, flags)) {
+               WL_ERR(("Id: %x - invaild length (%d)\n", tlv->id, tlv->len));
+               return;
+       }
+       if (summary->mode == ADPS_MODE_OFF) {
+               return;
+       }
+
+       adps->mode = summary->mode;
+       adps->flags = summary->flags;
+       adps->current_step = summary->current_step;
+       adps->duration_high = summary->stat[ADPS_STEP_HIGH].duration;
+       adps->duration_low = summary->stat[ADPS_STEP_LOW].duration;
+       adps->counts_high = summary->stat[ADPS_STEP_HIGH].counts;
+       adps->counts_low = summary->stat[ADPS_STEP_LOW].counts;
+}
+#else
+static void
+wsr_gather_adps(struct bcm_cfg80211 *cfg, wsr_elem_t *elem)
+{
+       WL_ERR(("ADPS is not enabled\n"));
+}
+#endif /* defined(WLADPS) || defined(WLADPS_PRIVATE_CMD) */
+/* ========= Debug Functions ============= */
+#if defined(WSR_DEBUG)
+static void
+wsr_dbg_main(wsr_info_t *wsr_info)
+{
+       int read_idx;
+       wsr_dbg_elem_t report_elem;
+
+       read_idx = wsr_get_conn_idx(wsr_info, WSR_REPORT_MAX_WPA_CNT);
+       WL_ERR(("WSR_DBG\n"));
+       WL_ERR(("WSR_DBG\n"));
+       WL_ERR(("WSR_DBG\n"));
+       WL_ERR(("WSR_DBG : counts: %d %d\n",
+               wsr_get_count(read_idx, wsr_info->write_idx), read_idx));
+       WL_ERR(("WSR_DBG : r:%d w:%d c:%d\n",
+               wsr_info->read_idx, wsr_info->write_idx, wsr_info->conn_idx));
+       while (read_idx != WSR_INVALID) {
+               wsr_elem_t *elem = &wsr_info->elem[read_idx];
+               wsr_dbg_copy_elem(&report_elem, elem);
+               wsr_dbg_print_elem(&report_elem);
+               read_idx = wsr_get_next_ptr(wsr_info, read_idx);
+       }
+
+}
+
+static void
+wsr_dbg_copy_elem(wsr_dbg_elem_t *dest, wsr_elem_t *src)
+{
+       wsr_dbg_copy_conn(dest, src);
+       wsr_dbg_copy_cnts(dest, src);
+       wsr_dbg_copy_clock(dest, src);
+       wsr_dbg_copy_link(dest, src);
+       wsr_dbg_copy_adps(dest, src);
+}
+
+static void
+wsr_dbg_copy_cnts(wsr_dbg_elem_t *dest, wsr_elem_t *src)
+{
+       wl_cnt_info_t *cntinfo = (wl_cnt_info_t *)src->cntinfo;
+       wl_cnt_wlc_t *wlc_cnt;
+       wl_cnt_ge40mcst_v1_t *macstat_cnt;
+
+       /* COPY WLC counts */
+       wlc_cnt = bcm_get_data_from_xtlv_buf(cntinfo->data, cntinfo->datalen,
+               WL_CNT_XTLV_WLC, NULL, BCM_XTLV_OPTION_ALIGN32);
+       if (wlc_cnt == NULL) {
+               WL_ERR(("WSR_DBG : NO CNT\n"));
+               return;
+       }
+       dest->txframe = wlc_cnt->txframe;
+
+       /* COPY MAC STAT counts */
+       macstat_cnt = bcm_get_data_from_xtlv_buf(cntinfo->data, cntinfo->datalen,
+               WL_CNT_XTLV_GE40_UCODE_V1, NULL, BCM_XTLV_OPTION_ALIGN32);
+       if (macstat_cnt == NULL) {
+               WL_ERR(("WSR_DBG : NO MAC STAT\n"));
+               return;
+       }
+       dest->rxmgocast = macstat_cnt->rxmgocast;
+}
+
+static inline void
+wsr_dbg_copy_conn(wsr_dbg_elem_t *dest, wsr_elem_t *src)
+{
+       memcpy(&dest->conn, &src->conn, sizeof(src->conn));
+}
+static inline void
+wsr_dbg_copy_clock(wsr_dbg_elem_t *dest, wsr_elem_t *src)
+{
+       memcpy(&dest->clock, &src->clock, sizeof(src->clock));
+}
+
+static inline void
+wsr_dbg_copy_link(wsr_dbg_elem_t *dest, wsr_elem_t *src)
+{
+       memcpy(&dest->link_quality, &src->link_quality, sizeof(src->link_quality));
+}
+
+static inline void
+wsr_dbg_copy_adps(wsr_dbg_elem_t *dest, wsr_elem_t *src)
+{
+       memcpy(&dest->adps, &src->adps, sizeof(src->adps));
+}
+
+static void
+wsr_dbg_print_elem(wsr_dbg_elem_t *elem)
+{
+       wsr_link_t *link = &elem->link_quality;
+       wsr_adps_t *adps = &elem->adps;
+       wsr_clock_t *clock = &elem->clock;
+       wsr_conn_t *conn = &elem->conn;
+       int idx;
+
+       WL_ERR(("WSR_DBG: DATE [%u] %d-%02d-%02d %02d:%02d:%02d\n", clock->kernel_clock,
+               clock->date/WSR_REPORT_YEAR_MUL,
+               (clock->date%WSR_REPORT_YEAR_MUL)/WSR_REPORT_MON_MUL,
+               (clock->date%WSR_REPORT_YEAR_MUL)%WSR_REPORT_MON_MUL,
+               clock->time/WSR_REPORT_HOUR_MUL,
+               (clock->time%WSR_REPORT_HOUR_MUL)/WSR_REPORT_MIN_MUL,
+               (clock->time%WSR_REPORT_HOUR_MUL)%WSR_REPORT_MIN_MUL));
+       WL_ERR(("WSR_DBG: CONN bssid: "MACDBG"\n",
+               MAC2STRDBG(conn->bssid)));
+       WL_ERR(("WSR_DBG: CONN  op_mode:%x vndr oui: %d", conn->dhd_opmode, conn->oui_cnt));
+       for (idx = 0; idx < conn->oui_cnt; idx++) {
+               WL_ERR((" "MACOUIDBG,
+                       MACOUI2STRDBG(conn->oui_list[idx])));
+       }
+       WL_ERR(("WSR_DBG\n"));
+       WL_ERR(("WSR_DBG: CNT txframe:%d rxmgocast:%d\n", elem->txframe, elem->rxmgocast));
+       WL_ERR(("WSR_DBG: LINK LQCM %d SNR %d RSSI %d\n", link->lqcm, link->snr, link->rssi));
+       WL_ERR(("WSR_DBG: ADPS M:%d F:%d S:%d H:(%d %d) L:(%d %d)\n", adps->mode, adps->flags,
+               adps->current_step, adps->duration_high, adps->counts_high,
+               adps->duration_low, adps->counts_low));
+}
+#endif /* WSR_DEBUG */
+
+/* ========= File Save ============= */
+#define WSR_TYPE_MAGIC "WIFI_STAT_REPORT"
+void wl_stat_report_file_save(void *dhdp, void *fp)
+{
+       struct file *pfp = (struct file *)fp;
+       dhd_pub_t *ppub = (dhd_pub_t *)dhdp;
+       wsr_info_t *wsr_info;
+       int first_idx, last_idx, count, wr_count;
+       int wr_size;
+       int err;
+
+       if (!pfp || !ppub) {
+               WL_ERR(("pfp and/or dhdp is NULL\n"));
+               return;
+       }
+
+       wsr_info =  (wsr_info_t *)ppub->stat_report_info;
+       if (!wsr_info) {
+               WL_ERR(("stat control block is not exist\n"));
+               return;
+       }
+
+       err = generic_file_llseek(pfp, 0, SEEK_END);
+       if (err < 0) {
+               WL_ERR(("WRITE ERROR!!!! err = %d\n", err));
+               return;
+       }
+
+       /* WRITE MAGICS TYPE + TYPE + VER */
+       vfs_write(pfp, WSR_TYPE_MAGIC, strlen(WSR_TYPE_MAGIC), &pfp->f_pos);
+       vfs_write(pfp, WSR_TYPE_MAGIC, strlen(WSR_TYPE_MAGIC), &pfp->f_pos);
+       vfs_write(pfp, (const char *)&wsr_info->version, sizeof(wsr_info->version), &pfp->f_pos);
+
+       /* WRITE total data size */
+       first_idx = wsr_get_first_idx(wsr_info);
+       last_idx = wsr_get_last_idx(wsr_info);
+       count = wsr_get_count(first_idx, last_idx);
+       wr_size = count * sizeof(wsr_elem_t) + strlen(WSR_TYPE_MAGIC);
+       vfs_write(pfp, (const char *)&wr_size, sizeof(wr_size), &pfp->f_pos);
+       if (count <= 0) {
+               goto final_magic;
+       }
+
+       /* WRITE TO THE END OF ARRAY */
+       wr_count = (WSR_REPORT_MAX_DATA - first_idx);
+       vfs_write(pfp, (const char *)&wsr_info->elem[first_idx],
+               sizeof(wsr_elem_t) * wr_count, &pfp->f_pos);
+
+       /* WRITE WRAP UP */
+       count = count - wr_count;
+       if (count <= 0) {
+               goto final_magic;
+       }
+       vfs_write(pfp, (const char *)&wsr_info->elem[0], sizeof(wsr_elem_t) * count, &pfp->f_pos);
+
+final_magic:
+       /* WRITE MAIC */
+       vfs_write(pfp, WSR_TYPE_MAGIC, strlen(WSR_TYPE_MAGIC), &pfp->f_pos);
+
+}
+
+/* ========= Private Command ============= */
+#define WSR_REPORT_ELEM_PRINT_BUF      256
+#define WSR_REPORT_STATE_NORMAL 0
+#define WSR_REPORT_STATE_WLC   1
+#define WSR_REPORT_STATE_LAST  0xffff
+#define WSR_REPORT_NAME_MAX    20
+
+#define WSR_DEC        1
+#define WSR_HEX        2
+
+#define WSR_UINT8      1
+#define WSR_UINT32     2
+#define WSR_DATE       3
+#define WSR_TIME       4
+#define WSR_BSSID      5
+#define WSR_OUI        6
+#define WSR_CNT_WLC    7
+#define WSR_CNT_MAC    8
+
+#define WSR_SERIAL_MODE_RECORD_FIRST   1
+#define WSR_SERIAL_MODE_ITEM_FIRST             2
+typedef struct {
+       char name[WSR_REPORT_NAME_MAX];
+       uint32 offset;
+       int format;
+       int type;
+       int f_signed;
+} wsr_serial_info_normal_t;
+
+typedef int (*wsr_serial_sub_func)
+       (wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem);
+
+#define WSR_SERIAL_CLOCK(name, value, fmt, type, f_s) \
+{#name, (uint32)(OFFSETOF(wsr_elem_t, clock) + \
+               OFFSETOF(wsr_clock_t, value)), fmt, type, f_s}
+
+#define WSR_SERIAL_CONN(name, value, fmt, type, f_s) \
+{#name, (uint32)(OFFSETOF(wsr_elem_t, conn) + \
+               OFFSETOF(wsr_conn_t, value)), fmt, type, f_s}
+
+#define WSR_SERIAL_LINK(name, value, fmt, type, f_s) \
+{#name, (uint32)(OFFSETOF(wsr_elem_t, link_quality) + \
+               OFFSETOF(wsr_link_t, value)), fmt, type, f_s}
+
+#define WSR_SERIAL_ADPS(name, value, fmt, type, f_s) \
+{#name, (uint32)(OFFSETOF(wsr_elem_t, adps) + \
+               OFFSETOF(wsr_adps_t, value)), fmt, type, f_s}
+
+#define WSR_SERIAL_TXP(name, value, fmt, type, f_s) \
+{#name, (uint32)(OFFSETOF(wsr_elem_t, tx_power) + \
+               OFFSETOF(wsr_tx_power_t, value)), fmt, type, f_s}
+
+static wsr_serial_info_normal_t
+wsr_serial_info_normal_tbl[] = {
+       /* clock */
+       WSR_SERIAL_CLOCK(CLOCK, kernel_clock, WSR_DEC, WSR_UINT32, FALSE),
+       WSR_SERIAL_CLOCK(DATE, date, WSR_DEC, WSR_DATE, FALSE),
+       WSR_SERIAL_CLOCK(TIME, time, WSR_DEC, WSR_TIME, FALSE),
+
+       /* connection */
+       WSR_SERIAL_CONN(ADDR, bssid, WSR_HEX, WSR_BSSID, FALSE),
+       WSR_SERIAL_CONN(OPMODE, dhd_opmode, WSR_HEX, WSR_UINT32, FALSE),
+       WSR_SERIAL_CONN(OUI, oui_list, WSR_HEX, WSR_OUI, FALSE),
+
+       /* link quality */
+       WSR_SERIAL_LINK(LQCM, lqcm, WSR_DEC, WSR_UINT8, TRUE),
+       WSR_SERIAL_LINK(RSSI, rssi, WSR_DEC, WSR_UINT8, TRUE),
+       WSR_SERIAL_LINK(SNR, snr, WSR_DEC, WSR_UINT8, FALSE),
+
+       /* adps */
+       WSR_SERIAL_ADPS(ADPS_MODE, mode, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_ADPS(ADPS_LFAG, flags, WSR_HEX, WSR_UINT8, FALSE),
+       WSR_SERIAL_ADPS(ADPS_STEP, current_step, WSR_DEC, WSR_UINT8, FALSE),
+#ifndef WSR_MINIMIZE_REPORT
+       WSR_SERIAL_ADPS(ADPS_DH, duration_high, WSR_DEC, WSR_UINT32, FALSE),
+       WSR_SERIAL_ADPS(ADPS_DL, duration_low, WSR_DEC, WSR_UINT32, FALSE),
+       WSR_SERIAL_ADPS(ADPS_CH, counts_high, WSR_DEC, WSR_UINT32, FALSE),
+       WSR_SERIAL_ADPS(ADPS_CL, counts_low, WSR_DEC, WSR_UINT32, FALSE),
+#endif /* WSR_MINIMIZE_REPORT */
+
+       /* TX PWR */
+       WSR_SERIAL_TXP(SAR_ENAB, sar_enable, WSR_DEC, WSR_UINT8, FALSE),
+#ifndef WSR_MINIMIZE_REPORT
+       WSR_SERIAL_TXP(RSDB_MOD, phy_rsdb_mode, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(SAR_2G_C0, sar_limit_2g_core0, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(SAR_2G_C1, sar_limit_2g_core1, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(SAR_5G_C0, sar_limit_5g_core0, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(SAR_5G_C1, sar_limit_5g_core1, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(FCC, fcc_enable, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(FCC_CH12, fccpwrch12, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(FCC_CH13, fccpwrch13, WSR_DEC, WSR_UINT8, FALSE),
+#endif /* WSR_MINIMIZE_REPORT */
+       WSR_SERIAL_TXP(BSS_L_MAX, bss_local_max, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(BSS_L_CST, bss_local_constraint, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(DSSS_1M, dsss_1mbps_2g, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(OFDM_6M_2G, ofdm_6mbps_2g, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(MCS0_2G, mcs_0_2g, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(OFDM_6M_5G, ofdm_6mbps_5g, WSR_DEC, WSR_UINT8, FALSE),
+       WSR_SERIAL_TXP(MCS0_5G, mcs_0_5g, WSR_DEC, WSR_UINT8, FALSE),
+       {"", 0, 0, 0, 0}
+};
+
+/* Serialize 1 byte variable with requested format/signed */
+static int
+wsr_serial_uint8(wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem)
+{
+       int bytes_written = 0;
+       uint8 *ptr;
+       int8 *ptr2;
+       char *fmt;
+       char *null_fmt = " -255";
+
+       if (buf_len <= strlen(null_fmt)) {
+               return -1;
+       }
+
+       if (elem == NULL) {
+               bytes_written = scnprintf(buf, buf_len, " 0");
+               return bytes_written;
+       }
+
+       ptr = ptr2 = (uint8 *)((char *)elem + info->offset);
+       switch (info->format) {
+               case WSR_DEC:
+                       if (info->f_signed) {
+                               fmt = " %d";
+                       } else {
+                               fmt = " %u";
+                       }
+                       break;
+               case WSR_HEX:
+                       fmt = " 0x%02x";
+                       break;
+               default:
+                       WL_ERR(("UKNOWN FMT\n"));
+                       return -1;
+       }
+
+       bytes_written = scnprintf(buf, buf_len, fmt, info->f_signed?(*ptr2) :(*ptr));
+       return bytes_written;
+}
+
+/* Serialize 4 byte variable with requested format/signed */
+static int
+wsr_serial_uint32(wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem)
+{
+       int bytes_written = 0;
+       uint32 *ptr;
+       int32 *ptr2;
+       char *fmt;
+       char *null_fmt = " -4294967295";
+
+       if (buf_len <= strlen(null_fmt)) {
+               return -1;
+       }
+
+       if (elem == NULL) {
+               bytes_written = scnprintf(buf, buf_len, " 0");
+               return bytes_written;
+       }
+
+       ptr = ptr2 = (uint32 *)((char *)elem + info->offset);
+       switch (info->format) {
+               case WSR_DEC:
+                       if (info->f_signed) {
+                               fmt = " %d";
+                       } else {
+                               fmt = " %u";
+                       }
+                       break;
+               case WSR_HEX:
+                       fmt = " 0x%08x";
+                       break;
+               default:
+                       WL_ERR(("UKNOWN FMT\n"));
+                       return -1;
+       }
+
+       bytes_written = scnprintf(buf, buf_len, fmt, info->f_signed?(*ptr2) :(*ptr));
+       return bytes_written;
+}
+
+/* serialize WSR date variable to date format */
+static int
+wsr_serial_date(wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem)
+{
+       int bytes_written = 0;
+       uint32 *ptr;
+       char *null_fmt = " 0-0-0";
+       char *norm_fmt = " 0000-00-00";
+
+       if (buf_len <= strlen(norm_fmt)) {
+               return -1;
+       }
+
+       if (elem == NULL) {
+               bytes_written = scnprintf(buf, buf_len, null_fmt);
+               return bytes_written;
+       }
+
+       ptr = (uint32 *)((char *)elem + info->offset);
+       bytes_written = scnprintf(buf, buf_len, " %d-%02d-%02d",
+                       (*ptr)/WSR_REPORT_YEAR_MUL,
+                       ((*ptr)%WSR_REPORT_YEAR_MUL)/WSR_REPORT_MON_MUL,
+                       ((*ptr)%WSR_REPORT_YEAR_MUL)%WSR_REPORT_MON_MUL);
+
+       return bytes_written;
+}
+
+/* serialize WSR time variable to time format */
+static int
+wsr_serial_time(wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem)
+{
+       int bytes_written = 0;
+       uint32 *ptr;
+       char *null_fmt = " 00:00:00";
+
+       if (buf_len <= strlen(null_fmt)) {
+               return -1;
+       }
+
+       if (elem == NULL) {
+               bytes_written = scnprintf(buf, buf_len, null_fmt);
+               return bytes_written;
+       }
+
+       ptr = (uint32 *)((char *)elem + info->offset);
+       bytes_written = scnprintf(buf, buf_len, " %02d:%02d:%02d",
+                       (*ptr)/WSR_REPORT_HOUR_MUL,
+                       ((*ptr)%WSR_REPORT_HOUR_MUL)/WSR_REPORT_MIN_MUL,
+                       ((*ptr)%WSR_REPORT_HOUR_MUL)%WSR_REPORT_MIN_MUL);
+
+       return bytes_written;
+}
+
+/* serialize BSSID type */
+static int
+wsr_serial_bssid(wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem)
+{
+       int bytes_written = 0;
+       int idx;
+       uint8 *ptr;
+       char *null_fmt = " 00:00:00:00:00:00";
+
+
+       if (buf_len <= strlen(null_fmt)) {
+               return -1;
+       }
+
+       if (elem == NULL) {
+               bytes_written = scnprintf(buf, buf_len, null_fmt);
+               return bytes_written;
+       }
+
+       ptr = (uint8 *)((char *)elem + info->offset);
+
+       for (idx = 0; idx < ETHER_ADDR_LEN; idx++) {
+               bytes_written += scnprintf(&buf[bytes_written],
+                       buf_len - bytes_written, ":%02x", *ptr);
+               ptr++;
+       }
+
+       /* start with white space */
+       buf[0] = ' ';
+
+       return bytes_written;
+}
+
+/* Serialize OUI type */
+static int
+wsr_serial_oui(wsr_serial_info_normal_t *info, char *buf, int buf_len, wsr_elem_t *elem)
+{
+       int bytes_written = 0;
+       int idx;
+       uint8 *ptr;
+       char *null_fmt = " 00-00-00";
+
+
+       if (buf_len <= strlen(null_fmt) * WSR_MAX_OUI) {
+               return -1;
+       }
+
+       if (elem == NULL) {
+               for (idx = 0; idx < WSR_MAX_OUI; idx++) {
+                       bytes_written += scnprintf(&buf[bytes_written],
+                               buf_len - bytes_written, null_fmt);
+               }
+               goto serial_oui_finish;
+       }
+
+       ptr = (uint8 *)((char *)elem + info->offset);
+
+       for (idx = 0; idx < DOT11_OUI_LEN * WSR_MAX_OUI; idx++) {
+               bytes_written += scnprintf(&buf[bytes_written],
+                       buf_len - bytes_written, "-%02x", *ptr);
+               ptr++;
+       }
+
+serial_oui_finish:
+       /* start with white space */
+       for (idx = 0; idx < WSR_MAX_OUI; idx++) {
+               ptr = &buf[idx * strlen(null_fmt)];
+               *ptr = ' ';
+       }
+
+       return bytes_written;
+}
+
+static int
+wsr_serial_normal(char *buf, int *sub_idx, wsr_elem_t **list, int list_cnt)
+{
+       int bytes_written = 0;
+       int cur_written = 0;
+       wsr_serial_info_normal_t *info;
+       char tmp_buf[WSR_REPORT_ELEM_PRINT_BUF] = {0, };
+       wsr_serial_sub_func func;
+       int idx;
+
+       if (strlen(wsr_serial_info_normal_tbl[*sub_idx].name) == 0) {
+               /* Serialize normal is finished */
+               return 0;
+       }
+
+       info = &wsr_serial_info_normal_tbl[*sub_idx];
+       /* set sub function */
+       switch (info->type) {
+               case WSR_UINT8:
+                       func = wsr_serial_uint8;
+                       break;
+               case WSR_UINT32:
+                       func = wsr_serial_uint32;
+                       break;
+               case WSR_BSSID:
+                       func = wsr_serial_bssid;
+                       break;
+               case WSR_OUI:
+                       func = wsr_serial_oui;
+                       break;
+               case WSR_DATE:
+                       func = wsr_serial_date;
+                       break;
+               case WSR_TIME:
+                       func = wsr_serial_time;
+                       break;
+               default:
+                       WL_ERR(("UNKNOWN SERIALIZE TYPE\n"));
+                       return -1;
+       }
+
+       for (idx = 0; idx < list_cnt; idx++) {
+               cur_written = func(info, &tmp_buf[bytes_written],
+                       sizeof(tmp_buf) - bytes_written, list[idx]);
+               if (cur_written <= 0) {
+                       /* need bigger buffer */
+                       return -1;
+               }
+
+               bytes_written += cur_written;
+       }
+
+       memcpy(buf, tmp_buf, bytes_written);
+       (*sub_idx)++;
+       return bytes_written;
+}
+
+#define WSR_SERIAL_WLC(a) {#a, OFFSETOF(wl_cnt_wlc_t, a), WSR_CNT_WLC}
+#define WSR_SERIAL_MAC(a) {#a, OFFSETOF(wl_cnt_ge40mcst_v1_t, a), WSR_CNT_MAC}
+typedef struct {
+       char name[WSR_REPORT_NAME_MAX];
+       uint32 offset;
+       int type;
+} wsr_serial_info_count_t;
+
+static wsr_serial_info_count_t
+wsr_serial_info_wlc_tbl[] = {
+       /* counts of wlc */
+#ifndef WSR_MINIMIZE_REPORT
+       WSR_SERIAL_WLC(txframe),
+#endif /* WSR_MINIMIZE_REPORT */
+       WSR_SERIAL_WLC(txretrans),
+       WSR_SERIAL_WLC(txfail),
+#ifndef WSR_MINIMIZE_REPORT
+       WSR_SERIAL_WLC(rxframe),
+       WSR_SERIAL_WLC(txphyerr),
+       WSR_SERIAL_WLC(rxnobuf),
+       WSR_SERIAL_WLC(rxrtry),
+#endif /* WSR_MINIMIZE_REPORT */
+       WSR_SERIAL_WLC(txprobereq),
+       WSR_SERIAL_WLC(rxprobersp),
+       WSR_SERIAL_MAC(txallfrm),
+       WSR_SERIAL_MAC(txrtsfrm),
+       WSR_SERIAL_MAC(txctsfrm),
+       WSR_SERIAL_WLC(txback),
+       WSR_SERIAL_MAC(txucast),
+       WSR_SERIAL_MAC(rxrsptmout),
+       WSR_SERIAL_MAC(txrtsfail),
+#ifndef WSR_MINIMIZE_REPORT
+       WSR_SERIAL_MAC(txphyerror),
+#endif /* WSR_MINIMIZE_REPORT */
+       WSR_SERIAL_MAC(rxstrt),
+       WSR_SERIAL_MAC(rxbadplcp),
+       WSR_SERIAL_MAC(rxcrsglitch),
+       WSR_SERIAL_MAC(rxnodelim),
+       WSR_SERIAL_MAC(bphy_badplcp),
+       WSR_SERIAL_MAC(bphy_rxcrsglitch),
+       WSR_SERIAL_MAC(rxbadfcs),
+       WSR_SERIAL_MAC(rxf0ovfl),
+       WSR_SERIAL_MAC(rxf1ovfl),
+       WSR_SERIAL_MAC(rxhlovfl),
+       WSR_SERIAL_MAC(rxrtsucast),
+       WSR_SERIAL_MAC(rxctsucast),
+       WSR_SERIAL_MAC(rxackucast),
+       WSR_SERIAL_WLC(rxback),
+       WSR_SERIAL_MAC(rxbeaconmbss),
+       WSR_SERIAL_MAC(rxdtucastmbss),
+       WSR_SERIAL_MAC(rxbeaconobss),
+       WSR_SERIAL_MAC(rxdtucastobss),
+       WSR_SERIAL_MAC(rxdtocast),
+       WSR_SERIAL_MAC(rxrtsocast),
+       WSR_SERIAL_MAC(rxctsocast),
+       WSR_SERIAL_MAC(rxdtmcast),
+#ifndef WSR_MINIMIZE_REPORT
+       WSR_SERIAL_WLC(rxmpdu_mu),
+       WSR_SERIAL_WLC(txassocreq),
+       WSR_SERIAL_WLC(txreassocreq),
+       WSR_SERIAL_WLC(txdisassoc),
+       WSR_SERIAL_WLC(txassocrsp),
+       WSR_SERIAL_WLC(txreassocrsp),
+       WSR_SERIAL_WLC(txauth),
+       WSR_SERIAL_WLC(txdeauth),
+       WSR_SERIAL_WLC(rxassocreq),
+       WSR_SERIAL_WLC(rxreassocreq),
+       WSR_SERIAL_WLC(rxdisassoc),
+       WSR_SERIAL_WLC(rxassocrsp),
+       WSR_SERIAL_WLC(rxreassocrsp),
+       WSR_SERIAL_WLC(rxauth),
+       WSR_SERIAL_WLC(rxdeauth),
+       WSR_SERIAL_MAC(txackfrm),
+       WSR_SERIAL_MAC(txampdu),
+       WSR_SERIAL_MAC(txmpdu),
+#endif /* WSR_MINIMIZE_REPORT */
+       {"", 0, 0}
+};
+
+static int
+wsr_serial_wlc(char *buf, int *sub_idx, wsr_elem_t **list, int list_cnt)
+{
+       int bytes_written = 0;
+       wsr_serial_info_count_t *info;
+       char tmp_buf[WSR_REPORT_ELEM_PRINT_BUF] = {0, };
+       int idx;
+       uint32 *ptr;
+       wl_cnt_info_t *cntinfo;
+       char *cntptr;
+
+       if (strlen(wsr_serial_info_wlc_tbl[*sub_idx].name) == 0) {
+               /* Serialize normal is finished */
+               return 0;
+       }
+
+       info = &wsr_serial_info_wlc_tbl[*sub_idx];
+
+       for (idx = 0; idx < list_cnt; idx++) {
+               if (bytes_written >= WSR_REPORT_ELEM_PRINT_BUF) {
+                       return -1;
+               }
+               if (list[idx] == NULL) {
+                       bytes_written += scnprintf(&tmp_buf[bytes_written],
+                               WSR_REPORT_ELEM_PRINT_BUF - bytes_written, " 0");
+                       continue;
+               }
+
+               /* find base PTR for WLC or MACSTAT */
+               cntinfo = (wl_cnt_info_t *)list[idx]->cntinfo;
+               if (info->type == WSR_CNT_WLC) {
+                       cntptr = (char *)bcm_get_data_from_xtlv_buf(cntinfo->data, cntinfo->datalen,
+                               WL_CNT_XTLV_WLC, NULL, BCM_XTLV_OPTION_ALIGN32);
+               } else if (info->type == WSR_CNT_MAC) {
+                       cntptr =  (char *)bcm_get_data_from_xtlv_buf(cntinfo->data,
+                               cntinfo->datalen,
+                               WL_CNT_XTLV_GE40_UCODE_V1, NULL, BCM_XTLV_OPTION_ALIGN32);
+               } else {
+                       WL_ERR(("INVALID TYPE\n"));
+                       return -1;
+               }
+
+               if (cntptr == NULL) {
+                       bytes_written += scnprintf(&tmp_buf[bytes_written],
+                               WSR_REPORT_ELEM_PRINT_BUF - bytes_written, " 0");
+               } else {
+                       ptr = (uint32 *)(cntptr + info->offset);
+                       bytes_written += scnprintf(&tmp_buf[bytes_written],
+                               WSR_REPORT_ELEM_PRINT_BUF - bytes_written, " %u",
+                               (*ptr) % WSR_CNT_VALUE_MAX);
+               }
+       }
+
+       memcpy(buf, tmp_buf, bytes_written);
+       (*sub_idx)++;
+       return bytes_written;
+}
+
+int
+wl_android_stat_report_get_start(void *net, char *cmd, int tot_len)
+{
+       struct net_device *dev = (struct net_device *)net;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       wsr_info_t *wsr_info = cfg->stat_report_info;
+       char *pcmd = cmd;
+       char *str_cmd;
+       char *str;
+       int mode, max_len;
+       int lock_count;
+       int bytes_written = 0;
+
+       /* SKIP command */
+       str_cmd = bcmstrtok(&pcmd, " ", NULL);
+
+       /* get MODE */
+       str = bcmstrtok(&pcmd, " ", NULL);
+       if (!str) {
+               WL_ERR(("NO mode for %s\n", str_cmd));
+               return BCME_ERROR;
+       }
+       mode = bcm_atoi(str);
+       if (mode != WSR_SERIAL_MODE_RECORD_FIRST &&
+               mode != WSR_SERIAL_MODE_ITEM_FIRST) {
+               WL_ERR(("NOT SUPPORTED MODE \n"));
+               return BCME_ERROR;
+       }
+
+
+       /* get max length */
+       str = bcmstrtok(&pcmd, " ", NULL);
+       if (!str) {
+               WL_ERR(("NO length for %s\n", str_cmd));
+               return BCME_ERROR;
+       }
+       max_len = bcm_atoi(str);
+       if (max_len <= WSR_REPORT_ELEM_PRINT_BUF) {
+               WL_ERR(("TO short buffer length (min=%d)\n", WSR_REPORT_ELEM_PRINT_BUF));
+               return BCME_ERROR;
+       }
+
+       /* Set seiralize info and lock record till serialzation is finished */
+       wsr_info->seral_mode = mode;
+       wsr_info->trans_buf_len = max_len;
+       wsr_set_lock_idx(wsr_info, WSR_REPORT_MAX_WPA_CNT);
+       wsr_info->seral_state = WSR_REPORT_STATE_NORMAL;
+       wsr_info->serial_sub_state = 0;
+
+       if (mode == WSR_SERIAL_MODE_RECORD_FIRST) {
+               lock_count = wsr_get_lock_cnt(wsr_info);
+               WL_ERR(("Lock WSR_SERIAL_MODE_RECORD_FIRST is set count= %d\n",
+                       lock_count));
+               bytes_written = scnprintf(cmd, tot_len, "%d", lock_count);
+               return bytes_written;
+       }
+
+       WL_ERR(("Lock WSR_SERIAL_MODE_ITEM_FIRST is set\n"));
+       return BCME_OK;
+}
+
+int
+wl_android_stat_report_get_next_mode_record(void *net, char *cmd, int tot_len)
+{
+       struct net_device *dev = (struct net_device *)net;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       wsr_info_t *wsr_info = cfg->stat_report_info;
+       wsr_elem_t *elem;
+       int bytes_written = 0;
+       int iter_written;
+       int lock_idx;
+
+       lock_idx = wsr_get_lock_idx(wsr_info);
+       if (lock_idx == WSR_INVALID) {
+               WL_ERR(("Lock pointer is not set\n"));
+               return BCME_ERROR;
+       }
+
+       elem = &wsr_info->elem[lock_idx];
+
+       memset(cmd, 0, wsr_info->trans_buf_len);
+       wsr_info->seral_state = WSR_REPORT_STATE_NORMAL;
+       wsr_info->serial_sub_state = 0;
+
+       while (bytes_written + WSR_REPORT_ELEM_PRINT_BUF < wsr_info->trans_buf_len) {
+               switch (wsr_info->seral_state) {
+                       case WSR_REPORT_STATE_NORMAL:
+                               iter_written = wsr_serial_normal(&cmd[bytes_written],
+                                       &wsr_info->serial_sub_state, &elem, 1);
+                               break;
+                       case WSR_REPORT_STATE_WLC:
+                               iter_written = wsr_serial_wlc(&cmd[bytes_written],
+                                       &wsr_info->serial_sub_state, &elem, 1);
+                               break;
+                       default:
+                               goto finished;
+               }
+
+               if (iter_written == 0) {
+                       wsr_info->seral_state++;
+                       wsr_info->serial_sub_state = 0;
+                       continue;
+               }
+               if (iter_written < 0) {
+                       WL_ERR(("At list one element is string lenght is too big(%d %d)\n",
+                               wsr_info->seral_state, wsr_info->serial_sub_state));
+                       wsr_free_lock_idx(wsr_info);
+                       return -1;
+               }
+               bytes_written += iter_written;
+       }
+
+       cmd[bytes_written] = '\0';
+       WL_ERR(("(len=%d) %s\n", bytes_written, cmd));
+       return bytes_written;
+
+finished:
+       cmd[bytes_written] = '\0';
+       wsr_decr_lock_count(wsr_info);
+
+       WL_ERR(("(len=%d) %s\n", bytes_written, cmd));
+       return bytes_written;
+}
+
+int
+wl_android_stat_report_get_next_mode_item(void *net, char *cmd, int tot_len)
+{
+       struct net_device *dev = (struct net_device *)net;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       wsr_info_t *wsr_info = cfg->stat_report_info;
+       wsr_elem_t *elem[WSR_REPORT_MAX_WPA_CNT] = {NULL, };
+       int idx;
+       int next_idx;
+       int bytes_written = 0;
+       int iter_written;
+       int lock_idx, lock_count;
+
+       lock_idx = wsr_get_lock_idx(wsr_info);
+       lock_count = wsr_get_lock_cnt(wsr_info);
+
+       if (lock_idx == WSR_INVALID) {
+               WL_ERR(("Lock pointer is not set\n"));
+               return BCME_ERROR;
+       }
+
+/* Init seiralze records of WSR_REPORT_MAX_WPA_CNT
+ * if locked record is less than WSR_REPORT_MAX_WPA_CNT
+ * fill NULL from first to WSR_REPORT_MAX_WPA_CNT - count
+ */
+       next_idx = lock_idx;
+       for (idx = WSR_REPORT_MAX_WPA_CNT - lock_count;
+               idx < WSR_REPORT_MAX_WPA_CNT; idx++) {
+               elem[idx] = &wsr_info->elem[next_idx];
+               next_idx = wsr_get_next_idx(wsr_info, next_idx);
+       }
+
+       memset(cmd, 0, wsr_info->trans_buf_len);
+       bytes_written = scnprintf(cmd, tot_len, "MORE");
+
+       while (bytes_written + WSR_REPORT_ELEM_PRINT_BUF < wsr_info->trans_buf_len) {
+               switch (wsr_info->seral_state) {
+                       case WSR_REPORT_STATE_NORMAL:
+                               iter_written = wsr_serial_normal(&cmd[bytes_written],
+                                       &wsr_info->serial_sub_state, elem, WSR_REPORT_MAX_WPA_CNT);
+                               break;
+                       case WSR_REPORT_STATE_WLC:
+                               iter_written = wsr_serial_wlc(&cmd[bytes_written],
+                                       &wsr_info->serial_sub_state, elem, WSR_REPORT_MAX_WPA_CNT);
+                               break;
+                       default:
+                               goto finished;
+               }
+
+               if (iter_written == 0) {
+                       wsr_info->seral_state++;
+                       wsr_info->serial_sub_state = 0;
+                       continue;
+               }
+               if (iter_written < 0) {
+                       WL_ERR(("At list one element is string lenght is too big(%d %d)\n",
+                               wsr_info->seral_state, wsr_info->serial_sub_state));
+                       goto finished;
+               }
+               bytes_written += iter_written;
+       }
+
+       cmd[bytes_written] = '\0';
+       WL_ERR(("(len=%d) %s\n", bytes_written, cmd));
+       return bytes_written;
+
+finished:
+       cmd[bytes_written] = '\0';
+       memcpy(cmd, "LAST", strlen("LAST"));
+       wsr_free_lock_idx(wsr_info);
+       WL_ERR(("(len=%d) %s\n", bytes_written, cmd));
+       return bytes_written;
+}
+
+int
+wl_android_stat_report_get_next(void *net, char *cmd, int tot_len)
+{
+       struct net_device *dev = (struct net_device *)net;
+       struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+       wsr_info_t *wsr_info = cfg->stat_report_info;
+
+       if (wsr_info == NULL) {
+               WL_ERR(("REPORT STAT is NOT enabled\n"));
+               return BCME_ERROR;
+       }
+
+       if (tot_len < wsr_info->trans_buf_len) {
+               WL_ERR(("To short buffer length (config:%d buf len:%d\n",
+                       wsr_info->trans_buf_len, tot_len));
+               wsr_free_lock_idx(wsr_info);
+               return BCME_ERROR;
+       }
+
+       if (wsr_info->seral_mode == WSR_SERIAL_MODE_RECORD_FIRST) {
+               return wl_android_stat_report_get_next_mode_record(net, cmd, tot_len);
+       } else {
+               return wl_android_stat_report_get_next_mode_item(net, cmd, tot_len);
+       }
+
+       return BCME_ERROR;
+}
diff --git a/drivers/net/wireless/bcmdhd_1_77/wl_statreport.h b/drivers/net/wireless/bcmdhd_1_77/wl_statreport.h
new file mode 100644 (file)
index 0000000..285c810
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+* Wifi dongle status logging and report
+*
+* Copyright (C) 1999-2018, Broadcom Corporation
+* 
+*      Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2 (the "GPL"),
+* available at http://www.broadcom.com/licenses/GPLv2.php, with the
+* following added to such license:
+* 
+*      As a special exception, the copyright holders of this software give you
+* permission to link this software with independent modules, and to copy and
+* distribute the resulting executable under terms of your choice, provided that
+* you also meet, for each linked independent module, the terms and conditions of
+* the license of that module.  An independent module is a module which is not
+* derived from this software.  The special exception does not apply to any
+* modifications of the software.
+* 
+*      Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a license
+* other than the GPL, without Broadcom's express prior written consent.
+*
+* <<Broadcom-WL-IPTag/Open:>>
+*
+* $Id: wl_statreport.h 707595 2017-06-28 08:28:30Z $
+*/
+#ifndef wl_stat_report_h
+#define wl_stat_report_h
+
+/* WSR module functions */
+int wl_attach_stat_report(void *cfg);
+void wl_detach_stat_report(void *cfg);
+void wl_stat_report_gather(void *cfg, void *cnt);
+void wl_stat_report_notify_connected(void *cfg);
+
+/* Private command functions */
+int wl_android_stat_report_get_start(void *net, char *cmd, int tot_len);
+int wl_android_stat_report_get_next(void *net, char *cmd, int tot_len);
+
+/* File Save functions */
+void wl_stat_report_file_save(void *dhdp, void *fp);
+#endif
index 7252cbd20d3dedc526665d00cfe1d8b762d4e273..7fa8b6f46b1e4a246920fde7bd42ac203ef5fbcb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Forward declarations for commonly used wl driver structs
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wlc_types.h 665242 2016-10-17 05:59:26Z $
+ * $Id: wlc_types.h 748342 2018-02-22 12:02:50Z $
  */
 
 #ifndef _wlc_types_h_
@@ -334,4 +334,5 @@ typedef wl_pfn_scanresult_v2_t wl_pfn_scanresult_t;
 
 typedef wl_dfs_ap_move_status_v2_t wl_dfs_ap_move_status_t;
 
+typedef wl_block_ch_v1_t wl_block_ch_t;
 #endif /* _wlc_types_h_ */
index 714854277908843867cce4ccdd71f971a080fc8c..71e56f758451f604ff4268fe0af5966397bc8310 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Common function shared by Linux WEXT, cfg80211 and p2p drivers
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wldev_common.c 676275 2016-12-21 07:10:30Z $
+ * $Id: wldev_common.c 733436 2017-11-28 10:53:14Z $
  */
 
 #include <osl.h>
@@ -57,7 +57,7 @@
 
 extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd);
 
-s32 wldev_ioctl(
+static s32 wldev_ioctl(
        struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
 {
        s32 ret = 0;
@@ -75,6 +75,34 @@ s32 wldev_ioctl(
        return ret;
 }
 
+
+/*
+SET commands :
+cast buffer to non-const  and call the GET function
+*/
+
+s32 wldev_ioctl_set(
+       struct net_device *dev, u32 cmd, const void *arg, u32 len)
+{
+
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+       return wldev_ioctl(dev, cmd, (void *)arg, len, 1);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+}
+
+
+s32 wldev_ioctl_get(
+       struct net_device *dev, u32 cmd, void *arg, u32 len)
+{
+       return wldev_ioctl(dev, cmd, (void *)arg, len, 0);
+}
+
 /* Format a iovar buffer, not bsscfg indexed. The bsscfg index will be
  * taken care of in dhd_ioctl_entry. Internal use only, not exposed to
  * wl_iw, wl_cfg80211 and wl_cfgp2p
@@ -97,8 +125,23 @@ s32 wldev_iovar_getbuf(
        if (buf_sync) {
                mutex_lock(buf_sync);
        }
-       wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
-       ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
+
+       if (buf && (buflen > 0)) {
+               /* initialize the response buffer */
+               memset(buf, 0, buflen);
+       } else {
+               ret = BCME_BADARG;
+               goto exit;
+       }
+
+       ret = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
+
+       if (!ret) {
+               ret = BCME_BUFTOOSHORT;
+               goto exit;
+       }
+       ret = wldev_ioctl_get(dev, WLC_GET_VAR, buf, buflen);
+exit:
        if (buf_sync)
                mutex_unlock(buf_sync);
        return ret;
@@ -116,7 +159,7 @@ s32 wldev_iovar_setbuf(
        }
        iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
        if (iovar_len > 0)
-               ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
+               ret = wldev_ioctl_set(dev, WLC_SET_VAR, buf, iovar_len);
        else
                ret = BCME_BUFTOOSHORT;
 
@@ -168,6 +211,11 @@ s32 wldev_mkiovar_bsscfg(
        u32 namelen;
        u32 iolen;
 
+       /* initialize buffer */
+       if (!iovar_buf || buflen == 0)
+               return BCME_BADARG;
+       memset(iovar_buf, 0, buflen);
+
        if (bssidx == 0) {
                return wldev_mkiovar(iovar_name, param, paramlen,
                        iovar_buf, buflen);
@@ -216,7 +264,7 @@ s32 wldev_iovar_getbuf_bsscfg(
        }
 
        wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
-       ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
+       ret = wldev_ioctl_get(dev, WLC_GET_VAR, buf, buflen);
        if (buf_sync) {
                mutex_unlock(buf_sync);
        }
@@ -235,7 +283,7 @@ s32 wldev_iovar_setbuf_bsscfg(
        }
        iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
        if (iovar_len > 0)
-               ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
+               ret = wldev_ioctl_set(dev, WLC_SET_VAR, buf, iovar_len);
        else {
                ret = BCME_BUFTOOSHORT;
        }
@@ -282,7 +330,8 @@ int wldev_get_link_speed(
 
        if (!plink_speed)
                return -ENOMEM;
-       error = wldev_ioctl(dev, WLC_GET_RATE, plink_speed, sizeof(int), 0);
+       *plink_speed = 0;
+       error = wldev_ioctl_get(dev, WLC_GET_RATE, plink_speed, sizeof(int));
        if (unlikely(error))
                return error;
 
@@ -298,8 +347,8 @@ int wldev_get_rssi(
 
        if (!scb_val)
                return -ENOMEM;
-
-       error = wldev_ioctl(dev, WLC_GET_RSSI, scb_val, sizeof(scb_val_t), 0);
+       memset(scb_val, 0, sizeof(scb_val_t));
+       error = wldev_ioctl_get(dev, WLC_GET_RSSI, scb_val, sizeof(scb_val_t));
        if (unlikely(error))
                return error;
 
@@ -313,7 +362,8 @@ int wldev_get_ssid(
 
        if (!pssid)
                return -ENOMEM;
-       error = wldev_ioctl(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t), 0);
+       memset(pssid, 0, sizeof(wlc_ssid_t));
+       error = wldev_ioctl_get(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t));
        if (unlikely(error))
                return error;
        pssid->SSID_len = dtoh32(pssid->SSID_len);
@@ -325,7 +375,8 @@ int wldev_get_band(
 {
        int error;
 
-       error = wldev_ioctl(dev, WLC_GET_BAND, pband, sizeof(uint), 0);
+       *pband = 0;
+       error = wldev_ioctl_get(dev, WLC_GET_BAND, pband, sizeof(uint));
        return error;
 }
 
@@ -334,8 +385,14 @@ int wldev_set_band(
 {
        int error = -1;
 
+#ifdef DHD_2G_ONLY_SUPPORT
+       if (band != WLC_BAND_2G) {
+               WLDEV_ERROR(("Enabled DHD only Band B support!! Blocked Band A!!\n"));
+               band = WLC_BAND_2G;
+       }
+#endif /* DHD_2G_ONLY_SUPPORT */
        if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) {
-               error = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), true);
+               error = wldev_ioctl_set(dev, WLC_SET_BAND, &band, sizeof(band));
                if (!error)
                        dhd_bus_band_set(dev, band);
        }
@@ -345,7 +402,7 @@ int wldev_get_datarate(struct net_device *dev, int *datarate)
 {
        int error = 0;
 
-       error = wldev_ioctl(dev, WLC_GET_RATE, datarate, sizeof(int), false);
+       error = wldev_ioctl_get(dev, WLC_GET_RATE, datarate, sizeof(int));
        if (error) {
                return -1;
        } else {
@@ -368,14 +425,14 @@ int wldev_get_mode(
        wl_bss_info_t *bss = NULL;
        char* buf = NULL;
 
-       buf = kmalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
+       buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
        if (!buf) {
                WLDEV_ERROR(("%s:ENOMEM\n", __FUNCTION__));
                return -ENOMEM;
        }
 
        *(u32*) buf = htod32(WL_EXTRA_BUF_MAX);
-       error = wldev_ioctl(dev, WLC_GET_BSS_INFO, (void*)buf, WL_EXTRA_BUF_MAX, false);
+       error = wldev_ioctl_get(dev, WLC_GET_BSS_INFO, (void*)buf, WL_EXTRA_BUF_MAX);
        if (error) {
                WLDEV_ERROR(("%s:failed:%d\n", __FUNCTION__, error));
                kfree(buf);
@@ -451,7 +508,8 @@ int wldev_set_country(
 
                if ((user_enforced) && (wl_get_drv_status(cfg, CONNECTED, dev))) {
                        bzero(&scbval, sizeof(scb_val_t));
-                       error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
+                       error = wldev_ioctl_set(dev, WLC_DISASSOC,
+                                               &scbval, sizeof(scb_val_t));
                        if (error < 0) {
                                WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
                                        __FUNCTION__, error));
index ca794f36d4969ef07480e8e86e93f5d58b121921..61b2c2b9d502fbebe41aa176391df9e3cc51ad48 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Common function shared by Linux WEXT, cfg80211 and p2p drivers
  *
- * Copyright (C) 1999-2017, Broadcom Corporation
+ * Copyright (C) 1999-2018, Broadcom Corporation
  * 
  *      Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -24,7 +24,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wldev_common.h 662434 2016-09-29 12:21:46Z $
+ * $Id: wldev_common.h 699163 2017-05-12 05:18:23Z $
  */
 #ifndef __WLDEV_COMMON_H__
 #define __WLDEV_COMMON_H__
  *  netdev_ops->ndo_do_ioctl in new kernels)
  *  @dev: the net_device handle
  */
-s32 wldev_ioctl(
-       struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set);
+
+s32 wldev_ioctl_get(
+       struct net_device *dev, u32 cmd, void *arg, u32 len);
+
+s32 wldev_ioctl_set(
+       struct net_device *dev, u32 cmd, const void *arg, u32 len);
 
 /** Retrieve named IOVARs, this function calls wl_dev_ioctl with
  *  WLC_GET_VAR IOCTL code
@@ -106,7 +110,7 @@ extern int net_os_set_dtim_skip(struct net_device *dev, int val);
 extern int net_os_set_suspend_disable(struct net_device *dev, int val);
 extern int net_os_set_suspend(struct net_device *dev, int val, int force);
 extern int net_os_set_max_dtim_enable(struct net_device *dev, int val);
-extern int wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid,
+extern int wl_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid,
        int max, int *bytes_left);
 
 /* Get the link speed from dongle, speed is in kpbs */