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
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"
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.
---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
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
#
-# 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
# 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
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
# 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
# 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
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
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
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
# 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
# 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
##############################
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
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
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
# 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
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
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
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
# 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
DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
DRIVER_TYPE = y
endif
-ifeq ($(BUS_IFACE_SDIO),y)
- DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
endif
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
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
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
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
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
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.
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),)
# 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
# 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),)
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))
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))
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),)
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
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
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
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
# 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
#
-# 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
# 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
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
# 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
# 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
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
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
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
# 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
# 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
##############################
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
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
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
# 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
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
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
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
# 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
DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
DRIVER_TYPE = y
endif
-ifeq ($(BUS_IFACE_SDIO),y)
- DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
endif
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
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
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
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
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
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.
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),)
# 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
# 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),)
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))
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))
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),)
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
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
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
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
# 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
#
-# 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
# 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
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
# 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
# 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
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
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
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
# 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
# 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
##############################
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
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
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
# 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
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
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
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
# 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
DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
DRIVER_TYPE = y
endif
-ifeq ($(BUS_IFACE_SDIO),y)
- DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
endif
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
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
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
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
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
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.
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),)
# 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
# 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),)
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))
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))
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),)
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
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
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
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
# 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
#
-# 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
# 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
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
# 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
# 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
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
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
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
# 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
# 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
##############################
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
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
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
# 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
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
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
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
# 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
DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
DRIVER_TYPE = y
endif
-ifeq ($(BUS_IFACE_SDIO),y)
- DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
endif
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
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
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
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
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
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.
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),)
# 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
# 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),)
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))
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))
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),)
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
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
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
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
# 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
#
-# 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
# 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
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
# 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
# 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
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
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
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
# 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
# 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
##############################
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
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
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
# 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
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
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
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
# 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
DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
DRIVER_TYPE = y
endif
-ifeq ($(BUS_IFACE_SDIO),y)
- DHDCFLAGS += -DCUSTOM_PSPRETEND_THR=30
-endif
endif
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
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
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
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
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
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.
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),)
# 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
# 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),)
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))
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))
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),)
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
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
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
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
# 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
* 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
* 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
/*
* 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
*
* <<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>
#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
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;
}
/* 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);
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;
}
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;
}
goto done;
}
+ BCM_REFERENCE(data_len);
done:
return err;
}
* 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
/*
* 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
/*
* 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
*
* <<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>
#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>
{"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 },
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;
/*
* 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
/*
* 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
*
* <<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>
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;
}
* 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
* 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
/*
* 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
/*
* 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
* 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
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: dhd.h 685046 2017-02-15 08:10:34Z $
+ * $Id: dhd.h 752171 2018-03-15 02:55:35Z $
*/
/****************
#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
(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
(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)
((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)
#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;
#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
*/
#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 */
#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"
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 {
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 */
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,
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
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)
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 */
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 */
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;
#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
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
/* 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 */
#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 {
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. */
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);
#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);
} 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);
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);
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
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);
#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
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)
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
#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)
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,
#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 */
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)
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_ */
* 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
*
* <<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_
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);
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_ */
/*
* 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
*
* <<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
/*
* 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
*
* <<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>
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));
}
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));
}
/*
* 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
/*
* 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
*
* <<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>
#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 |
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
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");
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");
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) {
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));
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);
#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));
}
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) {
{
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 */
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__));
/* 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);
}
}
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;
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,
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);
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;
}
#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,
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) {
#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)
__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);
#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;
}
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)
{
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) {
}
/* 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;
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));
}
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__));
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;
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;
}
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)
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)
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)
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));
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 */
/*
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
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)
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;
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') {
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.
}
} 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 */
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
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", \
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) {
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]));
uint32 *lognums = NULL;
char *logstrs = NULL;
int ram_index = 0;
- char **fmts;
+ char **fmts = NULL;
int num_fmts = 0;
int32 i = 0;
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.
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__));
}
#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)
* 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
*
* <<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>
{
char iovbuf[WLC_IOCTL_SMLEN];
struct ether_addr *mac;
+ int ret;
if (!dhdp) {
DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
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;
}
}
#ifdef SUPPORT_MULTIPLE_MODULE_CIS
-static bool
+bool
dhd_check_module(char *module_name)
{
char vname[MAX_VNAME_LEN];
/*
* 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
*
* <<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>
#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)
#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)) {
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
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;
}
}
#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 */
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
/*
* 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
/*
* 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
*
* <<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) + \
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)
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;
}
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;
}
}
#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;
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++) {
/*
* 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
*
* <<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 $
*
*/
#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)
/*
* 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 */
{"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},
{"IE", "IE", 5},
{"IL", "IL", 14},
{"IT", "IT", 4},
- {"JP", "JP", 45},
{"JO", "JO", 3},
{"KE", "SA", 0},
{"KW", "KW", 5},
{"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},
{"LK", "LK", 1},
{"SE", "SE", 4},
{"CH", "CH", 4},
- {"TW", "TW", 1},
{"TH", "TH", 5},
{"TT", "TT", 3},
{"TR", "TR", 7},
#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},
{"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
#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;
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;
#ifdef ROAM_ENABLE
uint roamvar = 1;
#endif
- uint32 ocl_enable = 0;
uint32 wl_updown = 1;
*power_mode = PM_OFF;
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));
}
}
#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) {
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 &&
/* 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",
#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));
}
/* 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));
{
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);
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",
}
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 {
}
#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)
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 */
/*
* 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
*
* <<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
* 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>
status.verbose_level = ring->log_level; \
} while (0)
+#define DHD_PKT_INFO DHD_ERROR
struct map_table {
uint16 fw_id;
uint16 host_id;
{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"}
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[] = {
ASSERT(0);
return 0;
}
+
memcpy(data, buf, rlen);
/* update ring context */
ring->rp += ENTRY_LENGTH(r_entry);
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) {
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;
}
/* 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++) {
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;
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;
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);
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
* 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)))) {
}
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)) {
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;
#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;
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;
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)
{
uint16 count;
+ DHD_PKT_INFO(("%s, %d\n", __FUNCTION__, __LINE__));
count = 0;
while ((count < pkt_count) && rx_pkts) {
if (rx_pkts->info.pkt)
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;
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;
}
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);
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;
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;
}
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;
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;
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;
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__,
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;
}
}
+ DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
return BCME_OK;
}
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__,
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;
}
}
+ DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
return BCME_OK;
}
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__,
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;
}
}
+ DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
return BCME_OK;
}
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;
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;
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);
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;
}
}
*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, "
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);
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;
}
}
*resp_count = pkt_count;
+ DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
return BCME_OK;
}
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;
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;
}
}
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;
}
*
* <<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
* 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_
};
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. */
#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;
#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 */
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;
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))
*
* <<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
* 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>
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));
}
{
int ret = BCME_OK;
*features = 0;
+#ifdef DEBUGABILITY
*features |= DBG_MEMORY_DUMP_SUPPORTED;
if (FW_SUPPORTED(dhdp, logtrace)) {
*features |= DBG_CONNECT_EVENT_SUPPORTED;
*features |= DBG_PACKET_FATE_SUPPORTED;
}
#endif /* DBG_PKT_MON */
+#endif /* DEBUGABILITY */
return ret;
}
* 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
*
* <<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 $
*/
/** 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) {
* 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
/*
* 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
*
* <<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>
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)
{
return;
}
-#endif /* DHDTCPACK_SUPPRESS */
static void dhd_tcpack_send(ulong data)
{
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:
*
* 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
* 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
*
* <<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>
#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);
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
#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);
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;
} 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);
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;
struct tasklet_struct tasklet;
spinlock_t sdlock;
spinlock_t txqlock;
+ spinlock_t rxqlock;
spinlock_t dhd_lock;
struct semaphore sdsem;
#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:
cpumask_clear_cpu(cpu, dhd->cpumask_curr_avail);
dhd_select_cpu_candidacy(dhd);
break;
+
default:
break;
}
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);
#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);
}
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
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);
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);
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__));
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);
}
#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 */
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;
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;
#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
#endif /* CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND */
#endif /* OEM_ANDROID && BCMPCIE */
- BCM_REFERENCE(iovbuf);
if (!dhd)
return -ENODEV;
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));
}
#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 */
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) {
/*
* 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;
/*
* 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) {
#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
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));
}
#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 */
#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) {
#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);
* 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
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 {
#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);
}
/* 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,
#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;
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__));
#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) {
}
}
#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
#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);
#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);
#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 */
#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
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);
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
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;
}
}
DHD_GENERAL_UNLOCK(&dhd->pub, flags);
}
+#ifdef BCMPCIE
DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
} else {
break;
}
return;
}
+#ifdef BCMPCIE
DHD_OS_WD_WAKE_LOCK(&dhd->pub);
+#endif /* BCMPCIE */
/* Call the bus module watchdog */
dhd_bus_watchdog(&dhd->pub);
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
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;
setScheduler(current, SCHED_FIFO, ¶m);
}
-#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;
#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)) {
{
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 */
setScheduler(current, SCHED_FIFO, ¶m);
}
-#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;
#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) {
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);
#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
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;
}
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;
}
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;
}
#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 */
#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));
}
#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
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 */
#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 */
#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
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;
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;
}
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;
}
{
struct file *filep = NULL;
mm_segment_t fs;
- char *raw_fmts = NULL;
+ char *raw_sstr = NULL;
uint32 logstrs_size = 0;
int error = 0;
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;
}
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;
}
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;
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:
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;
#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
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));
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;
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;
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);
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
(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:
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;
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).
/* 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 */
}
*/
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;
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';
}
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;
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;
}
dhd_os_sdunlock(dhdp);
#endif /* BCMSDIO */
DHD_PERIM_UNLOCK(dhdp);
+ DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
return -ENODEV;
}
#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;
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;
}
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;
}
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;
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;
}
} 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 {
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
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__));
#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;
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;
}
#endif /* WLAIBSS */
-#ifdef WLADPS
+#if defined(WLADPS) || defined(WLADPS_PRIVATE_CMD)
int
dhd_enable_adps(dhd_pub_t *dhd, uint8 on)
{
}
return ret;
}
-#endif /* WLADPS */
+#endif /* WLADPS || WLADPS_PRIVATE_CMD */
int
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;
#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
#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;
} 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;
}
#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;
{
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;
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
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));
}
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));
}
/* 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,
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
#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));
}
#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)
}
#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)
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
#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) {
(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));
}
}
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
#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
#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 */
}
#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 */
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 *)&du_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 *)&du_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));
}
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));
#if defined(CUSTOM_AMPDU_MPDU)
ampdu_mpdu = CUSTOM_AMPDU_MPDU;
if (ampdu_mpdu != 0 && (ampdu_mpdu <= ampdu_ba_wsize)) {
- bcm_mkiovar("ampdu_mpdu", (char *)&du_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 *)&du_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));
}
#if defined(CUSTOM_AMPDU_RELEASE)
ampdu_release = CUSTOM_AMPDU_RELEASE;
if (ampdu_release != 0 && (ampdu_release <= ampdu_ba_wsize)) {
- bcm_mkiovar("ampdu_release", (char *)&du_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 *)&du_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));
}
#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));
}
}
#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.
*/
}
#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) {
" 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;
}
#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) */
#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;
}
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
#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 */
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;
}
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
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;
/* 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);
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);
#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;
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;
/* 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 */
#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));
__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__));
}
}
#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
| 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)
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;
}
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));
#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:
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);
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 */
{
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);
}
#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);
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;
}
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 */
/* 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;
}
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));
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
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);
}
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);
#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;
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,
/* 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
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));
}
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 {
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));
}
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));
}
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));
}
} 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;
}
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));
}
/*
* 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 {
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,
/*
* 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 {
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;
#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
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);
#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;
}
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')
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";
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";
* 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 */
/* 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 */
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);
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);
}
#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 */
/* 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 {
/* 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;
}
}
#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)
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;
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);
}
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;
} 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 */
}
#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)
{
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;
}
}
+#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;
}
}
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;
}
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;
}
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;
/* 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)) {
"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;
}
}
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
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));
}
}
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)) {
}
}
#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 */
/*
* 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
*
* <<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
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 {
} 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__ */
/*
* 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
/*
* 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
* 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
* 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
*
* <<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_
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
};
*
* <<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
*
* <<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
* 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
*
* <<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[];
bool in_progress;
uint64 start_usec;
uint32 d11_lpbk;
+ int status;
} dhd_dmaxfer_t;
/**
#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);
/**
#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)
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 */
}
}
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);
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 */
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)
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;
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),
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 */
}
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 */
}
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;
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
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);
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 */
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);
* 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. */
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 */
#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);
#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 */
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 */
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;
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;
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.
* 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;
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);
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;
}
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)
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);
/*
* 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
*
* <<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 $
*/
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);
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,
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 },
}
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;
}
/* Check if the interrupt is ours or not */
if (intstatus == 0) {
+ DHD_TRACE(("%s : this interrupt is not ours\n", __FUNCTION__));
break;
}
/* 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:
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
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));
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);
} /* 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
}
#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)
{
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;
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) ||
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",
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);
}
char *str = NULL;
pciedev_shared_t *local_pciedev_shared = bus->pcie_sh;
struct bcmstrbuf strbuf;
+ unsigned long flags;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
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;
}
#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)
}
#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);
* 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
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;
}
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 */
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
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;
/** 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;
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;
}
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__));
/* 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);
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__));
/* 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) {
}
MFREE(bus->dhd->osh, tmpbuf, bus->varsz + 1);
}
-#endif /* KEEP_JP_REGREV */
+#endif /* KEEP_KR_REGREV || KEEP_JP_REGREV */
err:
return bcmerror;
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;
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)),
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;
}
/* 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);
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;
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",
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;
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);
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);
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);
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 */
/*
* 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
*
* <<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 $
*/
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 */
/*
* 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
*
* <<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 $
*/
}
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)) {
DHD_DISABLE_RUNTIME_PM(bus->dhd);
}
+ bus->chk_pm = TRUE;
return 0;
}
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);
#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
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)) {
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) {
}
#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",
}
#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)) {
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
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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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_ */
* 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
*
* <<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)
#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 *
_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));
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;
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__));
}
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;
}
}
/* 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;
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;
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;
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__));
}
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);
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;
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;
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)
{
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;
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));
}
_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;
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);
_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;
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",
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;
__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);
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));
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));
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;
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 "
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));
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 = ¶ms->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)
{
}
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;
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__)
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) -
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));
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;
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);
}
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;
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;
}
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));
}
{
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);
#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"
__FUNCTION__));
}
exit:
+ kfree(buf);
return err;
}
int dhd_pno_deinit(dhd_pub_t *dhd)
* 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
*
* <<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__
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 */
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;
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;
};
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;
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);
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);
* 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
*
* <<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_
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);
/*
* 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
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));
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__));
}
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;
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 {
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"));
}
}
#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) {
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,
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;
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 {
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 {
/*
* 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
/*
* 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
*
* <<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>
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)
{
(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) ||
(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;
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;
#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__));
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;
/* 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 */
}
#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);
IOV_SDREG,
IOV_SBREG,
IOV_SDCIS,
- IOV_MEMBYTES,
IOV_RAMSIZE,
IOV_RAMSTART,
#ifdef DHD_DEBUG
{"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 },
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;
*/
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 */
*/
dhd_bus_t *bus = dhdp->bus;
#ifdef BCMSDIOH_TXGLOM
- char buf[256];
uint32 rxglom;
int32 ret;
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 {
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;
} 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);
}
}
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;
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;
/* 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;
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)
return TRUE;
if (chipid == BCM4364_CHIP_ID)
return TRUE;
-
if (chipid == BCM43012_CHIP_ID)
return TRUE;
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:
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 */
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) {
}
#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)
{
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;
{
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 */
/*
* 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)
/*
* 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
*
* <<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 $
*
*/
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]));
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"));
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)"
/*
- * 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
* 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
-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
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
- 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
/*
* 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
/*
* 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
* 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
/*
* 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
*
* <<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_
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 */
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 */
} 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;
#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 */
#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 */
#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 */
#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) && \
#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 */
} 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
((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)
#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)
#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 {
#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 */
#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 */
#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 */
== 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) \
#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
#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
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 */
#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
#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 */
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 */
};
#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 */
#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];
/*
* 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
*
* <<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_
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
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>
/*
* 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
*
* <<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_
/*
* 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
*
* <<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_
/*
* 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
/*
* 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
* 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
*
* 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
*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: bcmeth.h 565501 2015-06-22 14:29:02Z $
+ * $Id: bcmeth.h 701825 2017-05-26 16:45:27Z $
*/
/*
#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
*
* 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
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: bcmevent.h 676796 2016-12-24 18:16:02Z $
+ * $Id: bcmevent.h 700076 2017-05-17 14:42:22Z $
*
*/
#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 */
* 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 */
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;
#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 {
#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_ */
/*
* 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
*
* <<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_
/*
* 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
*
* <<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_
*
* 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
*
* <<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_
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 */
/** delay before doing the dest txfer */
uint32 destdelay;
uint8 rsvd[3];
+ /* bit0: D11 DMA loopback flag */
uint8 flags;
} pcie_dma_xfer_params_t;
* 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
* 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
* 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
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: bcmsdh.h 671244 2016-11-21 08:36:36Z $
+ * $Id: bcmsdh.h 698895 2017-05-11 02:55:17Z $
*/
/**
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 */
/*
* 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
* 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
/*
* '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
/*
* 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
*
* <<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_
/*
* 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
*
* <<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_
#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;
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
/*
* 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
/*
* 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
*
* 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
*
* <<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_
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
#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 */
/*
* 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
/*
- * 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_ */
/*
* 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
*
* <<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 */
/*
* 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
*
* <<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_
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,
* 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
*
* <<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_
/*
* 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
*
* <<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_ */
/*
* 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
*
* <<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 */
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
/*
* 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
* 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
/*
* 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
* 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 */
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 {
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 */
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 */
/* 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
#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;
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;
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) */
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)
#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) \
#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
*/
#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
#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) == \
#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 */
} 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 */
/* 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
#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;
#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;
#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 {
/* 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
#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 */
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)
#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)
#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 */
/* 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 */
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 */
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 {
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 | \
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>
/*
* 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
/*
* 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
* 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
/*
* 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
*
* <<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_
* #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
* #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
/*
* 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
/*
* 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
*
* $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
/*
* 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
/*
* 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
* 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
/*
* 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
*
* 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
* 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
/*
* 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
/*
* 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
* 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
* 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
* 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
* 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
/*
- * 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
/*
* 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
*
* <<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_
/*
- * 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
*
* <<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
*
* 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
* 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_
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 */
};
/**
#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)
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 */
/* 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
*/
#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 */
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 */
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_ */
*
* 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
/*
* 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
/*
* 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
*
* <<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_
/*
* 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
* 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
* 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
* 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
/*
* 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
/*
* 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
*
* <<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;
#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
#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"
#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"
#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);
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);
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
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;
}
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;
}
} 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;
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(
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;
}
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(
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",
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;
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));
}
#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",
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));
}
#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",
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));
}
#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",
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;
}
#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",
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;
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));
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;
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));
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;
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,
#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));
}
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 */
/* 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;
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;
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;
}
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));
}
chanim_stats_t *stats;
memset(¶m, 0, sizeof(param));
- memset(result, 0, sizeof(result));
param.buflen = htod32(sizeof(wl_chanim_stats_t));
param.count = htod32(WL_CHANIM_COUNT_ONE);
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)));
}
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;
}
}
}
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;
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 {
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;
}
}
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));
}
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));
}
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));
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));
}
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);
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) {
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));
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);
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: "
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;
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;
if (ret) {
goto resume;
}
+#endif /* MIRACAST_AMPDU_SIZE */
/* FALLTROUGH */
/* Source mode shares most configurations with sink mode.
* Fall through here to avoid code duplication
}
/* 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;
}
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;
}
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)
/* 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;
}
#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(¶ms, sizeof(wl_reassoc_params_t));
- memcpy(¶ms.bssid, &bssid, ETHER_ADDR_LEN);
+ return bytes_written;
+}
- if ((err = wldev_ioctl(dev, WLC_REASSOC, ¶ms,
- 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
}
#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)
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)
{
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);
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
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);
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);
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
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");
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
/*
* 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
/*
* 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
*
* <<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>
};
#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).
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
*/
#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
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
*/
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);
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);
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);
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)) */
(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
#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), \
* 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);
}
/* 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;
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);
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;
}
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;
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:
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
err = -ENOMEM;
goto fail;
} else {
+ mutex_unlock(&cfg->if_sync);
return new_cfgdev;
}
#endif /* WL_VIRTUAL_APSTA */
err = -ENOMEM;
goto fail;
} else {
+ mutex_unlock(&cfg->if_sync);
return new_cfgdev;
}
#endif /* WL_VIRTUAL_APSTA */
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));
}
/* 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);
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);
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));
}
}
fail:
+ mutex_unlock(&cfg->if_sync);
if (err) {
#ifdef WLTDLS
/* Enable back TDLS on failure */
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);
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);
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);
} 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);
}
done:
+ mutex_unlock(&cfg->if_sync);
#ifdef WLTDLS
if (ret == BCME_OK) {
/* If interface del is success, try enabling back TDLS */
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:
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:
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,
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
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",
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).
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
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));
}
#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
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"));
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;
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;
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;
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;
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);
#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
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;
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) {
}
#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];
/* 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.
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)) {
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;
/* 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);
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.
*/
#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)) {
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;
}
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;
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;
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;
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;
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));
}
#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;
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;
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. */
/* 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) {
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 */
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)
{
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));
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;
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);
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);
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) {
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)) {
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"));
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 */
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);
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));
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));
/* 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));
}
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;
#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
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 {
}
/* 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 {
#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));
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;
/* 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));
}
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"));
{
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)
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 */
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
}
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);
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;
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));
#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
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", ¶m, sizeof(param),
cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
}
- } 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);
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));
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;
}
}
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;
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;
}
}
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;
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;
#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;
}
#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;
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 {
}
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
} 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
}
#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);
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));
}
#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));
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;
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)) {
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;
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);
}
#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;
#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) {
/* 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;
}
/* 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;
}
}
/* 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));
}
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));
}
/* 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;
}
#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)
#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);
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;
}
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);
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)
{
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;
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;
}
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 */
}
#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),
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;
}
}
}
#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;
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;
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
}
}
}
+
+ /* 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++) {
}
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);
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;
}
#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);
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)))) {
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
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",
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));
#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) {
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
*/
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 };
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;
} 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 {
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) {
}
#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)
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);
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);
#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
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);
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));
}
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,
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;
}
/* 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);
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);
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);
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
* 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;
if (unlikely(err)) {
WL_ERR(("Failed with error %d\n", err));
}
+
+ kfree(buf);
mutex_unlock(&cfg->usr_sync);
return err;
}
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)
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);
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,
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 */
}
#endif /* WBTEXT */
+fail:
return err;
}
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);
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);
}
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) {
}
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);
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;
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;
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) &&
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);
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 */
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)
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;
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 */
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
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"));
}
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;
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));
{
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"));
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));
#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"));
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 */
#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));
#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:
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();
#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);
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);
}
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"));
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;
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;
}
/* 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));
}
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;
} 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;
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);
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;
/* 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);
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;
}
/* IOVAR configurations with 'up' condition */
#ifdef DISABLE_PM_BCNRX
- bcm_mkiovar("pm_bcnrx", (char *)¶m, 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 *)¶m,
+ sizeof(param), iovbuf, sizeof(iovbuf), NULL);
if (unlikely(interr)) {
WL_ERR(("Set pm_bcnrx returned (%d)\n", interr));
}
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;
}
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;
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;
}
{
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))
}
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;
}
/* 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;
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) {
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) {
}
}
out:
+ if (ret) {
+ return -ENOTSUPP;
+ }
#endif /* WLTDLS */
return ret;
}
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;
{
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 |
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);
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]);
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;
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));
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;
{
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];
}
/* 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;
}
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;
}
}
- 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) {
}
}
- 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"));
err = wldev_iovar_setint_bsscfg(ndev, "grat_arp", 1, bssidx);
}
+ kfree(ie_setbuf);
return err;
}
#endif /* WL11U */
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)
{
}
#define BUFSZ 5
+#define BUFSZN BUFSZ + 1
#define _S(x) #x
#define S(x) _S(x)
{
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;
{
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);
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)
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));
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);
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;
}
}
#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;
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,
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,
}
/* 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;
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;
}
#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,
return err;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0) */
+#endif /* GTK_OFFLOAD_SUPPORT */
#if defined(WL_SUPPORT_AUTO_CHANNEL)
int
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;
}
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;
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
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,
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);
}
}
}
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,
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(¶ms, sizeof(wl_reassoc_params_t));
+ memcpy(¶ms.bssid, &bssid, ETHER_ADDR_LEN);
+
+ if ((err = wldev_ioctl_set(dev, WLC_REASSOC, ¶ms,
+ 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 */
/*
* 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
*
* <<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 $
*/
/**
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) { \
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 */
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) */
#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
};
/* 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 */
} 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 */
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;
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 */
#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__ == \
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
#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
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_ */
/*
* 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
*
* <<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>
bcm_mkiovar(name, (char *)(®), 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);
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
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
*/
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
/*
* 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
/*
* 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
/*
* 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
*
* <<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>
}
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;
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;
}
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);
/*
* 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
/*
* 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
*
* <<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)
/*
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
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
}
#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)
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:
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:
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:
#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)
{
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;
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();
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__));
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,
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)) {
}
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));
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;
}
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);
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) {
{
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);
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));
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;
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)
{
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)
}
#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)
.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,
.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
{
{
.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,
.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
{
},
.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 [] = {
/*
* 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
*
* <<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 $
*/
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"
/*
* 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
/*
* 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
*
* <<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 $
*/
#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
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]));
}
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];
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;
+ }
}
}
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;
+ }
}
}
--- /dev/null
+/*
+* 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;
+}
--- /dev/null
+/*
+* 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
/*
* 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
*
* <<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_
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_ */
/*
* 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
*
* <<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>
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;
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
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;
}
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;
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);
}
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);
}
}
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;
}
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;
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;
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);
{
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;
}
{
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);
}
{
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 {
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);
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));
/*
* 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
*
* <<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
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 */